You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
5.8 KiB
194 lines
5.8 KiB
// @title GoFaster API |
|
// @version 1.0 |
|
// @description GoFaster项目API文档 |
|
// @termsOfService http://swagger.io/terms/ |
|
|
|
// @contact.name API支持 |
|
// @contact.url http://www.gofaster.com/support |
|
// @contact.email support@gofaster.com |
|
|
|
// @license.name Apache 2.0 |
|
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html |
|
|
|
// @host localhost:8080 |
|
// @BasePath /api |
|
// @schemes http |
|
|
|
// @securityDefinitions.apikey BearerAuth |
|
// @in header |
|
// @name Authorization |
|
// @description 请输入 "Bearer " + JWT token,例如: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." |
|
package main |
|
|
|
import ( |
|
"fmt" |
|
"gofaster/internal/auth" |
|
"gofaster/internal/core" |
|
"gofaster/internal/shared/config" |
|
"gofaster/internal/shared/database" |
|
"gofaster/internal/shared/logger" |
|
"gofaster/internal/shared/middleware" |
|
"net/http" |
|
"time" |
|
|
|
// 导入各模块 |
|
_ "gofaster/internal/auth" |
|
"gofaster/internal/auth/migration" |
|
_ "gofaster/internal/workflow" |
|
|
|
"github.com/gin-gonic/gin" |
|
ginSwagger "github.com/swaggo/gin-swagger" |
|
"go.uber.org/zap" |
|
|
|
_ "gofaster/docs" |
|
|
|
swaggerFiles "github.com/swaggo/files" |
|
) |
|
|
|
func main() { |
|
printBanner() |
|
|
|
loc, err := time.LoadLocation("Asia/Shanghai") |
|
if err != nil { |
|
fmt.Printf("时区加载失败: %v\n", err) |
|
} else { |
|
fmt.Printf("时区加载成功: %v\n", loc) |
|
} |
|
|
|
// 列出可用时区(部分) |
|
fmt.Println("当前时间:", time.Now()) |
|
fmt.Println("UTC时间:", time.Now().UTC()) |
|
|
|
// 初始化配置 |
|
cfg, err := config.LoadConfig() |
|
if err != nil { |
|
panic(fmt.Sprintf("配置加载错误: %v\n", err)) |
|
} |
|
|
|
// 初始化日志 |
|
log := logger.NewLogger(cfg.Log.Level, cfg.Log.Path) |
|
defer log.Sync() |
|
|
|
// 初始化数据库 |
|
db, err := database.NewDB(&cfg.DB) |
|
if err != nil { |
|
log.Fatal("Failed to connect database", zap.Error(err)) |
|
} |
|
|
|
// 运行数据库迁移 |
|
if err := migration.RunMigrations(db); err != nil { |
|
log.Fatal("Failed to run database migrations", zap.Error(err)) |
|
} |
|
fmt.Printf("✅ 数据库迁移完成\n") |
|
|
|
// 初始化Redis |
|
redisClient := database.NewRedisClient(&cfg.Redis, log) |
|
defer redisClient.Close() |
|
|
|
// 创建模块管理器 |
|
moduleManager := core.NewModuleManager(log) |
|
|
|
// 自动发现并注册模块 |
|
|
|
if err := core.DiscoverModules(moduleManager); err != nil { |
|
log.Fatal("Failed to discover modules", zap.Error(err)) |
|
} |
|
fmt.Printf("✅ 模块发现完成\n") |
|
|
|
// 初始化所有模块 |
|
|
|
if err := moduleManager.InitModules(cfg, db, redisClient); err != nil { |
|
log.Fatal("Failed to initialize modules", zap.Error(err)) |
|
} |
|
fmt.Printf("✅ 模块初始化完成\n") |
|
|
|
// 创建Gin应用 |
|
app := gin.New() |
|
app.Use( |
|
middleware.Logger(log), |
|
middleware.RecoveryMiddleware(log), |
|
middleware.CORSMiddleware(), |
|
) |
|
|
|
// 注册路由 |
|
|
|
api := app.Group("/api") |
|
moduleManager.RegisterRoutes(api) |
|
fmt.Printf("✅ 路由注册完成\n") |
|
|
|
// 路由同步(在路由注册完成后执行) |
|
if err := syncRoutesOnStartup(app, log, moduleManager); err != nil { |
|
log.Error("路由同步失败", zap.Error(err)) |
|
} else { |
|
fmt.Printf("✅ 路由同步完成\n") |
|
} |
|
|
|
// 健康检查端点 |
|
app.GET("/health", func(c *gin.Context) { |
|
c.JSON(200, gin.H{ |
|
"status": "ok", |
|
"message": "GoFaster API is running", |
|
"timestamp": "2024-01-01T00:00:00Z", |
|
}) |
|
}) |
|
|
|
// Swagger路由配置 |
|
app.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, |
|
ginSwagger.URL("http://localhost:8080/swagger/doc.json"), |
|
ginSwagger.DefaultModelsExpandDepth(-1), |
|
)) |
|
app.GET("/docs", func(c *gin.Context) { |
|
c.Redirect(http.StatusMovedPermanently, "/swagger/index.html") |
|
}) |
|
app.GET("/api-docs", func(c *gin.Context) { |
|
c.Redirect(http.StatusMovedPermanently, "/swagger/index.html") |
|
}) |
|
|
|
// 自定义Swagger UI页面 |
|
app.GET("/swagger-ui", func(c *gin.Context) { |
|
c.File("./swagger-ui.html") |
|
}) |
|
|
|
// 修复版本的Swagger UI页面(确保Authorize按钮显示) |
|
app.GET("/swagger-ui-fixed", func(c *gin.Context) { |
|
c.File("./swagger-ui-fixed.html") |
|
}) |
|
|
|
// 启动服务器 |
|
log.Info("Starting server", zap.String("port", cfg.Server.Port)) |
|
if err := app.Run(":" + cfg.Server.Port); err != nil { |
|
log.Fatal("Failed to start server", zap.Error(err)) |
|
} |
|
|
|
// 清理模块资源 |
|
// moduleManager.Cleanup() // 暂时注释掉,因为ModuleManager没有这个方法 |
|
} |
|
|
|
// syncRoutesOnStartup 应用启动时同步路由 |
|
func syncRoutesOnStartup(app *gin.Engine, log *zap.Logger, moduleManager *core.ModuleManager) error { |
|
// 通过模块管理器获取auth模块并执行路由同步 |
|
authModule, exists := moduleManager.GetModule("auth") |
|
if !exists { |
|
log.Error("auth模块不存在") |
|
return fmt.Errorf("auth模块不存在") |
|
} |
|
if authModule != nil { |
|
if authMod, ok := authModule.(*auth.Module); ok { |
|
return authMod.SyncRoutes(app) |
|
} |
|
} |
|
return nil |
|
} |
|
|
|
func printBanner() { |
|
fmt.Print("\033[92m") |
|
fmt.Println(` |
|
██████╗ ██████╗ ███████╗ █████╗ ███████╗████████╗███████╗███████╗ |
|
██╔════╝ ██╔═══██╗██╔════╝██╔══██╗██╔════╝╚══██╔══╝██╔════╝██╔══██║ |
|
██║ ███╗██║ ██║█████╗ ███████║███████╗ ██║ █████╗ ██████║ |
|
██║ ██║██║ ██║██╔══╝ ██╔══██║╚════██║ ██║ ██╔══╝ ██╔══██╗ |
|
╚██████╔╝╚██████╔╝██╗ ██║ ██║███████║ ██║ ███████╗██║ ██║ |
|
╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ |
|
`) |
|
fmt.Print("\033[0m") |
|
}
|
|
|