Files
backend/internal/router/router.go
lan 9356cb6876
Some checks failed
Build Backend / build (push) Successful in 2m22s
Build Backend / build-docker (push) Failing after 3m3s
feat(runner): implement empty classroom sync functionality
Add support for fetching and synchronizing empty classroom data. This includes new protobuf definitions for task payloads and results, database models, repository, service, and HTTP handlers.

- Add `TASK_TYPE_GET_EMPTY_CLASSROOM` to `TaskType` enum
- Implement `EmptyClassroom` model and auto-migration
- Add `EmptyClassroomHandler` with `GET` and `POST /sync` routes
- Implement `EmptyClassroomSyncService` and `EmptyClassroomRepository`
- Update dependency injection with wire sets
2026-05-31 21:29:45 +08:00

721 lines
32 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package router
import (
"github.com/gin-gonic/gin"
"with_you/internal/handler"
"with_you/internal/middleware"
"with_you/internal/model"
"with_you/internal/repository"
"with_you/internal/service"
)
// RouterDeps 路由依赖
type RouterDeps struct {
UserRepo repository.UserRepository
UserHandler *handler.UserHandler
PostHandler *handler.PostHandler
CommentHandler *handler.CommentHandler
MessageHandler *handler.MessageHandler
NotificationHandler *handler.NotificationHandler
UploadHandler *handler.UploadHandler
PushHandler *handler.PushHandler
SystemMessageHandler *handler.SystemMessageHandler
GroupHandler *handler.GroupHandler
StickerHandler *handler.StickerHandler
VoteHandler *handler.VoteHandler
ChannelHandler *handler.ChannelHandler
ScheduleHandler *handler.ScheduleHandler
GradeHandler *handler.GradeHandler
ExamHandler *handler.ExamHandler
EmptyClassroomHandler *handler.EmptyClassroomHandler
RoleHandler *handler.RoleHandler
AdminUserHandler *handler.AdminUserHandler
AdminPostHandler *handler.AdminPostHandler
AdminCommentHandler *handler.AdminCommentHandler
AdminGroupHandler *handler.AdminGroupHandler
AdminDashboardHandler *handler.AdminDashboardHandler
AdminLogHandler *handler.AdminLogHandler
QRCodeHandler *handler.QRCodeHandler
MaterialHandler *handler.MaterialHandler
CallHandler *handler.CallHandler
ReportHandler *handler.ReportHandler
AdminReportHandler *handler.AdminReportHandler
VerificationHandler *handler.VerificationHandler
AdminVerificationHandler *handler.AdminVerificationHandler
AdminProfileAuditHandler *handler.AdminProfileAuditHandler
SetupHandler *handler.SetupHandler
TradeHandler *handler.TradeHandler
WSHandler *handler.WSHandler
JWTService *service.JWTService
LogService *service.LogService
ActivityService service.UserActivityService
CasbinService service.CasbinService
}
// Router 路由配置
type Router struct {
engine *gin.Engine
userRepo repository.UserRepository
userHandler *handler.UserHandler
postHandler *handler.PostHandler
commentHandler *handler.CommentHandler
messageHandler *handler.MessageHandler
notificationHandler *handler.NotificationHandler
uploadHandler *handler.UploadHandler
pushHandler *handler.PushHandler
systemMessageHandler *handler.SystemMessageHandler
groupHandler *handler.GroupHandler
stickerHandler *handler.StickerHandler
voteHandler *handler.VoteHandler
channelHandler *handler.ChannelHandler
scheduleHandler *handler.ScheduleHandler
gradeHandler *handler.GradeHandler
examHandler *handler.ExamHandler
emptyClassroomHandler *handler.EmptyClassroomHandler
roleHandler *handler.RoleHandler
adminUserHandler *handler.AdminUserHandler
adminPostHandler *handler.AdminPostHandler
adminCommentHandler *handler.AdminCommentHandler
adminGroupHandler *handler.AdminGroupHandler
adminDashboardHandler *handler.AdminDashboardHandler
adminLogHandler *handler.AdminLogHandler
qrcodeHandler *handler.QRCodeHandler
materialHandler *handler.MaterialHandler
callHandler *handler.CallHandler
reportHandler *handler.ReportHandler
adminReportHandler *handler.AdminReportHandler
verificationHandler *handler.VerificationHandler
adminVerificationHandler *handler.AdminVerificationHandler
adminProfileAuditHandler *handler.AdminProfileAuditHandler
setupHandler *handler.SetupHandler
tradeHandler *handler.TradeHandler
wsHandler *handler.WSHandler
logService *service.LogService
jwtService *service.JWTService
casbinService service.CasbinService
}
// New 创建路由
func New(deps RouterDeps) *Router {
deps.UserHandler.SetJWTService(deps.JWTService)
deps.UserHandler.SetActivityService(deps.ActivityService)
r := &Router{
engine: gin.Default(),
userRepo: deps.UserRepo,
userHandler: deps.UserHandler,
postHandler: deps.PostHandler,
commentHandler: deps.CommentHandler,
messageHandler: deps.MessageHandler,
notificationHandler: deps.NotificationHandler,
uploadHandler: deps.UploadHandler,
pushHandler: deps.PushHandler,
systemMessageHandler: deps.SystemMessageHandler,
groupHandler: deps.GroupHandler,
stickerHandler: deps.StickerHandler,
voteHandler: deps.VoteHandler,
channelHandler: deps.ChannelHandler,
scheduleHandler: deps.ScheduleHandler,
gradeHandler: deps.GradeHandler,
examHandler: deps.ExamHandler,
emptyClassroomHandler: deps.EmptyClassroomHandler,
roleHandler: deps.RoleHandler,
adminUserHandler: deps.AdminUserHandler,
adminPostHandler: deps.AdminPostHandler,
adminCommentHandler: deps.AdminCommentHandler,
adminGroupHandler: deps.AdminGroupHandler,
adminDashboardHandler: deps.AdminDashboardHandler,
adminLogHandler: deps.AdminLogHandler,
qrcodeHandler: deps.QRCodeHandler,
materialHandler: deps.MaterialHandler,
callHandler: deps.CallHandler,
reportHandler: deps.ReportHandler,
adminReportHandler: deps.AdminReportHandler,
verificationHandler: deps.VerificationHandler,
adminVerificationHandler: deps.AdminVerificationHandler,
adminProfileAuditHandler: deps.AdminProfileAuditHandler,
setupHandler: deps.SetupHandler,
tradeHandler: deps.TradeHandler,
logService: deps.LogService,
jwtService: deps.JWTService,
casbinService: deps.CasbinService,
wsHandler: deps.WSHandler,
}
r.setupRoutes()
return r
}
// setupRoutes 设置路由
func (r *Router) setupRoutes() {
// 中间件
r.engine.Use(middleware.SecurityHeaders())
r.engine.Use(middleware.CORS())
// 健康检查
r.engine.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "ok"})
})
// API v1
v1 := r.engine.Group("/api/v1")
{
// 认证路由(公开,按接口类型设置不同速率限制)
auth := v1.Group("/auth")
auth.Use(middleware.GlobalAuthRateLimit())
auth.Use(middleware.IPBanMiddleware())
{
auth.POST("/register", middleware.RegisterRateLimit(), r.userHandler.Register)
auth.POST("/register/send-code", middleware.SendCodeRateLimit(), r.userHandler.SendRegisterCode)
auth.POST("/login", middleware.LoginRateLimit(), r.userHandler.Login)
auth.POST("/password/send-code", middleware.PasswordResetRateLimit(), r.userHandler.SendPasswordResetCode)
auth.POST("/password/reset", middleware.PasswordResetRateLimit(), r.userHandler.ResetPassword)
auth.POST("/logout", r.userHandler.Logout)
auth.POST("/refresh", r.userHandler.RefreshToken)
}
// 初始化超级管理员(公开接口,只能使用一次)
if r.setupHandler != nil {
v1.POST("/admin/setup-super-admin", r.setupHandler.SetupSuperAdmin)
}
// 需要认证的路由
authMiddleware := middleware.Auth(r.jwtService)
// === 访问日志中间件 ===
if r.adminLogHandler != nil && r.logService != nil {
accessLogConfig := &middleware.AccessLogConfig{
Enable: true,
SkipPaths: []string{"/health", "/api/v1/health"},
ServerIP: "0.0.0.0",
ServerPort: 8080,
}
r.engine.Use(middleware.AccessLogMiddleware(
r.logService.OperationLog,
accessLogConfig,
))
}
// Casbin 权限中间件(暂不全局启用,可根据需要在特定路由组上使用)
// casbinMiddleware := middleware.CasbinAuth(r.casbinService)
// 用户路由
users := v1.Group("/users")
{
// 当前用户
users.GET("/me", authMiddleware, r.userHandler.GetCurrentUser)
users.PUT("/me", authMiddleware, r.userHandler.UpdateUser)
users.POST("/me/email/send-code", authMiddleware, r.userHandler.SendEmailVerifyCode)
users.POST("/me/email/verify", authMiddleware, r.userHandler.VerifyEmail)
users.POST("/me/avatar", authMiddleware, r.uploadHandler.UploadAvatar)
users.POST("/me/cover", authMiddleware, r.uploadHandler.UploadCover)
users.POST("/change-password/send-code", authMiddleware, r.userHandler.SendChangePasswordCode)
users.POST("/change-password", authMiddleware, r.userHandler.ChangePassword)
// 隐私设置
users.GET("/me/privacy", authMiddleware, r.userHandler.GetPrivacySettings)
users.PUT("/me/privacy", authMiddleware, r.userHandler.UpdatePrivacySettings)
// 账号注销
users.POST("/me/deactivate", authMiddleware, r.userHandler.RequestAccountDeletion)
users.DELETE("/me/deactivate", authMiddleware, r.userHandler.CancelAccountDeletion)
users.GET("/me/deletion-status", authMiddleware, r.userHandler.GetDeletionStatus)
// 当前用户角色
if r.roleHandler != nil {
users.GET("/me/roles", authMiddleware, r.roleHandler.GetMyRoles)
}
// 搜索用户
users.GET("/search", middleware.OptionalAuth(r.jwtService), r.userHandler.Search)
// 其他用户
users.GET("/:id", middleware.OptionalAuth(r.jwtService), r.userHandler.GetUserByID)
users.POST("/:id/follow", authMiddleware, r.userHandler.FollowUser)
users.DELETE("/:id/follow", authMiddleware, r.userHandler.UnfollowUser)
users.POST("/:id/block", authMiddleware, r.userHandler.BlockUser)
users.DELETE("/:id/block", authMiddleware, r.userHandler.UnblockUser)
users.GET("/:id/block-status", authMiddleware, r.userHandler.GetBlockStatus)
users.GET("/blocks", authMiddleware, r.userHandler.GetBlockedUsers)
users.GET("/:id/following", authMiddleware, r.userHandler.GetFollowingList)
users.GET("/:id/followers", authMiddleware, r.userHandler.GetFollowersList)
// 用户帖子 - 使用 OptionalAuth 获取当前用户点赞/收藏状态
users.GET("/:id/posts", middleware.OptionalAuth(r.jwtService), r.postHandler.GetUserPosts)
users.GET("/:id/favorites", middleware.OptionalAuth(r.jwtService), r.postHandler.GetFavorites)
}
// 身份认证路由
if r.verificationHandler != nil {
verification := v1.Group("/verification")
verification.Use(authMiddleware)
{
verification.GET("/status", r.verificationHandler.GetVerificationStatus)
verification.POST("/submit", r.verificationHandler.SubmitVerification)
verification.GET("/records", r.verificationHandler.GetVerificationRecords)
}
}
// 二维码登录(公开)
if r.qrcodeHandler != nil {
qrcode := v1.Group("/auth/qrcode")
{
qrcode.GET("", r.qrcodeHandler.GetQRCode)
qrcode.GET("/events", r.qrcodeHandler.WSEvents)
}
// 二维码操作(需认证)
qrcodeAuth := v1.Group("/auth/qrcode")
qrcodeAuth.Use(authMiddleware)
{
qrcodeAuth.POST("/scan", r.qrcodeHandler.Scan)
qrcodeAuth.POST("/confirm", r.qrcodeHandler.Confirm)
qrcodeAuth.POST("/cancel", r.qrcodeHandler.Cancel)
}
}
// 认证路由(公开)
authPublic := v1.Group("/auth")
{
authPublic.GET("/check-username", r.userHandler.CheckUsername)
}
// 帖子路由
posts := v1.Group("/posts")
{
// 使用 OptionalAuth 中间件来获取用户登录状态
posts.GET("", middleware.OptionalAuth(r.jwtService), r.postHandler.List)
posts.GET("/search", middleware.OptionalAuth(r.jwtService), r.postHandler.Search)
posts.GET("/suggest", middleware.OptionalAuth(r.jwtService), r.postHandler.Suggest)
posts.GET("/:id", middleware.OptionalAuth(r.jwtService), r.postHandler.GetByID)
posts.POST("", authMiddleware, middleware.RequireVerified(r.userRepo), r.postHandler.Create)
posts.PUT("/:id", authMiddleware, middleware.RequireVerified(r.userRepo), r.postHandler.Update)
posts.DELETE("/:id", authMiddleware, middleware.RequireVerified(r.userRepo), r.postHandler.Delete)
// 浏览量记录(可选认证,允许游客浏览)
posts.POST("/:id/view", middleware.OptionalAuth(r.jwtService), r.postHandler.RecordView)
// 分享计数(可选认证;仅已发布帖子生效)
posts.POST("/:id/share", middleware.OptionalAuth(r.jwtService), r.postHandler.RecordShare)
// 内链相关路由
posts.GET("/:id/related", middleware.OptionalAuth(r.jwtService), r.postHandler.GetRelatedPosts)
posts.GET("/:id/refs", middleware.OptionalAuth(r.jwtService), r.postHandler.GetReferencedPosts)
posts.POST("/:id/ref-click", middleware.OptionalAuth(r.jwtService), r.postHandler.RecordRefClick)
// 点赞
posts.POST("/:id/like", authMiddleware, middleware.RequireVerified(r.userRepo), r.postHandler.Like)
posts.DELETE("/:id/like", authMiddleware, middleware.RequireVerified(r.userRepo), r.postHandler.Unlike)
// 收藏
posts.POST("/:id/favorite", authMiddleware, middleware.RequireVerified(r.userRepo), r.postHandler.Favorite)
posts.DELETE("/:id/favorite", authMiddleware, middleware.RequireVerified(r.userRepo), r.postHandler.Unfavorite)
// 投票相关路由
posts.POST("/vote", authMiddleware, middleware.RequireVerified(r.userRepo), r.voteHandler.CreateVotePost) // 创建投票帖子
posts.GET("/:id/vote", middleware.OptionalAuth(r.jwtService), r.voteHandler.GetVoteResult) // 获取投票结果
posts.POST("/:id/vote", authMiddleware, middleware.RequireVerified(r.userRepo), r.voteHandler.Vote) // 投票
posts.DELETE("/:id/vote", authMiddleware, middleware.RequireVerified(r.userRepo), r.voteHandler.Unvote) // 取消投票
}
// 频道路由(公开)
if r.channelHandler != nil {
channels := v1.Group("/channels")
{
channels.GET("", r.channelHandler.ListPublic)
}
}
// 二手交易路由
if r.tradeHandler != nil {
trade := v1.Group("/trade")
{
trade.GET("", middleware.OptionalAuth(r.jwtService), r.tradeHandler.List)
trade.GET("/:id", middleware.OptionalAuth(r.jwtService), r.tradeHandler.GetByID)
trade.POST("", authMiddleware, middleware.RequireVerified(r.userRepo), r.tradeHandler.Create)
trade.PUT("/:id", authMiddleware, middleware.RequireVerified(r.userRepo), r.tradeHandler.Update)
trade.DELETE("/:id", authMiddleware, middleware.RequireVerified(r.userRepo), r.tradeHandler.Delete)
trade.PUT("/:id/status", authMiddleware, middleware.RequireVerified(r.userRepo), r.tradeHandler.UpdateStatus)
trade.POST("/:id/view", middleware.OptionalAuth(r.jwtService), r.tradeHandler.RecordView)
trade.POST("/:id/favorite", authMiddleware, middleware.RequireVerified(r.userRepo), r.tradeHandler.Favorite)
trade.DELETE("/:id/favorite", authMiddleware, middleware.RequireVerified(r.userRepo), r.tradeHandler.Unfavorite)
}
}
// 课表路由
if r.scheduleHandler != nil {
schedule := v1.Group("/schedule")
schedule.Use(authMiddleware)
{
schedule.GET("/courses", r.scheduleHandler.ListCourses)
schedule.POST("/courses", r.scheduleHandler.CreateCourse)
schedule.POST("/sync", r.scheduleHandler.SyncSchedule) // 同步课表
schedule.PUT("/courses/:id", r.scheduleHandler.UpdateCourse)
schedule.DELETE("/courses/:id", r.scheduleHandler.DeleteCourse)
}
}
// 成绩路由
if r.gradeHandler != nil {
grades := v1.Group("/grades")
grades.Use(authMiddleware)
{
grades.GET("", r.gradeHandler.ListGrades)
grades.POST("/sync", r.gradeHandler.SyncGrades)
}
}
// 考试安排路由
if r.examHandler != nil {
exams := v1.Group("/exams")
exams.Use(authMiddleware)
{
exams.GET("", r.examHandler.ListExams)
exams.POST("/sync", r.examHandler.SyncExams)
}
}
// 空教室路由
if r.emptyClassroomHandler != nil {
classrooms := v1.Group("/classrooms")
classrooms.Use(authMiddleware)
{
classrooms.GET("", r.emptyClassroomHandler.ListEmptyClassrooms)
classrooms.POST("/sync", r.emptyClassroomHandler.SyncEmptyClassrooms)
}
}
// 学习资料路由(公开)
if r.materialHandler != nil {
materials := v1.Group("/materials")
{
// 学科相关
materials.GET("/subjects", r.materialHandler.ListSubjects)
materials.GET("/subjects/:id", r.materialHandler.GetSubject)
// 资料相关
materials.GET("", r.materialHandler.ListMaterials)
materials.GET("/search", r.materialHandler.SearchMaterials)
materials.GET("/:id", r.materialHandler.GetMaterial)
materials.GET("/:id/download", r.materialHandler.DownloadMaterial)
}
}
// 投票选项路由
voteOptions := v1.Group("/vote-options")
voteOptions.Use(authMiddleware)
{
voteOptions.PUT("/:id", r.voteHandler.UpdateVoteOption) // 更新选项
}
// 评论路由
comments := v1.Group("/comments")
{
comments.GET("/post/:id", middleware.OptionalAuth(r.jwtService), r.commentHandler.GetByPostID)
comments.GET("/post/:id/cursor", middleware.OptionalAuth(r.jwtService), r.commentHandler.GetByPostIDByCursor) // 帖子评论游标分页
comments.GET("/:id", middleware.OptionalAuth(r.jwtService), r.commentHandler.GetByID)
comments.POST("", authMiddleware, middleware.RequireVerified(r.userRepo), r.commentHandler.Create)
comments.PUT("/:id", authMiddleware, middleware.RequireVerified(r.userRepo), r.commentHandler.Update)
comments.DELETE("/:id", authMiddleware, middleware.RequireVerified(r.userRepo), r.commentHandler.Delete)
comments.GET("/:id/replies", middleware.OptionalAuth(r.jwtService), r.commentHandler.GetReplies)
comments.GET("/:id/replies/flat", middleware.OptionalAuth(r.jwtService), r.commentHandler.GetRepliesByRootID) // 扁平化分页获取回复
comments.GET("/:id/replies/cursor", middleware.OptionalAuth(r.jwtService), r.commentHandler.GetRepliesByRootIDByCursor) // 回复游标分页
// 评论点赞
comments.POST("/:id/like", authMiddleware, middleware.RequireVerified(r.userRepo), r.commentHandler.Like)
comments.DELETE("/:id/like", authMiddleware, middleware.RequireVerified(r.userRepo), r.commentHandler.Unlike)
}
// 会话路由
conversations := v1.Group("/conversations")
conversations.Use(authMiddleware)
{
// ================================================================
// 新的 RESTful 风格路由(推荐使用)
// ================================================================
conversations.GET("", r.messageHandler.HandleGetConversationList) // 列表
conversations.GET("/cursor", r.messageHandler.GetConversationsByCursor) // 会话列表游标分页
conversations.POST("", middleware.RequireVerified(r.userRepo), r.messageHandler.HandleCreateConversation) // 创建
conversations.GET("/:id", r.messageHandler.HandleGetConversation) // 详情
conversations.GET("/:id/messages", r.messageHandler.HandleGetMessages) // 消息列表
conversations.GET("/:id/messages/cursor", r.messageHandler.GetMessagesByCursor) // 消息列表游标分页
conversations.POST("/:id/messages", middleware.RequireVerified(r.userRepo), r.messageHandler.HandleSendMessage) // 发送消息
conversations.POST("/:id/read", r.messageHandler.HandleMarkRead) // 标记已读
conversations.POST("/read-all", r.messageHandler.HandleMarkReadAll) // 批量标记已读
conversations.PUT("/:id/pinned", r.messageHandler.HandleSetConversationPinned) // 置顶设置
conversations.PUT("/:id/notification_muted", r.messageHandler.HandleSetConversationNotificationMuted) // 免打扰设置
conversations.GET("/unread/count", r.messageHandler.GetUnreadCount) // 未读数
conversations.GET("/sync-data", r.messageHandler.HandleGetSyncData) // 同步元数据
conversations.GET("/sync", r.messageHandler.HandleGetSyncByVersion) // 增量同步(版本日志)
conversations.POST("/:id/typing", r.messageHandler.HandleTyping) // 输入状态
conversations.DELETE("/:id/self", r.messageHandler.HandleDeleteConversationForSelf) // 删除会话(仅自己)
}
realtime := v1.Group("/realtime")
{
// WebSocket端点 - 在中间件之前处理认证通过query参数
realtime.GET("/ws", r.wsHandler.HandleWebSocket)
}
// 通话路由
if r.callHandler != nil {
calls := v1.Group("/calls")
calls.Use(authMiddleware)
{
calls.GET("/history", r.callHandler.GetCallHistory)
calls.GET("/ice-servers", r.callHandler.GetICEServers)
}
}
// 消息操作路由
messages := v1.Group("/messages")
messages.Use(authMiddleware)
{
// 撤回/删除消息(统一接口)
messages.POST("/delete_msg", middleware.RequireVerified(r.userRepo), r.messageHandler.HandleDeleteMsg)
}
// 举报路由
if r.reportHandler != nil {
reports := v1.Group("/reports")
reports.Use(authMiddleware)
{
reports.POST("", r.reportHandler.Create)
}
}
// 通知路由
notifications := v1.Group("/notifications")
{
notifications.GET("", authMiddleware, r.notificationHandler.GetNotifications)
notifications.GET("/cursor", authMiddleware, r.notificationHandler.GetNotificationsByCursor) // 通知游标分页
notifications.POST("/:id/read", authMiddleware, r.notificationHandler.MarkAsRead)
notifications.POST("/read-all", authMiddleware, r.notificationHandler.MarkAllAsRead)
notifications.GET("/unread-count", authMiddleware, r.notificationHandler.GetUnreadCount)
notifications.DELETE("/:id", authMiddleware, r.notificationHandler.DeleteNotification)
notifications.DELETE("", authMiddleware, r.notificationHandler.ClearAllNotifications)
}
// 上传路由
uploads := v1.Group("/uploads")
{
uploads.POST("/images", authMiddleware, r.uploadHandler.UploadImage)
}
// 推送相关路由
if r.pushHandler != nil {
pushGroup := v1.Group("/push")
pushGroup.Use(authMiddleware)
{
pushGroup.POST("/devices", r.pushHandler.RegisterDevice)
pushGroup.GET("/devices", r.pushHandler.GetMyDevices)
pushGroup.DELETE("/devices/:device_id", r.pushHandler.UnregisterDevice)
pushGroup.PUT("/devices/:device_id/token", r.pushHandler.UpdateDeviceToken)
pushGroup.GET("/records", r.pushHandler.GetPushRecords)
}
}
// 系统消息路由
if r.systemMessageHandler != nil {
msgGroup := v1.Group("/messages")
msgGroup.Use(authMiddleware)
{
msgGroup.GET("/system", r.systemMessageHandler.GetSystemMessages)
msgGroup.GET("/system/unread-count", r.systemMessageHandler.GetUnreadCount)
msgGroup.PUT("/system/:id/read", r.systemMessageHandler.MarkAsRead)
msgGroup.PUT("/system/read-all", r.systemMessageHandler.MarkAllAsRead)
}
}
// 群组路由
if r.groupHandler != nil {
groups := v1.Group("/groups")
groups.Use(authMiddleware)
{
// ================================================================
// 新的 RESTful 风格路由(推荐使用)
// ================================================================
// 群组基本操作
groups.GET("", r.groupHandler.HandleGetUserGroups) // 列表
groups.GET("/cursor", r.groupHandler.GetGroupsByCursor) // 群组游标分页
groups.POST("", r.groupHandler.HandleCreateGroup) // 创建
groups.GET("/:id", r.groupHandler.HandleGetGroupInfo) // 详情
groups.GET("/:id/me", r.groupHandler.HandleGetMyMemberInfo) // 当前用户成员信息
groups.DELETE("/:id", r.groupHandler.HandleDissolveGroup) // 解散群组
groups.POST("/:id/transfer", r.groupHandler.HandleTransferOwner) // 转让群主
// 成员管理
groups.POST("/:id/invitations", r.groupHandler.HandleInviteMembers) // 邀请成员
groups.POST("/:id/join-requests", r.groupHandler.HandleJoinGroup) // 申请加群
groups.POST("/:id/join-requests/respond", r.groupHandler.HandleRespondInvite) // 响应加群邀请/申请
groups.POST("/:id/leave", r.groupHandler.HandleSetGroupLeave) // 退群
groups.GET("/:id/members", r.groupHandler.HandleGetGroupMemberList) // 成员列表
groups.GET("/:id/members/cursor", r.groupHandler.GetMembersByCursor) // 成员游标分页
groups.POST("/:id/members/kick", r.groupHandler.HandleSetGroupKick) // 踢出成员
groups.PUT("/:id/members/:user_id/admin", r.groupHandler.HandleSetGroupAdmin) // 设置管理员
groups.PUT("/:id/members/me/nickname", r.groupHandler.HandleSetNickname) // 设置群昵称
groups.POST("/:id/members/ban", r.groupHandler.HandleSetGroupBan) // 禁言成员
// 群设置
groups.PUT("/:id/ban", r.groupHandler.HandleSetGroupWholeBan) // 全员禁言
groups.PUT("/:id/join-type", r.groupHandler.HandleSetJoinType) // 加群方式
groups.PUT("/:id/name", r.groupHandler.HandleSetGroupName) // 群名称
groups.PUT("/:id/avatar", r.groupHandler.HandleSetGroupAvatar) // 群头像
groups.PUT("/:id/description", r.groupHandler.HandleSetGroupDescription) // 群描述
// 群公告
groups.POST("/:id/announcements", r.groupHandler.HandleCreateAnnouncement) // 创建公告
groups.GET("/:id/announcements", r.groupHandler.HandleGetAnnouncements) // 公告列表
groups.GET("/:id/announcements/cursor", r.groupHandler.GetAnnouncementsByCursor) // 公告游标分页
groups.DELETE("/:id/announcements/:announcement_id", r.groupHandler.HandleDeleteAnnouncement) // 删除公告
// 加群请求处理
groups.POST("/:id/join-requests/handle", r.groupHandler.HandleSetGroupAddRequest) // 处理加群请求
}
}
// 自定义表情路由
if r.stickerHandler != nil {
stickers := v1.Group("/stickers")
stickers.Use(authMiddleware)
{
stickers.GET("", r.stickerHandler.GetStickers)
stickers.POST("", r.stickerHandler.AddSticker)
stickers.DELETE("", r.stickerHandler.DeleteSticker)
stickers.POST("/reorder", r.stickerHandler.ReorderStickers)
stickers.GET("/check", r.stickerHandler.CheckStickerExists)
}
}
// 管理路由(需要管理员权限)
if r.roleHandler != nil {
admin := v1.Group("/admin")
admin.Use(authMiddleware)
admin.Use(middleware.RequireRole(r.casbinService, model.RoleAdmin, model.RoleSuperAdmin))
{
// 角色管理
admin.GET("/roles", r.roleHandler.GetAllRoles)
admin.GET("/roles/:name", r.roleHandler.GetRoleDetail)
admin.GET("/roles/:name/permissions", r.roleHandler.GetRolePermissions)
admin.PUT("/roles/:name/permissions", r.roleHandler.UpdateRolePermissions)
admin.GET("/permissions", r.roleHandler.GetAllPermissions)
admin.GET("/users/:id/roles", r.roleHandler.GetUserRoles)
admin.POST("/users/:id/roles", r.roleHandler.AssignRole)
admin.DELETE("/users/:id/roles/:role", r.roleHandler.RemoveRole)
// 用户管理
if r.adminUserHandler != nil {
admin.GET("/users", r.adminUserHandler.GetUserList)
admin.GET("/users/:id", r.adminUserHandler.GetUserDetail)
admin.PUT("/users/:id/status", r.adminUserHandler.UpdateUserStatus)
}
// 帖子管理
if r.adminPostHandler != nil {
admin.GET("/posts", r.adminPostHandler.GetPostList)
admin.GET("/posts/:id", r.adminPostHandler.GetPostDetail)
admin.DELETE("/posts/:id", r.adminPostHandler.DeletePost)
admin.PUT("/posts/:id/moderate", r.adminPostHandler.ModeratePost)
admin.POST("/posts/batch-delete", r.adminPostHandler.BatchDeletePosts)
admin.POST("/posts/batch-moderate", r.adminPostHandler.BatchModeratePosts)
admin.PUT("/posts/:id/pin", r.adminPostHandler.SetPostPin)
admin.PUT("/posts/:id/feature", r.adminPostHandler.SetPostFeature)
}
// 频道管理
if r.channelHandler != nil {
admin.GET("/channels", r.channelHandler.AdminList)
admin.POST("/channels", r.channelHandler.AdminCreate)
admin.PUT("/channels/:id", r.channelHandler.AdminUpdate)
admin.DELETE("/channels/:id", r.channelHandler.AdminDelete)
}
// 评论管理
if r.adminCommentHandler != nil {
admin.GET("/comments", r.adminCommentHandler.GetCommentList)
admin.GET("/comments/:id", r.adminCommentHandler.GetCommentDetail)
admin.DELETE("/comments/:id", r.adminCommentHandler.DeleteComment)
admin.PUT("/comments/:id/moderate", r.adminCommentHandler.ModerateComment)
admin.POST("/comments/batch-delete", r.adminCommentHandler.BatchDeleteComments)
admin.POST("/comments/batch-moderate", r.adminCommentHandler.BatchModerateComments)
admin.GET("/comments/post/:postId", r.adminCommentHandler.GetPostComments)
}
// 群组管理
if r.adminGroupHandler != nil {
admin.GET("/groups", r.adminGroupHandler.GetGroupList)
admin.GET("/groups/:id", r.adminGroupHandler.GetGroupDetail)
admin.GET("/groups/:id/members", r.adminGroupHandler.GetGroupMembers)
admin.DELETE("/groups/:id", r.adminGroupHandler.DeleteGroup)
admin.PUT("/groups/:id/status", r.adminGroupHandler.UpdateGroupStatus)
admin.DELETE("/groups/:id/members/:userId", r.adminGroupHandler.RemoveMember)
admin.PUT("/groups/:id/transfer", r.adminGroupHandler.TransferOwner)
}
// 仪表盘
if r.adminDashboardHandler != nil {
admin.GET("/dashboard/stats", r.adminDashboardHandler.GetStats)
admin.GET("/dashboard/user-activity", r.adminDashboardHandler.GetUserActivityTrend)
admin.GET("/dashboard/content-stats", r.adminDashboardHandler.GetContentStats)
admin.GET("/dashboard/pending-content", r.adminDashboardHandler.GetPendingContent)
admin.GET("/dashboard/online-users", r.adminDashboardHandler.GetOnlineUsers)
}
// 日志管理
if r.adminLogHandler != nil {
logs := admin.Group("/logs")
{
logs.GET("/operations", r.adminLogHandler.GetOperationLogs)
logs.GET("/logins", r.adminLogHandler.GetLoginLogs)
logs.GET("/data-changes", r.adminLogHandler.GetDataChangeLogs)
logs.GET("/statistics", r.adminLogHandler.GetLogStatistics)
logs.GET("/export", r.adminLogHandler.ExportLogs)
}
}
// 学习资料管理
if r.materialHandler != nil {
// 学科管理
admin.GET("/materials/subjects", r.materialHandler.AdminListSubjects)
admin.POST("/materials/subjects", r.materialHandler.AdminCreateSubject)
admin.PUT("/materials/subjects/:id", r.materialHandler.AdminUpdateSubject)
admin.DELETE("/materials/subjects/:id", r.materialHandler.AdminDeleteSubject)
// 资料管理
admin.GET("/materials", r.materialHandler.AdminListMaterials)
admin.GET("/materials/:id", r.materialHandler.AdminGetMaterial)
admin.POST("/materials", r.materialHandler.AdminCreateMaterial)
admin.PUT("/materials/:id", r.materialHandler.AdminUpdateMaterial)
admin.DELETE("/materials/:id", r.materialHandler.AdminDeleteMaterial)
}
// 举报管理
if r.adminReportHandler != nil {
admin.GET("/reports", r.adminReportHandler.List)
admin.GET("/reports/:id", r.adminReportHandler.Detail)
admin.PUT("/reports/:id/handle", r.adminReportHandler.Handle)
admin.POST("/reports/batch-handle", r.adminReportHandler.BatchHandle)
}
// 身份认证管理
if r.adminVerificationHandler != nil {
admin.GET("/verifications", r.adminVerificationHandler.ListVerifications)
admin.GET("/verifications/:id", r.adminVerificationHandler.GetVerificationDetail)
admin.PUT("/verifications/:id/review", r.adminVerificationHandler.ReviewVerification)
}
// 用户资料审核管理
if r.adminProfileAuditHandler != nil {
admin.GET("/profile-audits", r.adminProfileAuditHandler.GetPendingList)
admin.PUT("/profile-audits/:id/moderate", r.adminProfileAuditHandler.ModerateAudit)
admin.POST("/profile-audits/batch-moderate", r.adminProfileAuditHandler.BatchModerate)
}
}
}
}
}
// Engine 获取引擎
func (r *Router) Engine() *gin.Engine {
return r.engine
}