gva-pms/server/initialize/gorm.go

170 lines
4.4 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 initialize
import (
"fmt"
"os"
"reflect"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/example"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
"github.com/flipped-aurora/gin-vue-admin/server/service"
"go.uber.org/zap"
"gorm.io/gorm"
)
var monitorService = service.ServiceGroupApp.SystemServiceGroup.MonitorService
func Gorm() *gorm.DB {
switch global.GVA_CONFIG.System.DbType {
case "mysql":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mysql.Dbname
return GormMysql()
case "pgsql":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Pgsql.Dbname
return GormPgSql()
case "oracle":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Oracle.Dbname
return GormOracle()
case "mssql":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mssql.Dbname
return GormMssql()
case "sqlite":
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Sqlite.Dbname
return GormSqlite()
default:
global.GVA_ACTIVE_DBNAME = &global.GVA_CONFIG.Mysql.Dbname
return GormMysql()
}
}
func RegisterTables() {
db := global.GVA_DB
err := db.AutoMigrate(
system.SysApi{},
system.SysIgnoreApi{},
system.SysUser{},
system.SysBaseMenu{},
system.JwtBlacklist{},
system.SysAuthority{},
system.SysDictionary{},
system.SysOperationRecord{},
system.SysAutoCodeHistory{},
system.SysDictionaryDetail{},
system.SysBaseMenuParameter{},
system.SysBaseMenuBtn{},
system.SysAuthorityBtn{},
system.SysAutoCodePackage{},
system.SysExportTemplate{},
system.Condition{},
system.JoinTemplate{},
system.SysParams{},
system.MonitorConfig{},
system.ChangeLog{},
example.ExaFile{},
example.ExaCustomer{},
example.ExaFileChunk{},
example.ExaFileUploadAndDownload{},
example.ExaAttachmentCategory{},
)
if err != nil {
global.GVA_LOG.Error("register table failed", zap.Error(err))
os.Exit(0)
}
err = bizModel()
RegisterHooks(db)
err = monitorService.InitMonitor()
if err != nil {
global.GVA_LOG.Error("register biz_table failed", zap.Error(err))
os.Exit(0)
}
global.GVA_LOG.Info("register table success")
}
func RegisterHooks(db *gorm.DB) {
err := db.Callback().Update().Before("gorm:update").Register("monitor:before_update", func(tx *gorm.DB) {
fmt.Println("==========钩子函数被调用")
if tx.Statement == nil || tx.Statement.Schema == nil {
return
}
// 获取表名(兼容自定义表名)
tableName := tx.Statement.Schema.Table
fmt.Printf("==========当前表名:%s", tableName)
// 获取主键名
pkField := tx.Statement.Schema.PrioritizedPrimaryField
//pkColumn := pkField.DBName
// 获取主键值
var pkValue interface{}
// 方法 1从 WHERE 条件中解析
//if whereClause, ok := tx.Statement.Clauses["WHERE"]; ok {
// if whereExpr, ok := whereClause.Expression.(clause.Where); ok {
// for _, expr := range whereExpr.Exprs {
// if eq, ok := expr.(clause.Eq); ok && eq.Column.Name == pkColumn {
// pkValue = eq.Value
// break
// }
// }
// }
//}
// 方法 2从模型实例中获取
if pkValue == nil && tx.Statement.Dest != nil {
dest := reflect.ValueOf(tx.Statement.Dest)
if dest.Kind() == reflect.Ptr {
dest = dest.Elem()
}
if dest.IsValid() {
pkValue = dest.FieldByName(pkField.Name).Interface()
}
}
if pkValue == nil {
global.GVA_LOG.Warn("无法获取主键值,跳过记录变更", zap.String("table", tableName))
return
}
// 查询旧记录
oldModel := reflect.New(tx.Statement.Schema.ModelType).Interface()
if err := tx.Session(&gorm.Session{}).First(oldModel, pkValue).Error; err != nil {
return
}
// 遍历所有字段,检查是否被监控
for _, field := range tx.Statement.Schema.Fields {
fieldName := field.DBName
if !monitorService.IsFieldMonitored(tableName, fieldName) {
continue // 跳过未监控字段
}
// 对比新旧值
oldVal := getFieldValue(oldModel, field.Name)
newVal := getFieldValue(tx.Statement.Dest, field.Name)
fmt.Printf("oldVal:%v;newVal:%v\n", oldVal, newVal)
if !reflect.DeepEqual(oldVal, newVal) {
// 记录日志
logEntry := system.ChangeLog{
Table: tableName,
Column: fieldName,
OldValue: toString(oldVal),
NewValue: toString(newVal),
}
fmt.Println("logEntry:", logEntry)
global.GVA_DB.Debug().Model(system.ChangeLog{}).Create(&logEntry)
}
}
})
if err != nil {
fmt.Println("register hook failed%%%%%%%%%%%%%%", zap.Error(err))
return
}
}