Files

147 lines
5.0 KiB
Go

package routers
import (
"net/http"
"git.lzcwy.cn/zhengchiliu/zt-closet-backend/internal/middleware"
v1 "git.lzcwy.cn/zhengchiliu/zt-closet-backend/internal/routers/api/v1"
"github.com/gin-gonic/gin"
)
// NewRouter 构建 gin 引擎:注册中间件链与 /api/v1 路由。
func NewRouter() *gin.Engine {
r := gin.New()
// 中间件链:Recovery -> RequestID -> OTel -> Slog -> CORS
r.Use(
middleware.Recovery(),
middleware.RequestID(),
middleware.GinOTelMiddleware(),
middleware.GinSlogMiddleware(),
middleware.CORS(),
)
// 健康检查
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "pong"})
})
// handler 实例
userHandler := v1.NewUserHandler()
quotaHandler := v1.NewQuotaHandler()
horoscopeHandler := v1.NewHoroscopeHandler()
clothesHandler := v1.NewClothesHandler()
outfitHandler := v1.NewOutfitHandler()
closetHandler := v1.NewClosetShareHandler()
outfitShareHandler := v1.NewOutfitShareHandler()
collectHandler := v1.NewCollectHandler()
likeHandler := v1.NewLikeHandler()
notificationHandler := v1.NewNotificationHandler()
goodsHandler := v1.NewGoodsHandler()
orderHandler := v1.NewOrderHandler()
aiHandler := v1.NewAIRecommendHandler()
adRewardHandler := v1.NewAdRewardHandler()
apiV1 := r.Group("/api/v1")
// ===== 公开路由(无需登录)=====
{
apiV1.POST("/user/wxlogin", userHandler.WxLogin)
apiV1.POST("/user/refresh-token", userHandler.RefreshToken)
apiV1.GET("/goods", goodsHandler.List)
apiV1.GET("/goods/:code", goodsHandler.GetByCode)
// 微信支付/退款回调
apiV1.POST("/order/pay/notify", orderHandler.PayNotify)
apiV1.POST("/order/refund/notify", orderHandler.RefundNotify)
// 虚拟支付消息推送(GET 为 URL 配置验证,POST 为业务回调)
apiV1.GET("/xpay/notify", orderHandler.XPayVerify)
apiV1.POST("/xpay/notify", orderHandler.XPayNotify)
}
// ===== 鉴权路由(需登录)=====
auth := apiV1.Group("")
auth.Use(middleware.JWTAuth())
{
// 用户
auth.GET("/user/info", userHandler.InfoGetBySelf)
auth.PUT("/user/profile", userHandler.ProfileUpdate)
auth.POST("/user/avatar/upload", userHandler.AvatarUpload)
// 额度
auth.GET("/quota/info", quotaHandler.Info)
auth.GET("/quota/flow", quotaHandler.FlowList)
// 运势
auth.GET("/horoscope/today", horoscopeHandler.Today)
// 衣物
auth.POST("/clothes/upload", clothesHandler.Upload)
auth.GET("/clothes", clothesHandler.List)
auth.GET("/clothes/:uuid", clothesHandler.Get)
auth.GET("/clothes/:uuid/status", clothesHandler.Status)
auth.PUT("/clothes/:uuid", clothesHandler.Update)
auth.DELETE("/clothes/:uuid", clothesHandler.Delete)
// 穿搭
auth.POST("/outfit", outfitHandler.Create)
auth.GET("/outfit", outfitHandler.List)
// 注意:静态路径 /outfit/community 必须先于 /outfit/:uuid 注册,避免被通配路由抢占
auth.GET("/outfit/community", outfitHandler.Community)
auth.GET("/outfit/:uuid", outfitHandler.Get)
auth.PUT("/outfit/:uuid", outfitHandler.Update)
auth.DELETE("/outfit/:uuid", outfitHandler.Delete)
auth.PUT("/outfit/:uuid/public", outfitHandler.Public)
// 衣柜分享
auth.POST("/closet-share", closetHandler.Create)
auth.GET("/closet-share", closetHandler.List)
auth.GET("/closet-share/received", closetHandler.ReceivedList)
auth.GET("/closet-share/:uuid", closetHandler.Detail)
auth.POST("/closet-share/:uuid/cancel", closetHandler.Cancel)
// 穿搭分享
auth.POST("/outfit-share", outfitShareHandler.Create)
auth.GET("/outfit-share", outfitShareHandler.List)
auth.GET("/outfit-share/received", outfitShareHandler.ReceivedList)
auth.GET("/outfit-share/:uuid", outfitShareHandler.Detail)
auth.POST("/outfit-share/:uuid/cancel", outfitShareHandler.Cancel)
// 收藏
auth.POST("/collect", collectHandler.Collect)
auth.GET("/collect", collectHandler.List)
auth.GET("/collect/:targetUUID", collectHandler.GetByTarget)
// 点赞
auth.POST("/like", likeHandler.Like)
auth.GET("/like/:targetUUID", likeHandler.GetByTarget)
// 通知
auth.GET("/notification", notificationHandler.List)
auth.GET("/notification/unread", notificationHandler.Unread)
// 静态路径 /notification/read-all 与 /notification/:uuid/read 段数不同,不会互相抢占
auth.POST("/notification/read-all", notificationHandler.ReadAll)
auth.GET("/notification/:uuid", notificationHandler.Get)
auth.POST("/notification/:uuid/read", notificationHandler.Read)
// 订单
auth.POST("/order", orderHandler.Create)
auth.POST("/order/virtual", orderHandler.VirtualCreate)
auth.GET("/order", orderHandler.List)
auth.POST("/order/:orderNo/cancel", orderHandler.Cancel)
auth.POST("/order/refund", orderHandler.RefundApply)
// 广告激励额度
auth.POST("/ad-reward/grant", adRewardHandler.Grant)
// AI 推荐(异步:提交任务后轮询结果,避免长耗时请求被超时中断)
auth.POST("/ai-recommend", aiHandler.Submit)
auth.GET("/ai-recommend/status", aiHandler.Status)
auth.POST("/ai-recommend/save", aiHandler.Save)
}
return r
}