package store import ( "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" ) // Open 连接 PostgreSQL 并自动迁移全部表。 func Open(dsn string) (*gorm.DB, error) { db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Warn), }) if err != nil { return nil, err } if err := db.AutoMigrate(AllModels()...); err != nil { return nil, err } // 打点原始表用 BRIN(时间局部性强、体积小),PG 专属语法 if err := db.Exec(`CREATE INDEX IF NOT EXISTS idx_metric_events_received_at ON metric_events USING brin (received_at)`).Error; err != nil { return nil, err } return db, SeedPacks(db) } // SeedPacks 初始化三档时长包(已存在则跳过;价格可后续在库内调整)。 func SeedPacks(db *gorm.DB) error { packs := []DurationPack{ {ID: "pack_100", Minutes: 100, PriceCents: 900, UnitDesc: "约 ¥0.09 / 分钟", Tag: "", Sort: 1, Active: true}, {ID: "pack_500", Minutes: 500, PriceCents: 3900, UnitDesc: "约 ¥0.078 / 分钟", Tag: "省 13%", Sort: 2, Active: true}, {ID: "pack_2000", Minutes: 2000, PriceCents: 12900, UnitDesc: "约 ¥0.065 / 分钟", Tag: "省 28%", Sort: 3, Active: true}, } for _, p := range packs { if err := db.Where(DurationPack{ID: p.ID}).FirstOrCreate(&p).Error; err != nil { return err } } return nil }