package router import ( "affiliate_dash/internal/handler" "affiliate_dash/internal/middleware" "affiliate_dash/internal/model" "affiliate_dash/internal/pkg/jwt" "affiliate_dash/internal/service" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "gorm.io/gorm" ) type Handlers struct { Auth *handler.AuthHandler Dashboard *handler.DashboardHandler Delivery *handler.DeliveryHandler User *handler.UserHandler Open *handler.OpenV1Handler SourceOpen *handler.OpenHandler Merchant *handler.MerchantHandler JWT *jwt.Manager Tenant *service.TenantService OpenDB *gorm.DB SecretCodec *service.SecretCodec OpenAPIKey string OpenAPISecret string OpenSignSkew int64 OpenAPIDebug bool } // requestLogger 访问日志中间件:跳过 /health 健康检查(每 30 秒一次,避免刷屏)。 func requestLogger() gin.HandlerFunc { inner := gin.Logger() return func(c *gin.Context) { if c.Request.URL.Path == "/health" { c.Next() return } inner(c) } } func Setup(h *Handlers) *gin.Engine { r := gin.New() r.Use(requestLogger(), gin.Recovery()) r.Use(cors.New(cors.Config{ AllowOrigins: []string{"*"}, AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"}, AllowHeaders: []string{"Origin", "Content-Type", "Authorization", "X-Merchant-ID", "X-App-Key", "X-Api-Key", "X-Timestamp", "X-Nonce", "X-Sign", "X-Request-ID"}, ExposeHeaders: []string{"Content-Length", "X-Request-ID"}, AllowCredentials: true, })) r.GET("/health", func(c *gin.Context) { c.JSON(200, gin.H{"status": "ok"}) }) api := r.Group("/api") { api.POST("/auth/login", h.Auth.Login) // 用户侧公开发货页接口:商户把发货链接给用户,用户只填写游戏 UID。 delivery := api.Group("/delivery/v1") { delivery.GET("/orders/:order_no", h.Delivery.GetOrder) delivery.POST("/orders/:order_no/bind", h.Delivery.Bind) delivery.POST("/orders/:order_no/submit", h.Delivery.Submit) } // 源头侧接口:上游发货平台查询订单并回传发货结果。 sourceOpen := api.Group("/open/v1") sourceOpen.Use(middleware.SourceOpenAuth(middleware.SourceOpenAuthConfig{ DB: h.OpenDB, APIKey: h.OpenAPIKey, APISecret: h.OpenAPISecret, SkewSeconds: h.OpenSignSkew, Debug: h.OpenAPIDebug, })) { sourceOpen.GET("/orders/:order_no", h.SourceOpen.QueryOrder) sourceOpen.POST("/orders/ship-notify", h.SourceOpen.ShipNotify) } // 商户侧接口:每个商户独立 API 客户端 + HMAC 签名。 clientOpen := api.Group("/client/v1") clientOpen.Use(middleware.OpenAuth(middleware.OpenAuthConfig{ DB: h.OpenDB, Codec: h.SecretCodec, SkewSeconds: h.OpenSignSkew, Debug: h.OpenAPIDebug, })) { clientOpen.GET("/products", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureProducts), middleware.RequireAPIScope("products:read"), h.Open.ListProducts) clientOpen.POST("/orders", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:write"), h.Open.CreateOrder) clientOpen.GET("/orders/:order_no", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:read", "shipping:read"), h.Open.QueryOrder) clientOpen.POST("/orders/:order_no/cancel", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:write"), h.Open.CancelOrder) clientOpen.GET("/orders/:order_no/delivery-link", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:read", "shipping:read"), h.Open.GetDeliveryLink) clientOpen.GET("/orders/:order_no/delivery", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:read", "shipping:read"), h.Open.GetDeliveryOrder) clientOpen.POST("/orders/:order_no/delivery/bind", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:write"), h.Open.BindDeliveryOrder) clientOpen.GET("/orders/:order_no/delivery/bind-result", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:read", "shipping:read"), h.Open.GetDeliveryBindResult) clientOpen.POST("/orders/:order_no/delivery/submit", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:write"), h.Open.SubmitDeliveryOrder) clientOpen.GET("/wallet", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureWallet), middleware.RequireAPIScope("wallet:read"), h.Open.GetWallet) } auth := api.Group("") auth.Use(middleware.Auth(h.JWT)) auth.Use(middleware.Tenant(h.Tenant)) { auth.GET("/auth/profile", h.Auth.Profile) auth.GET("/dashboard", h.Dashboard.Dashboard) // 商户后台:商户就是平台下游客户,成员只代表该商户内部员工。 merchant := auth.Group("/merchant") { merchant.GET("", h.Merchant.Current) merchant.GET("/products", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureProducts), h.Merchant.ListProducts) merchant.POST("/products", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureProducts), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateProduct) merchant.PATCH("/products/:id", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureProducts), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.UpdateProduct) merchant.GET("/orders", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), h.Merchant.ListOrders) merchant.POST("/orders/test", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateTestOrder) merchant.GET("/orders/:order_no/delivery-link", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.GetDeliveryLink) merchant.POST("/orders/:order_no/delivery-link/revoke", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.RevokeDeliveryLink) merchant.POST("/orders/:order_no/delivery-link/restore", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.RestoreDeliveryLink) merchant.GET("/wallet", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureWallet), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator, model.MemberRoleFinance), h.Merchant.GetWallet) merchant.GET("/wallet/ledger", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureWallet), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleFinance), h.Merchant.ListWalletLedger) merchant.POST("/wallet/adjust", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureWallet), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleFinance), h.Merchant.AdjustWallet) merchant.GET("/api-clients", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureAPI), h.Merchant.ListAPIClients) merchant.POST("/api-clients", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureAPI), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateAPIClient) merchant.PATCH("/api-clients/:id/status", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureAPI), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.UpdateAPIClientStatus) merchant.DELETE("/api-clients/:id", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureAPI), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.DeleteAPIClient) merchant.GET("/callbacks", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureCallbacks), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.ListCallbacks) merchant.POST("/callbacks", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureCallbacks), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateCallback) merchant.GET("/members", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.ListMembers) merchant.POST("/members", middleware.RequireMerchantRole(model.MemberRoleOwner), h.Merchant.AddCurrentMerchantMember) } // 用户 / 发货记录 / 平台商户(仅管理员) admin := auth.Group("") admin.Use(middleware.RequireRole(model.RoleAdmin)) { admin.GET("/users", h.User.List) admin.POST("/users", h.User.Create) admin.PATCH("/users/:id/status", h.User.UpdateStatus) admin.GET("/platform/merchants", h.Merchant.ListPlatformMerchants) admin.POST("/platform/merchants", h.Merchant.CreateMerchant) admin.PATCH("/platform/merchants/:id", h.Merchant.UpdateMerchantSettings) admin.POST("/platform/merchants/:id/members", h.Merchant.AddPlatformMerchantMember) admin.GET("/platform/product-catalog", h.Merchant.ListProductCatalog) admin.GET("/platform/merchants/:id/products", h.Merchant.ListMerchantProductsByAdmin) admin.POST("/platform/merchants/:id/products/assign", h.Merchant.AssignProducts) } } } return r }