Set up project files and add .gitignore to exclude local build/runtime artifacts. Made-with: Cursor
335 lines
13 KiB
Go
335 lines
13 KiB
Go
package router
|
|
|
|
import (
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"carrot_bbs/internal/handler"
|
|
"carrot_bbs/internal/middleware"
|
|
"carrot_bbs/internal/service"
|
|
)
|
|
|
|
// Router 路由配置
|
|
type Router struct {
|
|
engine *gin.Engine
|
|
userHandler *handler.UserHandler
|
|
postHandler *handler.PostHandler
|
|
commentHandler *handler.CommentHandler
|
|
messageHandler *handler.MessageHandler
|
|
notificationHandler *handler.NotificationHandler
|
|
uploadHandler *handler.UploadHandler
|
|
wsHandler *handler.WebSocketHandler
|
|
pushHandler *handler.PushHandler
|
|
systemMessageHandler *handler.SystemMessageHandler
|
|
groupHandler *handler.GroupHandler
|
|
stickerHandler *handler.StickerHandler
|
|
gorseHandler *handler.GorseHandler
|
|
voteHandler *handler.VoteHandler
|
|
jwtService *service.JWTService
|
|
}
|
|
|
|
// New 创建路由
|
|
func New(
|
|
userHandler *handler.UserHandler,
|
|
postHandler *handler.PostHandler,
|
|
commentHandler *handler.CommentHandler,
|
|
messageHandler *handler.MessageHandler,
|
|
notificationHandler *handler.NotificationHandler,
|
|
uploadHandler *handler.UploadHandler,
|
|
jwtService *service.JWTService,
|
|
wsHandler *handler.WebSocketHandler,
|
|
pushHandler *handler.PushHandler,
|
|
systemMessageHandler *handler.SystemMessageHandler,
|
|
groupHandler *handler.GroupHandler,
|
|
stickerHandler *handler.StickerHandler,
|
|
gorseHandler *handler.GorseHandler,
|
|
voteHandler *handler.VoteHandler,
|
|
) *Router {
|
|
// 设置JWT服务
|
|
userHandler.SetJWTService(jwtService)
|
|
|
|
r := &Router{
|
|
engine: gin.Default(),
|
|
userHandler: userHandler,
|
|
postHandler: postHandler,
|
|
commentHandler: commentHandler,
|
|
messageHandler: messageHandler,
|
|
notificationHandler: notificationHandler,
|
|
uploadHandler: uploadHandler,
|
|
wsHandler: wsHandler,
|
|
pushHandler: pushHandler,
|
|
systemMessageHandler: systemMessageHandler,
|
|
groupHandler: groupHandler,
|
|
stickerHandler: stickerHandler,
|
|
gorseHandler: gorseHandler,
|
|
voteHandler: voteHandler,
|
|
jwtService: jwtService,
|
|
}
|
|
|
|
r.setupRoutes()
|
|
return r
|
|
}
|
|
|
|
// setupRoutes 设置路由
|
|
func (r *Router) setupRoutes() {
|
|
// 中间件
|
|
r.engine.Use(middleware.CORS())
|
|
|
|
// 健康检查
|
|
r.engine.GET("/health", func(c *gin.Context) {
|
|
c.JSON(200, gin.H{"status": "ok"})
|
|
})
|
|
|
|
// WebSocket 路由
|
|
if r.wsHandler != nil {
|
|
r.engine.GET("/ws", r.wsHandler.HandleWebSocket)
|
|
}
|
|
|
|
// API v1
|
|
v1 := r.engine.Group("/api/v1")
|
|
{
|
|
// 认证路由(公开)
|
|
auth := v1.Group("/auth")
|
|
{
|
|
auth.POST("/register", r.userHandler.Register)
|
|
auth.POST("/register/send-code", r.userHandler.SendRegisterCode)
|
|
auth.POST("/login", r.userHandler.Login)
|
|
auth.POST("/password/send-code", r.userHandler.SendPasswordResetCode)
|
|
auth.POST("/password/reset", r.userHandler.ResetPassword)
|
|
auth.POST("/refresh", r.userHandler.RefreshToken)
|
|
}
|
|
|
|
// 需要认证的路由
|
|
authMiddleware := middleware.Auth(r.jwtService)
|
|
|
|
// 用户路由
|
|
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("/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)
|
|
}
|
|
|
|
// 认证路由(公开)
|
|
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("/:id", middleware.OptionalAuth(r.jwtService), r.postHandler.GetByID)
|
|
posts.POST("", authMiddleware, r.postHandler.Create)
|
|
posts.PUT("/:id", authMiddleware, r.postHandler.Update)
|
|
posts.DELETE("/:id", authMiddleware, r.postHandler.Delete)
|
|
|
|
// 浏览量记录(可选认证,允许游客浏览)
|
|
posts.POST("/:id/view", middleware.OptionalAuth(r.jwtService), r.postHandler.RecordView)
|
|
|
|
// 点赞
|
|
posts.POST("/:id/like", authMiddleware, r.postHandler.Like)
|
|
posts.DELETE("/:id/like", authMiddleware, r.postHandler.Unlike)
|
|
|
|
// 收藏
|
|
posts.POST("/:id/favorite", authMiddleware, r.postHandler.Favorite)
|
|
posts.DELETE("/:id/favorite", authMiddleware, r.postHandler.Unfavorite)
|
|
|
|
// 投票相关路由
|
|
posts.POST("/vote", authMiddleware, r.voteHandler.CreateVotePost) // 创建投票帖子
|
|
posts.GET("/:id/vote", middleware.OptionalAuth(r.jwtService), r.voteHandler.GetVoteResult) // 获取投票结果
|
|
posts.POST("/:id/vote", authMiddleware, r.voteHandler.Vote) // 投票
|
|
posts.DELETE("/:id/vote", authMiddleware, r.voteHandler.Unvote) // 取消投票
|
|
}
|
|
|
|
// 投票选项路由
|
|
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("/:id", middleware.OptionalAuth(r.jwtService), r.commentHandler.GetByID)
|
|
comments.POST("", authMiddleware, r.commentHandler.Create)
|
|
comments.PUT("/:id", authMiddleware, r.commentHandler.Update)
|
|
comments.DELETE("/:id", authMiddleware, 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.POST("/:id/like", authMiddleware, r.commentHandler.Like)
|
|
comments.DELETE("/:id/like", authMiddleware, r.commentHandler.Unlike)
|
|
}
|
|
|
|
// 会话路由(新版 RESTful action 风格)
|
|
conversations := v1.Group("/conversations")
|
|
conversations.Use(authMiddleware)
|
|
{
|
|
// 获取会话列表
|
|
conversations.GET("/list", r.messageHandler.HandleGetConversationList)
|
|
// 创建会话
|
|
conversations.POST("/create", r.messageHandler.HandleCreateConversation)
|
|
// 获取会话详情
|
|
conversations.GET("/get", r.messageHandler.HandleGetConversation)
|
|
// 获取会话消息
|
|
conversations.GET("/get_messages", r.messageHandler.HandleGetMessages)
|
|
// 发送消息
|
|
conversations.POST("/send_message", r.messageHandler.HandleSendMessage)
|
|
// 标记已读
|
|
conversations.POST("/mark_read", r.messageHandler.HandleMarkRead)
|
|
// 会话置顶
|
|
conversations.POST("/set_pinned", r.messageHandler.HandleSetConversationPinned)
|
|
// 获取未读消息总数
|
|
conversations.GET("/unread/count", r.messageHandler.GetUnreadCount)
|
|
// 仅自己删除会话
|
|
conversations.DELETE("/:id/self", r.messageHandler.HandleDeleteConversationForSelf)
|
|
}
|
|
|
|
// 消息操作路由
|
|
messages := v1.Group("/messages")
|
|
messages.Use(authMiddleware)
|
|
{
|
|
// 撤回/删除消息(统一接口)
|
|
messages.POST("/delete_msg", r.messageHandler.HandleDeleteMsg)
|
|
}
|
|
|
|
// 通知路由
|
|
notifications := v1.Group("/notifications")
|
|
{
|
|
notifications.GET("", authMiddleware, r.notificationHandler.GetNotifications)
|
|
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)
|
|
}
|
|
}
|
|
|
|
// 群组路由(新版 RESTful action 风格)
|
|
if r.groupHandler != nil {
|
|
groups := v1.Group("/groups")
|
|
groups.Use(authMiddleware)
|
|
{
|
|
// 群组管理
|
|
groups.POST("/create", r.groupHandler.HandleCreateGroup)
|
|
groups.GET("/list", r.groupHandler.HandleGetUserGroups)
|
|
groups.GET("/get", r.groupHandler.HandleGetGroupInfo)
|
|
groups.GET("/get_my_info", r.groupHandler.HandleGetMyMemberInfo)
|
|
groups.POST("/dissolve", r.groupHandler.HandleDissolveGroup)
|
|
groups.POST("/transfer", r.groupHandler.HandleTransferOwner)
|
|
|
|
// 成员管理
|
|
groups.POST("/invite_members", r.groupHandler.HandleInviteMembers)
|
|
groups.POST("/join", r.groupHandler.HandleJoinGroup)
|
|
groups.POST("/respond_invite", r.groupHandler.HandleRespondInvite)
|
|
groups.POST("/set_group_leave", r.groupHandler.HandleSetGroupLeave)
|
|
groups.GET("/get_members", r.groupHandler.HandleGetGroupMemberList)
|
|
groups.POST("/set_group_kick", r.groupHandler.HandleSetGroupKick)
|
|
groups.POST("/set_group_admin", r.groupHandler.HandleSetGroupAdmin)
|
|
groups.POST("/set_nickname", r.groupHandler.HandleSetNickname)
|
|
groups.POST("/set_group_ban", r.groupHandler.HandleSetGroupBan)
|
|
|
|
// 群设置
|
|
groups.POST("/set_group_whole_ban", r.groupHandler.HandleSetGroupWholeBan)
|
|
groups.POST("/set_join_type", r.groupHandler.HandleSetJoinType)
|
|
groups.POST("/set_group_name", r.groupHandler.HandleSetGroupName)
|
|
groups.POST("/set_group_avatar", r.groupHandler.HandleSetGroupAvatar)
|
|
|
|
// 群公告
|
|
groups.POST("/create_announcement", r.groupHandler.HandleCreateAnnouncement)
|
|
groups.GET("/get_announcements", r.groupHandler.HandleGetAnnouncements)
|
|
groups.POST("/delete_announcement", r.groupHandler.HandleDeleteAnnouncement)
|
|
|
|
// 加群请求处理(预留)
|
|
groups.POST("/set_group_add_request", 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)
|
|
}
|
|
}
|
|
|
|
// Gorse 管理路由
|
|
if r.gorseHandler != nil {
|
|
gorseGroup := v1.Group("/gorse")
|
|
{
|
|
gorseGroup.GET("/status", r.gorseHandler.GetStatus)
|
|
gorseGroup.POST("/import", r.gorseHandler.ImportData)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Engine 获取引擎
|
|
func (r *Router) Engine() *gin.Engine {
|
|
return r.engine
|
|
}
|