package main import ( "bytes" "io" "log" "os" "path/filepath" "time" "x-agents/server/internal/config" "x-agents/server/internal/handler" "x-agents/server/internal/model" "x-agents/server/internal/repository" "x-agents/server/internal/service" "github.com/gin-gonic/gin" ) // Logger 日志记录器 type Logger struct { successLog *log.Logger errorLog *log.Logger } func NewLogger() *Logger { // 创建日志目录 today := time.Now().Format("2006-01-02") logDir := filepath.Join("logs", today) os.MkdirAll(logDir, 0755) // 成功日志 successFile, _ := os.OpenFile(filepath.Join(logDir, "success.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) successLogger := log.New(successFile, "", log.Ldate|log.Ltime|log.Lshortfile) // 错误日志 errorFile, _ := os.OpenFile(filepath.Join(logDir, "failure.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) errorLogger := log.New(errorFile, "", log.Ldate|log.Ltime|log.Lshortfile) return &Logger{ successLog: successLogger, errorLog: errorLogger, } } // LogRequest 记录请求 func (l *Logger) LogRequest(method, path, body string, status int, duration time.Duration) { entry := "[%s] %s %s %d %v" if status >= 400 { l.errorLog.Printf(entry, method, path, body, status, duration) } else { l.successLog.Printf(entry, method, path, body, status, duration) } } var logger *Logger func main() { // 初始化日志 logger = NewLogger() // 1. 加载配置 cfg := config.Load() log.Printf("=== Server starting, port=%s ===", cfg.Port) // 2. 初始化数据库 db, err := config.InitDB(cfg) if err != nil { log.Fatalf("Failed to connect database: %v", err) } // 3. 自动迁移表 db.AutoMigrate(&model.DatabaseInfo{}, &model.SubTableInfo{}) // 4. 初始化 Repository dbRepo := repository.NewDatabaseRepository(db) subTableRepo := repository.NewSubTableRepository(db) // 5. 初始化 Service dbService := service.NewDatabaseService(dbRepo, subTableRepo) subTableService := service.NewSubTableService(subTableRepo, dbRepo) // 6. 初始化 Handler dbHandler := handler.NewDatabaseHandler(dbService) subTableHandler := handler.NewSubTableHandler(subTableService) systemHandler := handler.NewSystemHandler() // 7. 设置路由 r := gin.New() // 添加日志和恢复中间件 r.Use(gin.Logger()) r.Use(gin.Recovery()) // 请求日志中间件 r.Use(func(c *gin.Context) { start := time.Now() path := c.Request.URL.Path // 记录请求体 var requestBody []byte if c.Request.Method == "POST" || c.Request.Method == "PUT" { requestBody, _ = io.ReadAll(c.Request.Body) c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody)) } c.Next() // 记录响应日志 latency := time.Since(start) status := c.Writer.Status() // 使用日志系统记录 logger.LogRequest(c.Request.Method, path, string(requestBody), status, latency) }) // CORS 中间件 r.Use(func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() }) // 数据库管理模块 databaseGroup := r.Group("/database") { databaseGroup.GET("/list", dbHandler.List) databaseGroup.GET("/:id", dbHandler.GetByID) databaseGroup.POST("/check", dbHandler.Check) databaseGroup.POST("/add", dbHandler.Create) databaseGroup.PUT("/:id", dbHandler.Update) databaseGroup.DELETE("/:id", dbHandler.Delete) } // 子表映射管理模块 subTableGroup := r.Group("/sub-table") { subTableGroup.POST("/add", subTableHandler.Create) subTableGroup.GET("/:id", subTableHandler.GetByID) subTableGroup.GET("/database/:database_id", subTableHandler.ListByDatabase) subTableGroup.GET("/mapping/:database_id", subTableHandler.GetMappingFromFile) subTableGroup.GET("/ddl/:database_id", subTableHandler.GetTablesDDL) subTableGroup.PUT("/:id", subTableHandler.Update) subTableGroup.DELETE("/:id", subTableHandler.Delete) } // 系统信息模块 r.GET("/system/info", systemHandler.GetSystemInfo) // 8. 启动服务 log.Printf("Server starting on :%s", cfg.Port) if err := r.Run(":" + cfg.Port); err != nil { log.Fatalf("Failed to start server: %v", err) } }