227 lines
4.9 KiB
Go
227 lines
4.9 KiB
Go
package storage
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"goalfymax-admin/internal/config"
|
||
"goalfymax-admin/internal/models"
|
||
"goalfymax-admin/pkg/utils"
|
||
"time"
|
||
|
||
"go.uber.org/zap"
|
||
"gorm.io/driver/mysql"
|
||
"gorm.io/gorm"
|
||
"gorm.io/gorm/logger"
|
||
)
|
||
|
||
var DB *gorm.DB
|
||
|
||
// GormLoggerAdapter GORM logger适配器
|
||
type GormLoggerAdapter struct {
|
||
logger *utils.Logger
|
||
logLevel logger.LogLevel
|
||
}
|
||
|
||
// LogMode 设置日志级别
|
||
func (g *GormLoggerAdapter) LogMode(level logger.LogLevel) logger.Interface {
|
||
g.logLevel = level
|
||
return g
|
||
}
|
||
|
||
// Info 记录信息日志
|
||
func (g *GormLoggerAdapter) Info(ctx context.Context, msg string, data ...interface{}) {
|
||
g.logger.Info(msg, zap.Any("data", data))
|
||
}
|
||
|
||
// Warn 记录警告日志
|
||
func (g *GormLoggerAdapter) Warn(ctx context.Context, msg string, data ...interface{}) {
|
||
g.logger.Warn(msg, zap.Any("data", data))
|
||
}
|
||
|
||
// Error 记录错误日志
|
||
func (g *GormLoggerAdapter) Error(ctx context.Context, msg string, data ...interface{}) {
|
||
g.logger.Error(msg, zap.Any("data", data))
|
||
}
|
||
|
||
// Trace 记录跟踪日志
|
||
func (g *GormLoggerAdapter) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
|
||
// 根据日志级别决定是否记录
|
||
if g.logLevel < logger.Info {
|
||
return
|
||
}
|
||
|
||
elapsed := time.Since(begin)
|
||
sql, rows := fc()
|
||
|
||
if err != nil {
|
||
g.logger.Error("SQL执行失败",
|
||
zap.String("sql", sql),
|
||
zap.Int64("rows", rows),
|
||
zap.Duration("elapsed", elapsed),
|
||
zap.Error(err),
|
||
)
|
||
} else {
|
||
g.logger.Debug("SQL执行成功",
|
||
zap.String("sql", sql),
|
||
zap.Int64("rows", rows),
|
||
zap.Duration("elapsed", elapsed),
|
||
)
|
||
}
|
||
}
|
||
|
||
// InitDatabase 初始化数据库连接
|
||
func InitDatabase(appLogger *utils.Logger) error {
|
||
cfg := config.GetConfig()
|
||
|
||
// 配置数据库连接
|
||
dbConfig := mysql.Config{
|
||
DSN: cfg.Database.DSN,
|
||
}
|
||
|
||
// 创建GORM logger适配器
|
||
gormLogger := &GormLoggerAdapter{logger: appLogger}
|
||
|
||
// 根据配置设置日志级别
|
||
switch cfg.Database.LogLevel {
|
||
case "silent":
|
||
gormLogger.LogMode(logger.Silent)
|
||
case "error":
|
||
gormLogger.LogMode(logger.Error)
|
||
case "warn":
|
||
gormLogger.LogMode(logger.Warn)
|
||
case "info":
|
||
gormLogger.LogMode(logger.Info)
|
||
default:
|
||
gormLogger.LogMode(logger.Info)
|
||
}
|
||
|
||
// 连接数据库
|
||
db, err := gorm.Open(mysql.Open(dbConfig.DSN), &gorm.Config{
|
||
Logger: gormLogger,
|
||
})
|
||
if err != nil {
|
||
return fmt.Errorf("连接数据库失败: %w", err)
|
||
}
|
||
|
||
// 设置连接池
|
||
sqlDB, err := db.DB()
|
||
if err != nil {
|
||
return fmt.Errorf("获取数据库实例失败: %w", err)
|
||
}
|
||
|
||
sqlDB.SetMaxIdleConns(cfg.Database.MaxIdleConns)
|
||
sqlDB.SetMaxOpenConns(cfg.Database.MaxOpenConns)
|
||
|
||
DB = db
|
||
return nil
|
||
}
|
||
|
||
// AutoMigrate 自动迁移数据库表
|
||
func AutoMigrate() error {
|
||
if DB == nil {
|
||
return fmt.Errorf("数据库未初始化")
|
||
}
|
||
|
||
// 迁移所有模型
|
||
err := DB.AutoMigrate(
|
||
&models.UserLevelConfig{},
|
||
&models.GoalfyMaxUser{},
|
||
&models.BalanceOperationLog{},
|
||
&models.InviteCodeApplication{},
|
||
//&models.AuditLog{},
|
||
//&models.User{},
|
||
//&models.Role{},
|
||
//&models.Permission{},
|
||
//&models.Menu{},
|
||
// &models.SystemConfig{},
|
||
//&models.LoginLog{},
|
||
//&models.OperationLog{},
|
||
//&models.UserProjectQuota{},
|
||
//&models.PKCEState{},
|
||
//&models.LoginInfo{},
|
||
//&models.User{},
|
||
//&models.Role{},
|
||
//&models.Permission{},
|
||
//&models.Menu{},
|
||
//&models.SystemConfig{},
|
||
//&models.LoginLog{},
|
||
//&models.OperationLog{},
|
||
//&models.UserProjectQuota{},
|
||
//&models.PKCEState{},
|
||
//&models.LoginInfo{},
|
||
// &models.InviteCode{},
|
||
)
|
||
|
||
if err != nil {
|
||
return fmt.Errorf("数据库迁移失败: %w", err)
|
||
}
|
||
|
||
// 初始化默认用户等级配置
|
||
if err := initDefaultUserLevelConfigs(); err != nil {
|
||
return fmt.Errorf("初始化默认用户等级配置失败: %w", err)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// initDefaultUserLevelConfigs 初始化默认用户等级配置
|
||
func initDefaultUserLevelConfigs() error {
|
||
// 检查是否已存在配置
|
||
var count int64
|
||
if err := DB.Model(&models.UserLevelConfig{}).Count(&count).Error; err != nil {
|
||
return err
|
||
}
|
||
|
||
// 如果已存在配置,则跳过
|
||
if count > 0 {
|
||
return nil
|
||
}
|
||
|
||
// 创建默认配置
|
||
defaultConfigs := []models.UserLevelConfig{
|
||
{
|
||
LevelName: "普通",
|
||
LevelCode: "normal",
|
||
ProjectLimit: 2,
|
||
Description: "普通用户等级,可创建2个项目",
|
||
SortOrder: 1,
|
||
Status: 1,
|
||
},
|
||
{
|
||
LevelName: "VIP",
|
||
LevelCode: "vip",
|
||
ProjectLimit: 10,
|
||
Description: "VIP用户等级,可创建10个项目",
|
||
SortOrder: 2,
|
||
Status: 1,
|
||
},
|
||
{
|
||
LevelName: "内部",
|
||
LevelCode: "internal",
|
||
ProjectLimit: 0,
|
||
Description: "内部用户等级,无项目数限制",
|
||
SortOrder: 3,
|
||
Status: 1,
|
||
},
|
||
}
|
||
|
||
return DB.Create(&defaultConfigs).Error
|
||
}
|
||
|
||
// GetDB 获取数据库实例
|
||
func GetDB() *gorm.DB {
|
||
return DB
|
||
}
|
||
|
||
// Close 关闭数据库连接
|
||
func Close() error {
|
||
if DB != nil {
|
||
sqlDB, err := DB.DB()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return sqlDB.Close()
|
||
}
|
||
return nil
|
||
}
|