main.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package main
  2. import (
  3. "license-admin/database"
  4. "license-admin/handlers"
  5. "license-admin/middleware"
  6. "license-admin/models"
  7. "log"
  8. "github.com/gin-gonic/gin"
  9. "gorm.io/gorm"
  10. )
  11. // seedData 初始化种子数据
  12. // 在数据库为空时,自动插入一条测试数据
  13. func seedData(db *gorm.DB) error {
  14. var count int64
  15. // 检查数据库中是否已有数据
  16. if err := db.Model(&models.License{}).Count(&count).Error; err != nil {
  17. return err
  18. }
  19. // 如果数据库为空,插入测试数据
  20. if count == 0 {
  21. testLicense := models.License{
  22. LicenseKey: "TEST-KEY-123456",
  23. BoundDevices: "[]", // 空数组
  24. MaxDevices: 2,
  25. }
  26. if err := db.Create(&testLicense).Error; err != nil {
  27. return err
  28. }
  29. log.Println("已插入测试数据: Key=TEST-KEY-123456, MaxDevices=2")
  30. }
  31. return nil
  32. }
  33. func main() {
  34. // 初始化数据库
  35. if err := database.InitDB(); err != nil {
  36. log.Fatalf("初始化数据库失败: %v", err)
  37. }
  38. // 初始化种子数据(如果数据库为空)
  39. if err := seedData(database.DB); err != nil {
  40. log.Fatalf("初始化种子数据失败: %v", err)
  41. }
  42. // 创建 Gin 路由
  43. r := gin.Default()
  44. // 添加 CORS 中间件(Chrome 插件可能需要)
  45. r.Use(func(c *gin.Context) {
  46. c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
  47. c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
  48. c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
  49. c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
  50. if c.Request.Method == "OPTIONS" {
  51. c.AbortWithStatus(204)
  52. return
  53. }
  54. c.Next()
  55. })
  56. // 静态文件服务(前端页面)
  57. r.Static("/web", "./web")
  58. r.GET("/", func(c *gin.Context) {
  59. c.Redirect(302, "/web/login.html")
  60. })
  61. // 健康检查接口
  62. r.GET("/health", func(c *gin.Context) {
  63. c.JSON(200, gin.H{
  64. "status": "ok",
  65. })
  66. })
  67. // API 路由组
  68. api := r.Group("/api")
  69. {
  70. // 公开接口(不需要认证)
  71. api.POST("/verify", handlers.VerifyLicense(database.DB)) // License 验证接口(Chrome插件使用)
  72. api.POST("/login", handlers.Login()) // 登录接口
  73. // 需要认证的管理接口
  74. api.Use(middleware.AuthMiddleware())
  75. {
  76. // License 管理接口(CRUD)
  77. licenses := api.Group("/licenses")
  78. {
  79. licenses.POST("", handlers.CreateLicense(database.DB)) // 创建 License
  80. licenses.POST("/batch", handlers.BatchCreateLicense(database.DB)) // 批量创建 License
  81. licenses.DELETE("/batch", handlers.BatchDeleteLicense(database.DB)) // 批量删除 License
  82. licenses.PUT("/batch/max-devices", handlers.BatchUpdateMaxDevices(database.DB)) // 批量修改最大设备数
  83. licenses.GET("", handlers.GetLicenseList(database.DB)) // 获取 License 列表
  84. licenses.GET("/export", handlers.ExportLicenses(database.DB)) // 导出 License 列表
  85. licenses.GET("/:id", handlers.GetLicense(database.DB)) // 获取单个 License
  86. licenses.PUT("/:id", handlers.UpdateLicense(database.DB)) // 更新 License
  87. licenses.DELETE("/:id", handlers.DeleteLicense(database.DB)) // 删除 License
  88. licenses.DELETE("/:id/devices/:device_id", handlers.UnbindDevice(database.DB)) // 解绑设备
  89. }
  90. }
  91. }
  92. // 启动服务器
  93. log.Println("License 验证服务启动在 :8080")
  94. if err := r.Run(":8080"); err != nil {
  95. log.Fatalf("启动服务器失败: %v", err)
  96. }
  97. }