// Package main 应用程序入口 package main import ( "context" "log" "net/http" "os" "os/signal" "syscall" "time" "server/common" "server/config" _ "server/docs" "server/middleware" sysController "server/modules/system/controller" yxController "server/modules/yx/controller" "github.com/gin-gonic/gin" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" ) // @title 艺考招生管理系统 API // @version 2.0 // @description 提供用户认证、院校专业、历年招生、计算专业的管理接口 // @host localhost:8080 // @BasePath /api // @securityDefinitions.apikey Bearer // @in header // @name Authorization func main() { // 初始化日志 common.InitLogger() common.Info("========== 应用启动 ==========") // 初始化数据库 config.InitDB() common.Info("数据库初始化完成") // 初始化Redis config.InitRedis() common.Info("Redis初始化完成") // 创建 Gin 引擎 gin.SetMode(gin.ReleaseMode) r := gin.New() r.Use(gin.Recovery()) // 请求日志中间件 r.Use(requestLogMiddleware()) // Swagger 文档 (不需要登录) r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) // API 路由组 api := r.Group("/api") // 中间件顺序: 安全校验 -> 限流 -> 登录鉴权 api.Use(middleware.SecurityMiddleware()) api.Use(middleware.RateLimitMiddleware()) api.Use(middleware.AuthMiddleware()) // 注册 System 模块路由 sysController.NewAuthController().RegisterRoutes(api) sysController.NewSysUserController().RegisterRoutes(api) // 注册 YX 模块路由 yxController.NewYxSchoolMajorController().RegisterRoutes(api) yxController.NewYxHistoryMajorEnrollController().RegisterRoutes(api) yxController.NewYxCalculationMajorController().RegisterRoutes(api) // 创建 HTTP 服务器 srv := &http.Server{ Addr: ":8080", Handler: r, } // 启动服务器 go func() { common.Info("服务器启动: http://localhost:8080") common.Info("Swagger文档: http://localhost:8080/swagger/index.html") log.Println("服务器启动: http://localhost:8080") if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { common.LogError("启动失败: %s", err) log.Fatalf("启动失败: %s\n", err) } }() // 优雅关闭 quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit common.Info("正在关闭服务器...") log.Println("正在关闭服务器...") ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { common.LogError("服务器关闭异常: %v", err) log.Fatal("服务器关闭异常:", err) } // 关闭资源 config.CloseDB() config.CloseRedis() common.Info("========== 应用关闭 ==========") common.CloseLogger() log.Println("服务器已退出") } // requestLogMiddleware 请求日志中间件 func requestLogMiddleware() gin.HandlerFunc { return func(c *gin.Context) { start := time.Now() path := c.Request.URL.Path method := c.Request.Method c.Next() latency := time.Since(start) status := c.Writer.Status() clientIP := c.ClientIP() common.Info("%s %s %d %v %s", method, path, status, latency, clientIP) } }