Files

227 lines
4.9 KiB
Go
Raw Permalink 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 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
}