package main import ( "fmt" "log" "os" "hunliji-api/models" "hunliji-api/router" "hunliji-api/spark" "hunliji-api/utils" "hunliji-api/visit" "github.com/gin-gonic/gin" "github.com/joho/godotenv" "gorm.io/driver/mysql" "gorm.io/gorm" ) func setTableComment(db *gorm.DB, table, comment string) error { sql := fmt.Sprintf("ALTER TABLE `%s` COMMENT='%s'", table, utils.EscapeMySQLComment(comment)) return db.Exec(sql).Error } func migrateSchema(db *gorm.DB) { tables := []struct { model interface{} comment string name string }{ {&models.TemplateConfig{}, "请柬模板配置", "template_configs"}, {&models.PosterConfig{}, "邀请函海报配置", "poster_configs"}, {&models.UploadConfig{}, "上传配置", "upload_configs"}, {&models.Rsvp{}, "出席回执", "rsvps"}, {&models.Danmaku{}, "祝福弹幕", "danmakus"}, {&models.SiteLike{}, "站点点赞", "site_likes"}, {&models.SiteGift{}, "站点礼物", "site_gifts"}, {&models.GiftConfig{}, "礼物兑换配置", "gift_configs"}, {&models.AiModerationCache{}, "AI审核缓存", "ai_moderation_caches"}, {&visit.SiteVisit{}, "访客记录", "site_visits"}, } for _, t := range tables { opts := fmt.Sprintf("ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='%s'", utils.EscapeMySQLComment(t.comment)) if err := db.Set("gorm:table_options", opts).AutoMigrate(t.model); err != nil { log.Printf("AutoMigrate 失败 %s: %v", t.name, err) } if err := setTableComment(db, t.name, t.comment); err != nil { log.Printf("设置表注释失败 %s: %v", t.name, err) } else { log.Printf("表注释已更新 %s => %s", t.name, t.comment) } } if db.Migrator().HasIndex(&models.SiteLike{}, "idx_site_likes_client_id") { _ = db.Migrator().DropIndex(&models.SiteLike{}, "idx_site_likes_client_id") } } func initDB() *gorm.DB { dbHost := utils.GetEnv("DB_HOST", "root:root@tcp(127.0.0.1:3306)/nl_wedding?charset=utf8mb4&parseTime=True&loc=Local") dsn := dbHost //dsn := "root:mysql_PKC65h@tcp(127.0.0.1:3306)/nl_wedding?charset=utf8mb4&parseTime=True&loc=Local" database, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { log.Fatalf("数据库连接失败: %v", err) } migrateSchema(database) _ = os.MkdirAll("./uploads", os.ModePerm) fmt.Println("数据库初始化成功,表结构已同步,上传目录已就绪") return database } func main() { _ = godotenv.Load() adminAccount := utils.GetEnv("ADMIN_ACCOUNT", "admin") adminPassword := utils.GetEnv("ADMIN_PASSWORD", "admin123") adminSecret := utils.GetEnv("ADMIN_SECRET", "wedding-admin-secret-2026") utils.InitAuth(adminSecret) database := initDB() r := gin.Default() router.Register(r, router.Deps{ DB: database, Spark: spark.NewFromEnv(), AdminAccount: adminAccount, AdminPassword: adminPassword, }) fmt.Println("婚礼纪后端 API 已在 http://localhost:15201 启动") _ = r.Run(":15201") }