Files
backend/pkg/database/seed.go

157 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package database
import (
"carrotskin/internal/model"
"go.uber.org/zap"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
// 默认管理员配置
const (
defaultAdminUsername = "admin"
defaultAdminEmail = "admin@example.com"
defaultAdminPassword = "admin123456" // 首次登录后请立即修改
)
// defaultSystemConfigs 默认系统配置
var defaultSystemConfigs = []model.SystemConfig{
{Key: "site_name", Value: "CarrotSkin", Description: "网站名称", Type: model.ConfigTypeString, IsPublic: true},
{Key: "site_description", Value: "一个优秀的Minecraft皮肤站", Description: "网站描述", Type: model.ConfigTypeString, IsPublic: true},
{Key: "registration_enabled", Value: "true", Description: "是否允许用户注册", Type: model.ConfigTypeBoolean, IsPublic: true},
{Key: "checkin_reward", Value: "10", Description: "签到奖励积分", Type: model.ConfigTypeInteger, IsPublic: true},
{Key: "texture_download_reward", Value: "1", Description: "材质被下载奖励积分", Type: model.ConfigTypeInteger, IsPublic: false},
{Key: "max_textures_per_user", Value: "50", Description: "每个用户最大材质数量", Type: model.ConfigTypeInteger, IsPublic: false},
{Key: "max_profiles_per_user", Value: "5", Description: "每个用户最大角色数量", Type: model.ConfigTypeInteger, IsPublic: false},
{Key: "default_avatar", Value: "", Description: "默认头像URL", Type: model.ConfigTypeString, IsPublic: true},
}
// defaultCasbinRules 默认Casbin权限规则
var defaultCasbinRules = []model.CasbinRule{
// 管理员拥有所有权限
{PType: "p", V0: "admin", V1: "*", V2: "*"},
// 普通用户权限
{PType: "p", V0: "user", V1: "texture", V2: "create"},
{PType: "p", V0: "user", V1: "texture", V2: "read"},
{PType: "p", V0: "user", V1: "texture", V2: "update_own"},
{PType: "p", V0: "user", V1: "texture", V2: "delete_own"},
{PType: "p", V0: "user", V1: "profile", V2: "create"},
{PType: "p", V0: "user", V1: "profile", V2: "read"},
{PType: "p", V0: "user", V1: "profile", V2: "update_own"},
{PType: "p", V0: "user", V1: "profile", V2: "delete_own"},
{PType: "p", V0: "user", V1: "user", V2: "update_own"},
// 角色继承admin 继承 user 的所有权限
{PType: "g", V0: "admin", V1: "user"},
}
// Seed 初始化种子数据
func Seed(logger *zap.Logger) error {
db, err := GetDB()
if err != nil {
return err
}
logger.Info("开始初始化种子数据...")
// 初始化默认管理员用户
if err := seedAdminUser(db, logger); err != nil {
return err
}
// 初始化系统配置
if err := seedSystemConfigs(db, logger); err != nil {
return err
}
// 初始化Casbin权限规则
if err := seedCasbinRules(db, logger); err != nil {
return err
}
logger.Info("种子数据初始化完成")
return nil
}
// seedAdminUser 初始化默认管理员用户
func seedAdminUser(db *gorm.DB, logger *zap.Logger) error {
// 检查是否已存在管理员用户
var count int64
if err := db.Model(&model.User{}).Where("role = ?", "admin").Count(&count).Error; err != nil {
logger.Error("检查管理员用户失败", zap.Error(err))
return err
}
// 如果已存在管理员,跳过创建
if count > 0 {
logger.Info("管理员用户已存在,跳过创建")
return nil
}
// 加密密码
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(defaultAdminPassword), bcrypt.DefaultCost)
if err != nil {
logger.Error("密码加密失败", zap.Error(err))
return err
}
// 创建默认管理员
admin := &model.User{
Username: defaultAdminUsername,
Email: defaultAdminEmail,
Password: string(hashedPassword),
Role: "admin",
Status: 1,
Points: 0,
}
if err := db.Create(admin).Error; err != nil {
logger.Error("创建管理员用户失败", zap.Error(err))
return err
}
logger.Info("默认管理员用户创建成功",
zap.String("username", defaultAdminUsername),
zap.String("email", defaultAdminEmail),
)
logger.Warn("请立即登录并修改默认管理员密码!默认密码请查看源码中的 defaultAdminPassword 常量")
return nil
}
// seedSystemConfigs 初始化系统配置
func seedSystemConfigs(db *gorm.DB, logger *zap.Logger) error {
for _, config := range defaultSystemConfigs {
// 使用 FirstOrCreate 避免重复插入
var existing model.SystemConfig
result := db.Where("key = ?", config.Key).First(&existing)
if result.Error == gorm.ErrRecordNotFound {
if err := db.Create(&config).Error; err != nil {
logger.Error("创建系统配置失败", zap.String("key", config.Key), zap.Error(err))
return err
}
logger.Info("创建系统配置", zap.String("key", config.Key))
}
}
return nil
}
// seedCasbinRules 初始化Casbin权限规则
func seedCasbinRules(db *gorm.DB, logger *zap.Logger) error {
for _, rule := range defaultCasbinRules {
// 检查规则是否已存在
var existing model.CasbinRule
query := db.Where("ptype = ? AND v0 = ? AND v1 = ? AND v2 = ?", rule.PType, rule.V0, rule.V1, rule.V2)
result := query.First(&existing)
if result.Error == gorm.ErrRecordNotFound {
if err := db.Create(&rule).Error; err != nil {
logger.Error("创建Casbin规则失败", zap.String("ptype", rule.PType), zap.Error(err))
return err
}
logger.Info("创建Casbin规则", zap.String("ptype", rule.PType), zap.String("v0", rule.V0), zap.String("v1", rule.V1))
}
}
return nil
}