仪表盘/浏览器用 GET 校验 URL 时返回 ready;支付事件仍走 POST。 Co-authored-by: Cursor <cursoragent@cursor.com>
232 lines
8.7 KiB
Go
232 lines
8.7 KiB
Go
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
|
||
}
|