feat: 管理端板块管理与旧版数据导入,补充部署运营文档
- 新增管理端板块管理页面与后端接口(admin_board) - 新增旧版数据导入:legacyimport 服务、导入面板、importusers 命令行工具 - 聊天用户卡片、板块图标等 UI 组件与界面优化 - 补充 about/公告/1Panel 部署等文档 - gitignore 排除 dist/ 构建产物与 .agents/ 本地工具目录
This commit is contained in:
@@ -56,7 +56,7 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
settingSvc := service.NewSettingService(model.DB)
|
||||
ops := service.NewOperations(model.DB, cfg)
|
||||
go ops.Run(context.Background())
|
||||
postSvc := service.NewPostService(model.DB).WithSetting(settingSvc).WithDevMode(cfg.DevMode)
|
||||
postSvc := service.NewPostService(model.DB).WithSetting(settingSvc).WithBoard(boardSvc).WithDevMode(cfg.DevMode)
|
||||
commentSvc := service.NewCommentService(model.DB)
|
||||
likeSvc := service.NewLikeService(model.DB)
|
||||
notifSvc := service.NewNotificationService(model.DB)
|
||||
@@ -70,6 +70,7 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
postFileSvc.WithOperations(ops)
|
||||
pointsSvc := service.NewPointsService(model.DB)
|
||||
adminUserSvc := service.NewAdminUserService(model.DB)
|
||||
legacyImportSvc := service.NewLegacyImportService(model.DB, filepath.Join(cfg.DataDir, "uploads"))
|
||||
moderationSvc := service.NewModerationService(model.DB, notifSvc)
|
||||
chatSvc := service.NewChatService(model.DB, notifSvc)
|
||||
telemetrySvc := service.NewTelemetryService(model.DB)
|
||||
@@ -103,6 +104,7 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
Points: pointsSvc,
|
||||
Setting: settingSvc,
|
||||
AdminUser: adminUserSvc,
|
||||
LegacyImport: legacyImportSvc,
|
||||
Moderation: moderationSvc,
|
||||
Chat: chatSvc,
|
||||
Telemetry: telemetrySvc,
|
||||
@@ -176,22 +178,22 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
api.GET("/me/login-devices", h.MyLoginDevices)
|
||||
api.DELETE("/me/login-devices/:id", h.RevokeLoginDevice)
|
||||
api.PUT("/profile", h.UpdateProfile)
|
||||
api.POST("/posts", middleware.RateLimitMiddleware(limiter, service.RatePost), h.CreatePost)
|
||||
api.POST("/posts", middleware.StaffExempt(middleware.RateLimitMiddleware(limiter, service.RatePost)), h.CreatePost)
|
||||
api.PUT("/posts/:id", h.UpdatePost)
|
||||
api.POST("/posts/:id/unlock", middleware.RateLimitUserMiddleware(limiter, service.RateInteract), h.UnlockPostContent)
|
||||
api.POST("/posts/:id/poll/vote", middleware.RateLimitUserMiddleware(limiter, service.RateInteract), h.VotePoll)
|
||||
api.POST("/posts/:id/unlock", middleware.StaffExempt(middleware.RateLimitUserMiddleware(limiter, service.RateInteract)), h.UnlockPostContent)
|
||||
api.POST("/posts/:id/poll/vote", middleware.StaffExempt(middleware.RateLimitUserMiddleware(limiter, service.RateInteract)), h.VotePoll)
|
||||
api.POST("/posts/:id/poll/close", h.ClosePoll)
|
||||
api.POST("/posts/:id/question/accept", middleware.RateLimitUserMiddleware(limiter, service.RateInteract), h.AcceptQuestion)
|
||||
api.POST("/posts/:id/question/solve", middleware.RateLimitUserMiddleware(limiter, service.RateInteract), h.SolveQuestion)
|
||||
api.POST("/posts/:id/question/reopen", middleware.RateLimitUserMiddleware(limiter, service.RateInteract), h.ReopenQuestion)
|
||||
api.POST("/posts/:id/bounty/accept", middleware.RateLimitUserMiddleware(limiter, service.RateInteract), h.AcceptBounty)
|
||||
api.POST("/posts/:id/question/accept", middleware.StaffExempt(middleware.RateLimitUserMiddleware(limiter, service.RateInteract)), h.AcceptQuestion)
|
||||
api.POST("/posts/:id/question/solve", middleware.StaffExempt(middleware.RateLimitUserMiddleware(limiter, service.RateInteract)), h.SolveQuestion)
|
||||
api.POST("/posts/:id/question/reopen", middleware.StaffExempt(middleware.RateLimitUserMiddleware(limiter, service.RateInteract)), h.ReopenQuestion)
|
||||
api.POST("/posts/:id/bounty/accept", middleware.StaffExempt(middleware.RateLimitUserMiddleware(limiter, service.RateInteract)), h.AcceptBounty)
|
||||
api.POST("/posts/:id/lottery/draw", h.DrawLottery)
|
||||
api.DELETE("/posts/:id", h.DeletePost)
|
||||
api.PUT("/posts/:id/pin", h.TogglePin)
|
||||
api.PUT("/posts/:id/recommend", h.ToggleRecommend)
|
||||
api.POST("/posts/:id/like", h.ToggleLike)
|
||||
api.POST("/posts/:id/comments", middleware.RateLimitMiddleware(limiter, service.RateComment), h.CreateComment)
|
||||
api.PUT("/posts/:id/comments/:cid", middleware.RateLimitMiddleware(limiter, service.RateComment), h.UpdateComment)
|
||||
api.POST("/posts/:id/comments", middleware.StaffExempt(middleware.RateLimitMiddleware(limiter, service.RateComment)), h.CreateComment)
|
||||
api.PUT("/posts/:id/comments/:cid", middleware.StaffExempt(middleware.RateLimitMiddleware(limiter, service.RateComment)), h.UpdateComment)
|
||||
api.DELETE("/posts/:id/comments/:cid", h.DeleteComment)
|
||||
api.PUT("/posts/:id/comments/:cid/restore", h.RestoreComment)
|
||||
api.DELETE("/posts/:id/comments/:cid/purge", h.PurgeComment)
|
||||
@@ -202,13 +204,13 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
api.PUT("/notifications/read-all", h.MarkAllRead)
|
||||
// 每日签到 / 积分
|
||||
api.GET("/checkin", h.GetCheckin)
|
||||
api.POST("/checkin", middleware.RateLimitMiddleware(limiter, service.RateComment), h.DoCheckin)
|
||||
api.POST("/checkin", middleware.StaffExempt(middleware.RateLimitMiddleware(limiter, service.RateComment)), h.DoCheckin)
|
||||
api.GET("/points", h.GetPointsBalance)
|
||||
api.GET("/points/ledger", h.GetPointsLedger)
|
||||
// 头像上传(裁剪后的 WebP)/ 帖子插图 / 媒体库 / 附件删除
|
||||
api.POST("/upload/avatar", h.UploadAvatar)
|
||||
api.POST("/upload/image", middleware.RateLimitMiddleware(limiter, service.RateUpload), h.UploadImage)
|
||||
api.POST("/upload/file", middleware.RateLimitMiddleware(limiter, service.RateUpload), h.UploadPostFile)
|
||||
api.POST("/upload/image", middleware.StaffExempt(middleware.RateLimitMiddleware(limiter, service.RateUpload)), h.UploadImage)
|
||||
api.POST("/upload/file", middleware.StaffExempt(middleware.RateLimitMiddleware(limiter, service.RateUpload)), h.UploadPostFile)
|
||||
api.PUT("/upload/file/:id/price", h.UpdatePostFilePrice)
|
||||
api.DELETE("/upload/file/:id", h.DeletePostFile)
|
||||
api.PUT("/avatar/use", h.UseAvatar)
|
||||
@@ -216,7 +218,7 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
api.DELETE("/my/attachments/:id", h.DeleteAttachment)
|
||||
|
||||
// 时间线:从 Git commits 页导入(登录用户;适配器由超管配置)
|
||||
api.POST("/timeline/from-git", middleware.RateLimitUserMiddleware(limiter, service.RateTimelineGit), h.TimelineFromGit)
|
||||
api.POST("/timeline/from-git", middleware.StaffExempt(middleware.RateLimitUserMiddleware(limiter, service.RateTimelineGit)), h.TimelineFromGit)
|
||||
|
||||
// 群聊(二期):建群/成员/消息/未读;全站关闭消息时前台一律 403
|
||||
chatAPI := api.Group("/chat", h.RequireMessagesOpen)
|
||||
@@ -237,7 +239,7 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
chatAPI.PUT("/rooms/:id/members/:uid/mute", h.SetChatMemberMute)
|
||||
chatAPI.PUT("/rooms/:id/members/:uid/role", h.SetChatMemberRole)
|
||||
chatAPI.GET("/rooms/:id/messages", h.ListChatMessages)
|
||||
chatAPI.POST("/rooms/:id/messages", middleware.RateLimitMiddleware(limiter, service.RateChat), h.SendChatMessage)
|
||||
chatAPI.POST("/rooms/:id/messages", middleware.StaffExempt(middleware.RateLimitMiddleware(limiter, service.RateChat)), h.SendChatMessage)
|
||||
chatAPI.DELETE("/rooms/:id/messages/:mid", h.RecallChatMessage)
|
||||
chatAPI.PUT("/rooms/:id/read", h.MarkChatRead)
|
||||
chatAPI.GET("/unread-summary", h.ChatUnreadSummary)
|
||||
@@ -312,6 +314,8 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
opsAPI.GET("/:module/records", h.ModuleRecords)
|
||||
staffAPI.GET("/diagnostics", authMW.RequirePerm(service.PermSettings), h.Diagnostics)
|
||||
staffAPI.POST("/maintenance/actions", authMW.RequirePerm(service.PermSettings), h.MaintenanceAction)
|
||||
// 数据导入(旧站 / WordPress / Typecho 等,source 白名单见 service.LegacyImportSource)
|
||||
staffAPI.POST("/import/:source", authMW.RequirePerm(service.PermSettings), h.AdminImportLegacy)
|
||||
staffAPI.PUT("/settings", authMW.RequirePerm(service.PermSettings), h.UpdateSettings)
|
||||
staffAPI.POST("/upload/background", authMW.RequirePerm(service.PermSettings), middleware.RateLimitMiddleware(limiter, service.RateUpload), h.UploadBackground)
|
||||
staffAPI.POST("/upload/background/from-media", authMW.RequirePerm(service.PermSettings), middleware.RateLimitMiddleware(limiter, service.RateUpload), h.UploadBackgroundFromMedia)
|
||||
@@ -320,16 +324,31 @@ func Setup(cfg *config.Config) (*gin.Engine, error) {
|
||||
|
||||
// 用户与权限管理(超级管理员/站长):列表、角色授权、封禁、登录历史
|
||||
usersAPI := staffAPI.Group("", authMW.RequirePerm(service.PermUsers))
|
||||
usersAPI.GET("/users", h.AdminListUsers)
|
||||
usersAPI.PUT("/users/:id/role", h.AdminUpdateUserRole)
|
||||
usersAPI.PUT("/users/:id/messages", h.AdminSetUserMessages)
|
||||
usersAPI.PUT("/users/:id/ban", h.AdminSetUserBan)
|
||||
usersAPI.GET("/users/:id/login-logs", h.AdminUserLoginLogs)
|
||||
// 站长内容档案(handler 内再校验 owner)
|
||||
usersAPI.GET("/users/:id", h.AdminGetUserAudit)
|
||||
usersAPI.GET("/users/:id/posts", h.AdminUserAuditPosts)
|
||||
usersAPI.GET("/users/:id/comments", h.AdminUserAuditComments)
|
||||
usersAPI.GET("/users/:id/messages", h.AdminUserAuditMessages)
|
||||
{
|
||||
usersAPI.GET("/users", h.AdminListUsers)
|
||||
usersAPI.PUT("/users/:id/role", h.AdminUpdateUserRole)
|
||||
usersAPI.PUT("/users/:id/messages", h.AdminSetUserMessages)
|
||||
usersAPI.PUT("/users/:id/ban", h.AdminSetUserBan)
|
||||
usersAPI.GET("/users/:id/login-logs", h.AdminUserLoginLogs)
|
||||
// 站长内容档案(handler 内再校验 owner)
|
||||
usersAPI.GET("/users/:id", h.AdminGetUserAudit)
|
||||
usersAPI.GET("/users/:id/posts", h.AdminUserAuditPosts)
|
||||
usersAPI.GET("/users/:id/comments", h.AdminUserAuditComments)
|
||||
usersAPI.GET("/users/:id/messages", h.AdminUserAuditMessages)
|
||||
}
|
||||
|
||||
// 板块管理(仅站长):增删改、排序、版主授权
|
||||
boardsAPI := staffAPI.Group("", authMW.RequirePerm(service.PermBoards))
|
||||
{
|
||||
boardsAPI.GET("/boards", h.AdminListBoards)
|
||||
boardsAPI.POST("/boards", h.AdminCreateBoard)
|
||||
boardsAPI.PUT("/boards/:id", h.AdminUpdateBoard)
|
||||
boardsAPI.DELETE("/boards/:id", h.AdminDeleteBoard)
|
||||
boardsAPI.PUT("/boards/reorder", h.AdminReorderBoards)
|
||||
boardsAPI.GET("/boards/:id/moderators", h.AdminListBoardModerators)
|
||||
boardsAPI.POST("/boards/:id/moderators", h.AdminAddBoardModerator)
|
||||
boardsAPI.DELETE("/boards/:id/moderators/:uid", h.AdminRemoveBoardModerator)
|
||||
}
|
||||
}
|
||||
|
||||
// 消息管理后台:登录即可(handler 内校验站点消息权或群管理员)
|
||||
|
||||
Reference in New Issue
Block a user