package database import ( "log/slog" "silk-server-go/internal/config" "silk-server-go/internal/model" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" ) var DB *gorm.DB func Init(cfg *config.Config) error { db, err := gorm.Open(postgres.Open(cfg.PG), &gorm.Config{ Logger: logger.Default.LogMode(logger.Warn), }) if err != nil { return err } DB = db // 自动迁移(错误不阻止启动,仅记录警告) if err := db.AutoMigrate( &model.User{}, &model.Room{}, &model.Device{}, &model.Sensor{}, &model.Threshold{}, &model.Alarm{}, &model.Camera{}, &model.VideoClip{}, &model.AuditLog{}, &model.Telemetry{}, &model.Permission{}, &model.RolePermission{}, ); err != nil { slog.Warn("自动迁移有警告(可忽略)", "err", err) } // 初始化权限种子数据 seedPermissions(db) slog.Info("数据库连接成功,自动迁移完成") return nil } // seedPermissions 初始化权限和角色-权限映射种子数据(幂等) func seedPermissions(db *gorm.DB) { // 1. 写入权限定义(已存在则跳过) codeToID := make(map[string]string) for _, p := range model.AllPermissions { var existing model.Permission if db.Where("code = ?", p.Code).First(&existing).Error == nil { codeToID[p.Code] = existing.ID continue } desc := p.Description perm := model.Permission{ Code: p.Code, Name: p.Name, Description: &desc, } if err := db.Create(&perm).Error; err != nil { slog.Warn("写入权限种子失败", "code", p.Code, "err", err) continue } codeToID[p.Code] = perm.ID } // 2. 写入角色-权限映射(已存在则跳过) for role, codes := range model.RolePermissionMap { for _, code := range codes { pid, ok := codeToID[code] if !ok { continue } var cnt int64 db.Model(&model.RolePermission{}). Where("role = ? AND permission_id = ?", role, pid). Count(&cnt) if cnt > 0 { continue } db.Create(&model.RolePermission{Role: role, PermissionID: pid}) } } }