feat: 实时消息与管理端运营能力
新增群聊/私信与公共 WebSocket 总线,站长用户内容档案,并将通知与待审角标改为推送驱动;同步精简管理仪表盘并修复主题换肤 DOM 冲突。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -105,6 +105,65 @@ func (h *Handlers) AdminUserLoginLogs(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"logs": logs, "total": total, "page": page})
|
||||
}
|
||||
|
||||
// AdminGetUserAudit 站长:用户内容档案摘要
|
||||
func (h *Handlers) AdminGetUserAudit(c *gin.Context) {
|
||||
id, ok := parseAdminUserID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
profile, err := h.AdminUser.GetAuditProfile(middleware.CurrentActor(c), id)
|
||||
if err != nil {
|
||||
respondAdminUserError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, profile)
|
||||
}
|
||||
|
||||
// AdminUserAuditPosts 站长:用户帖子(含驳回/软删)
|
||||
func (h *Handlers) AdminUserAuditPosts(c *gin.Context) {
|
||||
id, ok := parseAdminUserID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
items, total, page, err := h.AdminUser.ListAuditPosts(middleware.CurrentActor(c), id, page, 20)
|
||||
if err != nil {
|
||||
respondAdminUserError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"items": items, "total": total, "page": page})
|
||||
}
|
||||
|
||||
// AdminUserAuditComments 站长:用户评论(含驳回/软删)
|
||||
func (h *Handlers) AdminUserAuditComments(c *gin.Context) {
|
||||
id, ok := parseAdminUserID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
items, total, page, err := h.AdminUser.ListAuditComments(middleware.CurrentActor(c), id, page, 20)
|
||||
if err != nil {
|
||||
respondAdminUserError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"items": items, "total": total, "page": page})
|
||||
}
|
||||
|
||||
// AdminUserAuditMessages 站长:用户聊天消息(含撤回/软删)
|
||||
func (h *Handlers) AdminUserAuditMessages(c *gin.Context) {
|
||||
id, ok := parseAdminUserID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
items, total, page, err := h.AdminUser.ListAuditMessages(middleware.CurrentActor(c), id, page, 20)
|
||||
if err != nil {
|
||||
respondAdminUserError(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"items": items, "total": total, "page": page})
|
||||
}
|
||||
|
||||
// parseAdminUserID 解析路径中的用户 ID,失败时直接写出 400
|
||||
func parseAdminUserID(c *gin.Context) (uint, bool) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||||
@@ -120,8 +179,8 @@ func respondAdminUserError(c *gin.Context, err error) {
|
||||
switch {
|
||||
case errors.Is(err, gorm.ErrRecordNotFound):
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
|
||||
case errors.Is(err, service.ErrProtectedOwner):
|
||||
// 站长保护属于权限边界而非参数错误
|
||||
case errors.Is(err, service.ErrProtectedOwner),
|
||||
errors.Is(err, service.ErrOwnerOnly):
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": err.Error()})
|
||||
case errors.Is(err, service.ErrAdminSelfAction),
|
||||
errors.Is(err, service.ErrInvalidRole),
|
||||
|
||||
Reference in New Issue
Block a user