feat(admin): 完善站点设置、内容回收站与后台菜单分组
新增站点设置与内容管理(含已删除恢复/清除),用户页改用独有运营指标,并按概览/内容/成员与经济/站点重组侧栏。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -87,16 +87,91 @@ func (h *Handlers) AdminRejectComment(c *gin.Context) {
|
||||
h.execModeration(c, h.Moderation.RejectComment)
|
||||
}
|
||||
|
||||
// writeModerationError 映射审核业务错误为 HTTP 响应
|
||||
// ===== 内容库(帖子/评论 + 已删除回收站) =====
|
||||
|
||||
func (h *Handlers) AdminContentCounts(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, h.Moderation.AdminContentCounts(middleware.CurrentActor(c)))
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminListPosts(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
items, total, err := h.Moderation.ListAdminPosts(
|
||||
middleware.CurrentActor(c), c.Query("status"), c.Query("q"), page,
|
||||
)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取帖子列表失败"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"posts": nonNilSlice(items), "total": total, "page": page})
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminListComments(c *gin.Context) {
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
items, total, err := h.Moderation.ListAdminComments(
|
||||
middleware.CurrentActor(c), c.Query("status"), c.Query("q"), page,
|
||||
)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取评论列表失败"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"comments": nonNilSlice(items), "total": total, "page": page})
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminSoftDeletePost(c *gin.Context) {
|
||||
h.execContentAction(c, h.Moderation.SoftDeletePost)
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminRestorePost(c *gin.Context) {
|
||||
h.execContentAction(c, h.Moderation.RestorePost)
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminPurgePost(c *gin.Context) {
|
||||
h.execContentAction(c, h.Moderation.PurgePost)
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminSoftDeleteComment(c *gin.Context) {
|
||||
h.execContentAction(c, h.Moderation.SoftDeleteComment)
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminRestoreComment(c *gin.Context) {
|
||||
h.execContentAction(c, h.Moderation.RestoreComment)
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminPurgeComment(c *gin.Context) {
|
||||
h.execContentAction(c, h.Moderation.PurgeComment)
|
||||
}
|
||||
|
||||
func (h *Handlers) execContentAction(c *gin.Context, fn func(*service.Actor, uint) error) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
|
||||
return
|
||||
}
|
||||
if err := fn(middleware.CurrentActor(c), uint(id)); err != nil {
|
||||
h.writeModerationError(c, err)
|
||||
return
|
||||
}
|
||||
h.broadcastModerationChanged()
|
||||
c.JSON(http.StatusOK, gin.H{"message": "操作成功"})
|
||||
}
|
||||
|
||||
// writeModerationError 映射审核/内容库业务错误为 HTTP 响应
|
||||
func (h *Handlers) writeModerationError(c *gin.Context, err error) {
|
||||
switch {
|
||||
case errors.Is(err, gorm.ErrRecordNotFound):
|
||||
case errors.Is(err, gorm.ErrRecordNotFound), errors.Is(err, service.ErrContentNotFound):
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "内容不存在"})
|
||||
case errors.Is(err, service.ErrModerationForbidden):
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": err.Error()})
|
||||
case errors.Is(err, service.ErrNotPending):
|
||||
case errors.Is(err, service.ErrNotPending),
|
||||
errors.Is(err, service.ErrContentNotDeleted):
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
default:
|
||||
msg := err.Error()
|
||||
if msg == "帖子已在回收站" || msg == "帖子未被删除" ||
|
||||
msg == "评论已在回收站" || msg == "评论未被删除" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": msg})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "操作失败"})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user