170 lines
4.4 KiB
Go
170 lines
4.4 KiB
Go
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
|
||
}
|
||
}
|