为 Spark Messenger 主路径补齐 POST /v1/friends/requests/reject,并落地法律协议/反馈/订阅/密码登录及管理页,同步 OpenAPI 文档。 Co-authored-by: Cursor <cursoragent@cursor.com>
276 lines
7.4 KiB
Go
276 lines
7.4 KiB
Go
package httpx
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"spark-server/internal/pkg/errs"
|
|
"spark-server/internal/pkg/i18n"
|
|
"spark-server/internal/pkg/reply"
|
|
"spark-server/internal/pkg/reqctx"
|
|
authhandler "spark-server/internal/transport/http/handler/auth"
|
|
clienthandler "spark-server/internal/transport/http/handler/client"
|
|
convhandler "spark-server/internal/transport/http/handler/conversation"
|
|
favhandler "spark-server/internal/transport/http/handler/favorite"
|
|
filehandler "spark-server/internal/transport/http/handler/file"
|
|
friendhandler "spark-server/internal/transport/http/handler/friend"
|
|
grouphandler "spark-server/internal/transport/http/handler/group"
|
|
msghandler "spark-server/internal/transport/http/handler/message"
|
|
metahandler "spark-server/internal/transport/http/handler/meta"
|
|
momenthandler "spark-server/internal/transport/http/handler/moment"
|
|
musichandler "spark-server/internal/transport/http/handler/music"
|
|
smshandler "spark-server/internal/transport/http/handler/sms"
|
|
squarehandler "spark-server/internal/transport/http/handler/square"
|
|
userhandler "spark-server/internal/transport/http/handler/user"
|
|
"spark-server/internal/transport/http/respond"
|
|
)
|
|
|
|
func registerRoutes(r *gin.Engine, deps *EngineDeps) {
|
|
registerDocs(r)
|
|
registerHealth(r, deps.Health)
|
|
registerAdminRoutes(r, deps)
|
|
v1 := r.Group("/v1")
|
|
registerMetaRoutes(v1)
|
|
registerAuthRoutes(v1, deps)
|
|
registerSMSRoutes(v1, deps)
|
|
registerClientRoutes(v1, deps)
|
|
registerUserRoutes(v1, deps)
|
|
registerFriendRoutes(v1, deps)
|
|
registerGroupRoutes(v1, deps)
|
|
registerFileRoutes(v1, deps)
|
|
registerFavoriteRoutes(v1, deps)
|
|
registerMomentRoutes(v1, deps)
|
|
registerSquareRoutes(v1, deps)
|
|
registerMusicRoutes(v1, deps)
|
|
registerConversationRoutes(v1, deps)
|
|
registerMessageRoutes(v1, deps)
|
|
}
|
|
|
|
func registerHealth(r *gin.Engine, h Health) {
|
|
r.GET("/healthz", func(c *gin.Context) {
|
|
JSON(c, gin.H{"status": "ok"})
|
|
})
|
|
r.GET("/readyz", func(c *gin.Context) {
|
|
if h == nil {
|
|
JSON(c, gin.H{"status": "ok", "ready": true})
|
|
return
|
|
}
|
|
ok, data := h.Ready(c.Request.Context())
|
|
if ok {
|
|
JSON(c, data)
|
|
return
|
|
}
|
|
lang := reqctx.Lang(c.Request.Context())
|
|
c.JSON(http.StatusServiceUnavailable, reply.Stamp(c.Request.Context(), reply.FailData(
|
|
errs.ErrAvailable.Code,
|
|
i18n.ErrorMsg(lang, errs.ErrAvailable.Code),
|
|
data,
|
|
)))
|
|
})
|
|
}
|
|
|
|
func registerMetaRoutes(v1 *gin.RouterGroup) {
|
|
h := metahandler.New()
|
|
v1.GET("/meta/enums", h.Enums)
|
|
}
|
|
|
|
func registerAuthRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
g := v1.Group("/auth")
|
|
if deps.Login == nil {
|
|
return
|
|
}
|
|
h := authhandler.New(deps.Login)
|
|
g.POST("/login", h.Login)
|
|
g.POST("/password-login", h.PasswordLogin)
|
|
g.POST("/token/refresh", h.Refresh)
|
|
g.POST("/logout", h.Logout)
|
|
if deps.Client != nil {
|
|
ch := clienthandler.New(deps.Client)
|
|
g.POST("/password", ch.SetPassword)
|
|
}
|
|
}
|
|
|
|
func registerClientRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Client == nil {
|
|
return
|
|
}
|
|
h := clienthandler.New(deps.Client)
|
|
v1.GET("/legal/agreements", h.LegalAgreements)
|
|
v1.POST("/feedback", h.SubmitFeedback)
|
|
v1.GET("/subscriptions/plans", h.SubscriptionPlans)
|
|
}
|
|
|
|
func registerSMSRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.SMS == nil {
|
|
return
|
|
}
|
|
h := smshandler.New(deps.SMS)
|
|
g := v1.Group("/sms")
|
|
g.POST("/codes", h.SendCode)
|
|
}
|
|
|
|
func registerUserRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Users == nil {
|
|
return
|
|
}
|
|
h := userhandler.New(deps.Users)
|
|
g := v1.Group("/users")
|
|
g.GET("/me", h.Me)
|
|
g.PATCH("/me", h.PatchMe)
|
|
g.DELETE("/me", h.DeleteMe)
|
|
}
|
|
|
|
func registerFriendRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Friends == nil {
|
|
return
|
|
}
|
|
h := friendhandler.New(deps.Friends)
|
|
g := v1.Group("/friends")
|
|
g.GET("/lookup", h.Lookup)
|
|
g.GET("/requests", h.ListRequests)
|
|
g.POST("/requests", h.Apply)
|
|
g.POST("/requests/reject", h.Reject)
|
|
g.GET("", h.List)
|
|
g.POST("", h.Accept)
|
|
g.GET("/:uid", h.Get)
|
|
g.DELETE("/:uid", h.Delete)
|
|
g.PUT("/:uid/remark", h.Remark)
|
|
g.PUT("/:uid/pin", h.Pin)
|
|
g.DELETE("/:uid/pin", h.Unpin)
|
|
g.PUT("/:uid/block", h.Block)
|
|
g.DELETE("/:uid/block", h.Unblock)
|
|
g.POST("/:uid/reports", h.Report)
|
|
}
|
|
|
|
func registerGroupRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Groups == nil {
|
|
return
|
|
}
|
|
h := grouphandler.New(deps.Groups)
|
|
g := v1.Group("/groups")
|
|
g.POST("", h.Create)
|
|
g.GET("", h.List)
|
|
g.GET("/:id/members", h.ListMembers)
|
|
g.POST("/:id/members", h.Invite)
|
|
g.PATCH("/:id/members/:uid", h.UpdateMember)
|
|
g.DELETE("/:id/members/:uid", h.RemoveMember)
|
|
g.POST("/:id/transfer", h.Transfer)
|
|
g.GET("/:id", h.Get)
|
|
g.PATCH("/:id", h.Update)
|
|
g.DELETE("/:id", h.Dissolve)
|
|
}
|
|
|
|
func registerFileRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Files == nil {
|
|
return
|
|
}
|
|
h := filehandler.New(deps.Files)
|
|
g := v1.Group("/files")
|
|
g.POST("", h.Create)
|
|
g.POST("/batch", h.CreateBatch)
|
|
g.POST("/downloads", h.Download)
|
|
g.POST("/downloads/batch", h.DownloadBatch)
|
|
}
|
|
|
|
func registerFavoriteRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Favorites == nil {
|
|
return
|
|
}
|
|
h := favhandler.New(deps.Favorites)
|
|
g := v1.Group("/favorites")
|
|
g.GET("", h.List)
|
|
g.POST("", h.Create)
|
|
g.DELETE("/:id", h.Delete)
|
|
}
|
|
|
|
func registerMomentRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Moments == nil {
|
|
return
|
|
}
|
|
h := momenthandler.New(deps.Moments)
|
|
g := v1.Group("/moments")
|
|
g.GET("", h.Feed)
|
|
g.POST("", h.Publish)
|
|
g.GET("/unread", h.Unread)
|
|
g.PUT("/read", h.Read)
|
|
g.GET("/notices", h.ListNotices)
|
|
g.POST("/notices/read", h.ReadNotices)
|
|
g.GET("/settings", h.GetSettings)
|
|
g.PATCH("/settings", h.PatchSettings)
|
|
g.PUT("/settings/hides/:uid", h.PutHide)
|
|
g.DELETE("/settings/hides/:uid", h.DeleteHide)
|
|
g.GET("/users/:uid", h.Album)
|
|
g.GET("/:id", h.Get)
|
|
g.DELETE("/:id", h.Delete)
|
|
g.PUT("/:id/like", h.Like)
|
|
g.DELETE("/:id/like", h.Unlike)
|
|
g.POST("/:id/comments", h.CreateComment)
|
|
g.DELETE("/:id/comments/:cid", h.DeleteComment)
|
|
}
|
|
|
|
func registerSquareRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Square == nil {
|
|
return
|
|
}
|
|
h := squarehandler.New(deps.Square)
|
|
g := v1.Group("/square")
|
|
g.GET("/posts", h.Feed)
|
|
g.POST("/posts", h.Publish)
|
|
g.GET("/posts/:id", h.Get)
|
|
g.DELETE("/posts/:id", h.Delete)
|
|
g.PUT("/posts/:id/like", h.Like)
|
|
g.DELETE("/posts/:id/like", h.Unlike)
|
|
g.POST("/posts/:id/comments", h.CreateComment)
|
|
g.DELETE("/posts/:id/comments/:cid", h.DeleteComment)
|
|
g.GET("/users/:uid/posts", h.UserPosts)
|
|
g.GET("/notices", h.ListNotices)
|
|
g.GET("/notices/unread", h.NoticeUnread)
|
|
g.POST("/notices/read", h.ReadNotices)
|
|
}
|
|
|
|
func registerMusicRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Music == nil {
|
|
return
|
|
}
|
|
h := musichandler.New(deps.Music)
|
|
g := v1.Group("/music")
|
|
// 客户端可读:无需登录(列表为运营配置的公开曲目元数据)
|
|
g.GET("/playlist", h.Playlist)
|
|
g.GET("/categories", h.Categories)
|
|
g.GET("/settings", h.Settings)
|
|
}
|
|
|
|
func registerConversationRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Sync == nil {
|
|
return
|
|
}
|
|
h := convhandler.New(deps.Sync)
|
|
g := v1.Group("/conversations")
|
|
g.GET("", h.Inbox)
|
|
}
|
|
|
|
func registerMessageRoutes(v1 *gin.RouterGroup, deps *EngineDeps) {
|
|
if deps.Messages == nil {
|
|
return
|
|
}
|
|
h := msghandler.New(deps.Messages)
|
|
g := v1.Group("/messages")
|
|
g.GET("", h.History)
|
|
g.POST("", h.Send)
|
|
g.POST("/:id/recall", h.Recall)
|
|
g.DELETE("/:id", h.Delete)
|
|
}
|
|
|
|
func JSON(c *gin.Context, data any) {
|
|
respond.JSON(c, data)
|
|
}
|
|
|
|
func JSONError(c *gin.Context, err error) {
|
|
respond.JSONError(c, err)
|
|
}
|
|
|
|
func BindJSON(c *gin.Context, dst any) error {
|
|
return respond.BindJSON(c, dst)
|
|
}
|