package main import ( "flag" "log" "net/http" "os" "os/signal" "syscall" "time" "sms-receiver-go/auth" "sms-receiver-go/config" "sms-receiver-go/database" "sms-receiver-go/handlers" "github.com/gorilla/mux" "github.com/robfig/cron/v3" ) func main() { // 记录启动时间 startTime := time.Now() // 命令行参数 configPath := flag.String("config", "config.yaml", "配置文件路径") templatesPath := flag.String("templates", "templates", "模板目录路径") flag.Parse() // 加载配置 cfg, err := config.Load(*configPath) if err != nil { log.Fatalf("加载配置失败: %v", err) } log.Printf("配置加载成功: %s v%s", cfg.App.Name, cfg.App.Version) // 初始化数据库 if err := database.Init(&cfg.Database); err != nil { log.Fatalf("初始化数据库失败: %v", err) } defer database.Close() // 初始化会话存储 if err := auth.Init(cfg.Security.SecretKey); err != nil { log.Fatalf("初始化会话存储失败: %v", err) } // 初始化模板 if err := handlers.InitTemplates(*templatesPath); err != nil { log.Fatalf("初始化模板失败: %v", err) } // 创建路由器 r := mux.NewRouter() // 静态文件 r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) // 页面路由 r.HandleFunc("/", handlers.Index) r.HandleFunc("/login", handlers.Login) r.HandleFunc("/logout", handlers.Logout) r.HandleFunc("/message/{id}", handlers.MessageDetail) r.HandleFunc("/logs", handlers.Logs) r.HandleFunc("/statistics", handlers.Statistics) // API 路由(v1) apiV1 := r.PathPrefix("/api/v1").Subrouter() apiV1.HandleFunc("/receive", handlers.ReceiveSMS) apiV1.HandleFunc("/messages", handlers.APIGetMessages) apiV1.HandleFunc("/statistics", handlers.APIStatistics) // 兼容旧版 API(无版本号) r.HandleFunc("/api/receive", handlers.ReceiveSMS) r.HandleFunc("/api/messages", handlers.APIGetMessages) r.HandleFunc("/api/statistics", handlers.APIStatistics) // 健康检查 r.HandleFunc("/health", handlers.HealthCheck(startTime)) // 配置服务器 server := &http.Server{ Addr: cfg.GetServerAddress(), Handler: r, ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 60 * time.Second, } // 启动后台清理任务 cronInstance := startCleanupTask(cfg) defer cronInstance.Stop() // 优雅关闭 go func() { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) <-sigChan log.Println("正在关闭服务...") server.Close() }() log.Printf("服务启动: http://%s", cfg.GetServerAddress()) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("服务器启动失败: %v", err) } } // startCleanupTask 启动定期清理任务 func startCleanupTask(cfg *config.Config) *cron.Cron { if !cfg.SMS.AutoCleanup { log.Println("自动清理功能未启用") return cron.New(cron.WithSeconds()) } // 创建 cron 实例 c := cron.New(cron.WithSeconds()) // 每天凌晨 3 点执行清理任务 _, err := c.AddFunc("0 0 3 * * *", func() { log.Println("开始执行自动清理任务...") deleted, err := database.CleanupOldMessages(cfg.SMS.CleanupDays) if err != nil { log.Printf("清理旧消息失败: %v", err) } else { log.Printf("自动清理旧消息完成: 删除 %d 条记录", deleted) } }) if err != nil { log.Printf("添加清理任务失败: %v", err) return c } // 启动 cron 服务 c.Start() log.Println("自动清理任务已启动: 每天 03:00 执行") return c }