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( gin.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) 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 }