feat: 实现完整的板块级RBAC内容审核系统

- 新增站长/超级管理员/管理员/板块管理员四级角色体系
- 实现实时权限快照加载与细粒度权限校验
- 新增内容审核队列与前后端页面
- 重构用户权限管理与站点管理逻辑
- 新增评论/帖子审核状态与通知推送
- 优化前端权限控制与角色徽章展示
- 修正数据库迁移与默认值问题
This commit is contained in:
2026-09-15 04:47:34 +08:00
parent 6da4309453
commit a7b6421840
44 changed files with 3149 additions and 585 deletions

View File

@@ -50,6 +50,7 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
uploadSvc := service.NewUploadService(model.DB, filepath.Join(cfg.DataDir, "uploads"))
settingSvc := service.NewSettingService(model.DB)
adminUserSvc := service.NewAdminUserService(model.DB)
moderationSvc := service.NewModerationService(model.DB, notifSvc)
if err := uploadSvc.EnsureDir(); err != nil {
return nil, err
}
@@ -69,6 +70,7 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
Upload: uploadSvc,
Setting: settingSvc,
AdminUser: adminUserSvc,
Moderation: moderationSvc,
}
authMW := middleware.NewAuthMiddleware(authSvc)
@@ -131,23 +133,39 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
api.DELETE("/my/attachments/:id", h.DeleteAttachment)
}
// 管理员 API(同样需要 CSRF 防护)
adminAPI := r.Group("/api/admin", authMW.RequireAuth(), middleware.CSRFMiddleware(), authMW.RequireAdmin())
// 管理后台 API:RequireStaff 基础鉴权(板块管理员及以上,Actor 实时从 DB 现取),
// 各功能点再由 RequirePerm 按角色放行;板块范围在 service 层按 Actor.BoardIDs 隔离
staffAPI := r.Group("/api/admin", authMW.RequireStaff(), middleware.CSRFMiddleware())
{
adminAPI.GET("/dashboard", func(c *gin.Context) {
staffAPI.GET("/dashboard", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "admin dashboard"})
})
// 站点公告文章管理
adminAPI.GET("/announcements", h.AdminListAnnouncements)
adminAPI.POST("/announcements", h.AdminCreateAnnouncement)
adminAPI.PUT("/announcements/:id", h.AdminUpdateAnnouncement)
adminAPI.DELETE("/announcements/:id", h.AdminDeleteAnnouncement)
// 站点外观设置(主题色)
adminAPI.PUT("/settings", h.UpdateSettings)
// 用户管理:列表(搜索/筛选/汇总)、角色变更、封禁解封
adminAPI.GET("/users", h.AdminListUsers)
adminAPI.PUT("/users/:id/role", h.AdminUpdateUserRole)
adminAPI.PUT("/users/:id/ban", h.AdminSetUserBan)
// 内容审核队列(任意管理角色;板块管理员只见授权板块)
staffAPI.GET("/moderation/pending-posts", h.AdminPendingPosts)
staffAPI.GET("/moderation/pending-comments", h.AdminPendingComments)
staffAPI.GET("/moderation/counts", h.AdminPendingCounts)
staffAPI.PUT("/moderation/posts/:id/approve", h.AdminApprovePost)
staffAPI.PUT("/moderation/posts/:id/reject", h.AdminRejectPost)
staffAPI.PUT("/moderation/comments/:id/approve", h.AdminApproveComment)
staffAPI.PUT("/moderation/comments/:id/reject", h.AdminRejectComment)
// 站点公告文章管理(管理员及以上)
announceAPI := staffAPI.Group("", authMW.RequirePerm(service.PermAnnouncements))
announceAPI.GET("/announcements", h.AdminListAnnouncements)
announceAPI.POST("/announcements", h.AdminCreateAnnouncement)
announceAPI.PUT("/announcements/:id", h.AdminUpdateAnnouncement)
announceAPI.DELETE("/announcements/:id", h.AdminDeleteAnnouncement)
// 站点外观设置(超级管理员/站长)
staffAPI.PUT("/settings", authMW.RequirePerm(service.PermSettings), h.UpdateSettings)
// 用户与权限管理(超级管理员/站长):列表、角色授权、封禁、登录历史
usersAPI := staffAPI.Group("", authMW.RequirePerm(service.PermUsers))
usersAPI.GET("/users", h.AdminListUsers)
usersAPI.PUT("/users/:id/role", h.AdminUpdateUserRole)
usersAPI.PUT("/users/:id/ban", h.AdminSetUserBan)
usersAPI.GET("/users/:id/login-logs", h.AdminUserLoginLogs)
}
r.NoRoute(func(c *gin.Context) {