package router import ( "backend/config" "backend/internal/controller/analytics" "backend/internal/controller/auth" "backend/internal/controller/customer" "backend/internal/controller/entitlement" "backend/internal/controller/license" "backend/internal/controller/order" "backend/internal/controller/plan" "backend/internal/controller/product" "backend/internal/controller/setting" "backend/middleware" "strings" "github.com/gin-contrib/gzip" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // register 同时注册带和不带 trailing slash 的路由 // Logan.Li func register(r gin.IRoutes, method, relativePath string, handlers ...gin.HandlerFunc) { isParamRoute := strings.Contains(relativePath, ":") switch method { case "GET": r.GET(relativePath, handlers...) if !isParamRoute { r.GET(relativePath+"/", handlers...) } case "POST": r.POST(relativePath, handlers...) if !isParamRoute { r.POST(relativePath+"/", handlers...) } case "PUT": r.PUT(relativePath, handlers...) if !isParamRoute { r.PUT(relativePath+"/", handlers...) } case "DELETE": r.DELETE(relativePath, handlers...) if !isParamRoute { r.DELETE(relativePath+"/", handlers...) } case "PATCH": r.PATCH(relativePath, handlers...) if !isParamRoute { r.PATCH(relativePath+"/", handlers...) } } } // SetupRouter 初始化路由 // Logan.Li func SetupRouter(db *gorm.DB, cfg *config.Config) *gin.Engine { gin.SetMode(cfg.Mode) r := gin.Default() r.RedirectTrailingSlash = false r.RedirectFixedPath = false // Gzip 压缩中间件 // Logan.Li r.Use(gzip.Gzip(gzip.DefaultCompression)) // CORS 中间件 // Logan.Li r.Use(middleware.CORSMiddleware(cfg)) // 健康检查 // Logan.Li r.GET("/health", func(c *gin.Context) { c.JSON(200, gin.H{"code": 0, "message": "ok", "data": nil}) }) // 初始化控制器 // Logan.Li authController := auth.NewAuthController(db, cfg) productController := product.NewProductController(db) customerController := customer.NewCustomerController(db) licenseController := license.NewLicenseController(db) planController := plan.NewPlanController(db) orderController := order.NewOrderController(db) entitlementController := entitlement.NewEntitlementController(db) analyticsController := analytics.NewAnalyticsController(db) settingController := setting.NewSettingController(db) api := r.Group("/api") { // ============ 认证路由(无需 JWT) ============ authGroup := api.Group("/auth") { register(authGroup, "POST", "/login", authController.Login) } // ============ 客户端授权契约(无需认证,供外部工具调用) ============ clientAPI := api.Group("/v1") { // License 验证 / 激活 / 停用 / 心跳 register(clientAPI, "POST", "/license/verify", licenseController.Verify) register(clientAPI, "POST", "/license/activate", licenseController.ActivateDevice) register(clientAPI, "POST", "/license/deactivate", licenseController.Deactivate) register(clientAPI, "POST", "/license/heartbeat", licenseController.Heartbeat) register(clientAPI, "POST", "/license/devices", licenseController.ListDevices) // 产品定价查询(展示用) register(clientAPI, "GET", "/products/code/:code", productController.GetByCode) clientAPI.GET("/products/:product_id/plans", planController.GetByProduct) // 订单与支付(客户端购买入口 + 支付回调) register(clientAPI, "POST", "/orders", orderController.CreateOrder) register(clientAPI, "POST", "/checkout", orderController.Checkout) register(clientAPI, "POST", "/purchase/claim", orderController.ClaimPurchase) register(clientAPI, "POST", "/webhooks/payment", orderController.PaymentWebhook) register(clientAPI, "GET", "/webhooks/waffo", orderController.WaffoWebhookReady) register(clientAPI, "POST", "/webhooks/waffo", orderController.WaffoWebhook) register(clientAPI, "POST", "/purchase/check", orderController.CheckDuplicatePurchase) register(clientAPI, "POST", "/purchase/status", orderController.CheckPurchaseStatus) // 客户权益查询(通过邮箱) register(clientAPI, "GET", "/entitlements/my", entitlementController.GetByEmail) } // ============ 需要认证的管理路由 ============ protected := api.Group("", middleware.AuthMiddleware(cfg)) { // 认证相关 register(protected, "GET", "/auth/me", authController.Me) register(protected, "PUT", "/auth/password", authController.ChangePassword) // 产品管理 products := protected.Group("/products") { register(products, "GET", "", productController.List) register(products, "GET", "/all", productController.GetAll) register(products, "POST", "", productController.Create) register(products, "GET", "/:id", productController.Get) register(products, "PUT", "/:id", productController.Update) register(products, "DELETE", "/:id", productController.Delete) register(products, "PATCH", "/:id/status", productController.UpdateStatus) } // 客户管理 customers := protected.Group("/customers") { register(customers, "GET", "", customerController.List) register(customers, "GET", "/all", customerController.GetAll) register(customers, "POST", "", customerController.Create) register(customers, "GET", "/:id", customerController.Get) register(customers, "PUT", "/:id", customerController.Update) register(customers, "DELETE", "/:id", customerController.Delete) register(customers, "PATCH", "/:id/status", customerController.UpdateStatus) } // License 管理 licenses := protected.Group("/licenses") { register(licenses, "GET", "", licenseController.List) register(licenses, "POST", "", licenseController.Create) register(licenses, "GET", "/export", licenseController.Export) register(licenses, "GET", "/:id", licenseController.Get) register(licenses, "PUT", "/:id", licenseController.Update) register(licenses, "DELETE", "/:id", licenseController.Delete) register(licenses, "POST", "/:id/renew", licenseController.Renew) register(licenses, "POST", "/:id/revoke", licenseController.Revoke) register(licenses, "POST", "/:id/suspend", licenseController.Suspend) register(licenses, "POST", "/:id/activate", licenseController.Activate) register(licenses, "GET", "/:id/activations", licenseController.GetActivations) register(licenses, "POST", "/:id/activations/:activationId/offline", licenseController.ForceOffline) } // 定价计划管理 plans := protected.Group("/plans") { register(plans, "GET", "", planController.List) register(plans, "POST", "", planController.Create) register(plans, "PUT", "/:id", planController.Update) register(plans, "DELETE", "/:id", planController.Delete) register(plans, "PATCH", "/:id/status", planController.ToggleStatus) } // 订单管理 orders := protected.Group("/orders") { register(orders, "GET", "", orderController.List) register(orders, "GET", "/:id", orderController.GetDetail) register(orders, "POST", "/manual-grant", orderController.ManualGrant) } // 客户权益管理 entitlements := protected.Group("/entitlements") { register(entitlements, "GET", "", entitlementController.List) register(entitlements, "GET", "/:id", entitlementController.Get) register(entitlements, "POST", "/:id/revoke", entitlementController.Revoke) register(entitlements, "POST", "/:id/renew", entitlementController.Renew) } // 仪表板与数据分析 dashboard := protected.Group("/dashboard") { register(dashboard, "GET", "/stats", analyticsController.GetDashboardStats) register(dashboard, "GET", "/expiring", analyticsController.GetExpiringLicenses) register(dashboard, "GET", "/activities", analyticsController.GetRecentActivities) register(dashboard, "GET", "/online-stats", analyticsController.GetOnlineStats) register(dashboard, "GET", "/revenue", analyticsController.GetRevenueStats) } analyticsGroup := protected.Group("/analytics") { register(analyticsGroup, "GET", "/license-growth", analyticsController.GetLicenseGrowth) register(analyticsGroup, "GET", "/product-distribution", analyticsController.GetProductDistribution) } // 日志审计与系统设置 logs := protected.Group("/logs") { register(logs, "GET", "", settingController.ListAuditLogs) register(logs, "DELETE", "/clear", settingController.ClearAuditLogs) } system := protected.Group("/settings") { register(system, "GET", "", settingController.Get) register(system, "PUT", "", settingController.Update) register(system, "GET", "/license-templates", settingController.ListLicenseTemplates) register(system, "POST", "/license-templates", settingController.SaveLicenseTemplate) register(system, "DELETE", "/license-templates/:id", settingController.DeleteLicenseTemplate) } } } return r }