完善角色与消息权限:收紧板管内容处置,彻底删除仅站长,并统一管理删帖/评弹窗。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -21,9 +21,12 @@ func chatErrToStatus(err error) int {
|
||||
errors.Is(err, service.ErrChatOwnerOnly), errors.Is(err, service.ErrChatPrivateInvite),
|
||||
errors.Is(err, service.ErrChatRecallDenied), errors.Is(err, service.ErrChatDefaultLeave),
|
||||
errors.Is(err, service.ErrChatDefaultDissolve), errors.Is(err, service.ErrChatDMDissolve),
|
||||
errors.Is(err, service.ErrChatHallPinFixed):
|
||||
errors.Is(err, service.ErrChatHallPinFixed), errors.Is(err, service.ErrChatSiteOwnerOnly),
|
||||
errors.Is(err, service.ErrChatMuteDenied), errors.Is(err, service.ErrChatCannotMuteOwner),
|
||||
errors.Is(err, service.ErrChatAdminAccess):
|
||||
return http.StatusForbidden
|
||||
case errors.Is(err, service.ErrChatDMSelf), errors.Is(err, service.ErrChatUserGone):
|
||||
case errors.Is(err, service.ErrChatDMSelf), errors.Is(err, service.ErrChatUserGone),
|
||||
errors.Is(err, service.ErrChatInvalidRole):
|
||||
return http.StatusBadRequest
|
||||
default:
|
||||
return http.StatusBadRequest
|
||||
@@ -307,7 +310,7 @@ func (h *Handlers) KickChatMember(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "用户 ID 无效"})
|
||||
return
|
||||
}
|
||||
if err := h.Chat.Kick(claims.ID, roomID, uint(targetID)); err != nil {
|
||||
if err := h.Chat.Kick(claims.ID, roomID, uint(targetID), h.chatOversee(claims.ID)); err != nil {
|
||||
c.JSON(chatErrToStatus(err), gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
@@ -319,6 +322,63 @@ func (h *Handlers) KickChatMember(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
// SetChatMemberMute 禁言/解禁成员
|
||||
func (h *Handlers) SetChatMemberMute(c *gin.Context) {
|
||||
claims := middleware.CurrentUser(c)
|
||||
roomID, ok := chatRoomID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
targetID, err := strconv.ParseUint(c.Param("uid"), 10, 64)
|
||||
if err != nil || targetID == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "用户 ID 无效"})
|
||||
return
|
||||
}
|
||||
var body struct {
|
||||
Muted bool `json:"muted"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||||
return
|
||||
}
|
||||
if err := h.Chat.SetMemberMute(claims.ID, roomID, uint(targetID), body.Muted, h.chatOversee(claims.ID)); err != nil {
|
||||
c.JSON(chatErrToStatus(err), gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true, "muted": body.Muted})
|
||||
}
|
||||
|
||||
// SetChatMemberRole 站长任命/撤销群管理员
|
||||
func (h *Handlers) SetChatMemberRole(c *gin.Context) {
|
||||
claims := middleware.CurrentUser(c)
|
||||
roomID, ok := chatRoomID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
targetID, err := strconv.ParseUint(c.Param("uid"), 10, 64)
|
||||
if err != nil || targetID == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "用户 ID 无效"})
|
||||
return
|
||||
}
|
||||
var body struct {
|
||||
Role string `json:"role"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "请求参数无效"})
|
||||
return
|
||||
}
|
||||
actor := h.loadActor(claims.ID)
|
||||
role := model.RoleUser
|
||||
if actor != nil {
|
||||
role = actor.Role
|
||||
}
|
||||
if err := h.Chat.SetMemberRole(role, roomID, uint(targetID), body.Role); err != nil {
|
||||
c.JSON(chatErrToStatus(err), gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true, "role": body.Role})
|
||||
}
|
||||
|
||||
// ListChatMessages 历史消息
|
||||
func (h *Handlers) ListChatMessages(c *gin.Context) {
|
||||
claims := middleware.CurrentUser(c)
|
||||
@@ -474,11 +534,21 @@ func (h *Handlers) ChatUnreadSummary(c *gin.Context) {
|
||||
|
||||
// AdminChatMessages 管理端消息监管队列;room_type=group|direct
|
||||
func (h *Handlers) AdminChatMessages(c *gin.Context) {
|
||||
claims := middleware.CurrentUser(c)
|
||||
actor := h.loadActor(claims.ID)
|
||||
if actor == nil || !h.Chat.CanAccessAdminMessages(actor) {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "无权管理消息"})
|
||||
return
|
||||
}
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
q := c.Query("q")
|
||||
roomType := c.Query("room_type")
|
||||
msgs, total, err := h.Chat.AdminListMessages(page, q, roomType)
|
||||
msgs, total, err := h.Chat.AdminListMessages(actor, page, q, roomType)
|
||||
if err != nil {
|
||||
if errors.Is(err, service.ErrChatAdminAccess) {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if err.Error() == "房间类型无效" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -486,12 +556,24 @@ func (h *Handlers) AdminChatMessages(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "加载聊天消息失败"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"messages": msgs, "total": total, "page": page})
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"messages": msgs,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"can_oversee": service.CanOverseeChat(actor.Role),
|
||||
"can_recall": true,
|
||||
"site_messages": actor.HasSiteMessagePerm(),
|
||||
})
|
||||
}
|
||||
|
||||
// AdminRecallChatMessage 管理端撤回群聊消息(staff;监管者可撤任意)
|
||||
// AdminRecallChatMessage 管理端撤回群聊消息
|
||||
func (h *Handlers) AdminRecallChatMessage(c *gin.Context) {
|
||||
claims := middleware.CurrentUser(c)
|
||||
actor := h.loadActor(claims.ID)
|
||||
if actor == nil || !h.Chat.CanAccessAdminMessages(actor) {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "无权管理消息"})
|
||||
return
|
||||
}
|
||||
roomID, err := strconv.ParseUint(c.Param("roomId"), 10, 64)
|
||||
if err != nil || roomID == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "房间 ID 无效"})
|
||||
@@ -502,8 +584,7 @@ func (h *Handlers) AdminRecallChatMessage(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "消息 ID 无效"})
|
||||
return
|
||||
}
|
||||
oversee := h.chatOversee(claims.ID)
|
||||
// 非监管 staff:仅允许撤回自己发送的(与前台一致)
|
||||
oversee := service.CanOverseeChat(actor.Role)
|
||||
msg, newly, err := h.Chat.RecallMessage(claims.ID, uint(roomID), uint(mid), oversee)
|
||||
if err != nil {
|
||||
c.JSON(chatErrToStatus(err), gin.H{"error": err.Error()})
|
||||
|
||||
Reference in New Issue
Block a user