package register import ( "context" "fmt" "strings" "time" "git.x2erp.com/qdy/go-base/config/core" _ "git.x2erp.com/qdy/go-base/config/subconfigs" "git.x2erp.com/qdy/go-base/ctx" "git.x2erp.com/qdy/go-base/logger" "git.x2erp.com/qdy/go-base/model/response" "git.x2erp.com/qdy/go-base/util" "git.x2erp.com/qdy/go-db/factory/database" "git.x2erp.com/qdy/go-svc-configure/internal/tables" "github.com/jmoiron/sqlx" ) // / RegisterConfigMeta 注册所有配置元信息到数据库 func RegisterConfigMeta(ctx context.Context, dbFactory *database.DBFactory, reqCtx *ctx.RequestContext) *response.QueryResult[map[string]interface{}] { logger.Debug("SyncAllConfigMeta-开始同步配置元信息") creator := reqCtx.UserID allMeta := core.GetAllConfigsMeta() // 记录获取到的配置数量 logger.Debug(fmt.Sprintf("获取到 %d 个配置的元数据", len(allMeta))) // 1. 获取数据库连接 db := dbFactory.GetDB() // 2. 开始事务 tx, err := db.BeginTxx(ctx, nil) if err != nil { logger.ErrorC(reqCtx, fmt.Sprintf("开始事务失败: %v", err)) return util.CreateErrorResult[map[string]interface{}](fmt.Sprintf("开始事务失败: %v", err), reqCtx) } // 确保事务要么提交要么回滚 defer func() { if p := recover(); p != nil { tx.Rollback() panic(p) } }() // 3. 遍历每个配置,先删除后插入 logger.Debug("开始删除各个配置的旧数据") for configName := range allMeta { logger.Debug(fmt.Sprintf("正在删除配置: %s", configName)) if err := deleteConfigMetaByName(ctx, tx, configName); err != nil { tx.Rollback() logger.ErrorC(reqCtx, fmt.Sprintf("删除配置 %s 失败: %v", configName, err)) return util.CreateErrorResult[map[string]interface{}](fmt.Sprintf("删除配置 %s 失败: %v", configName, err), reqCtx) } logger.Debug(fmt.Sprintf("已删除配置: %s", configName)) } logger.Debug(fmt.Sprintf("已完成删除 %d 个配置的旧数据", len(allMeta))) // 4. 生成所有记录 logger.Debug("开始生成配置记录") records := generateConfigMetaRecords(allMeta, creator) logger.Debug(fmt.Sprintf("生成了 %d 条配置记录", len(records))) // 记录每个配置的字段数量 configFieldCounts := make(map[string]int) for _, record := range records { configFieldCounts[record.ConfigName]++ } for configName, count := range configFieldCounts { logger.Debug(fmt.Sprintf("配置 %s 有 %d 个字段", configName, count)) } // 5. 批量插入所有记录 logger.Debug("开始批量插入配置记录") if err := batchInsertConfigMeta(ctx, tx, records); err != nil { tx.Rollback() logger.ErrorC(reqCtx, fmt.Sprintf("批量插入失败: %v", err)) return util.CreateErrorResult[map[string]interface{}](fmt.Sprintf("批量插入失败: %v", err), reqCtx) } logger.Debug(fmt.Sprintf("成功插入 %d 条记录", len(records))) // 6. 提交事务 logger.Debug("正在提交事务") if err := tx.Commit(); err != nil { logger.ErrorC(reqCtx, fmt.Sprintf("提交事务失败: %v", err)) return util.CreateErrorResult[map[string]interface{}](fmt.Sprintf("提交事务失败: %v", err), reqCtx) } logger.Debug("配置元信息同步完成") return util.CreateSuccessResult[map[string]interface{}](reqCtx) } // deleteConfigMetaByName 删除指定配置名称的所有记录 func deleteConfigMetaByName(ctx context.Context, tx *sqlx.Tx, configName string) error { query := "DELETE FROM config_meta WHERE config_name = ?" _, err := tx.ExecContext(ctx, query, configName) if err != nil { return fmt.Errorf("删除配置 %s 失败: %w", configName, err) } return nil } // batchInsertConfigMeta 批量插入配置元信息 func batchInsertConfigMeta(ctx context.Context, tx *sqlx.Tx, records []tables.ConfigMetaDB) error { if len(records) == 0 { return nil } logger.Debug(fmt.Sprintf("执行批量插入,记录数: %d", len(records))) // 使用真正的批量VALUES语法 query := ` INSERT INTO config_meta (id, config_name,field_name,field_type, yaml_name, field_desc, creator, created_at) VALUES ` // 生成占位符和参数 var placeholders []string var args []interface{} for _, record := range records { placeholders = append(placeholders, "(?,?, ?, ?, ?, ?, ?, ?)") args = append(args, record.ID, record.ConfigName, record.FieldName, record.FieldType, record.YamlName, record.FieldDesc, record.Creator, record.CreatedAt, ) } // 拼接VALUES部分 query += strings.Join(placeholders, ",") // 执行批量插入 _, err := tx.ExecContext(ctx, query, args...) if err != nil { return fmt.Errorf("批量插入失败: %w", err) } logger.Debug("批量插入执行成功") return nil } // GenerateConfigMetaRecords 将配置元信息转换为数据库记录 func generateConfigMetaRecords(configs map[string]*core.ConfigMeta, creator string) []tables.ConfigMetaDB { var records []tables.ConfigMetaDB for configName, configInfo := range configs { fieldCount := 0 for fieldName, fieldInfo := range configInfo.Fields { fieldCount++ // 生成唯一ID:配置名:字段名 id := fmt.Sprintf("%s.%s", configName, fieldInfo.YamlName) record := tables.ConfigMetaDB{ ID: id, ConfigName: configName, FieldName: fieldName, FieldType: fieldInfo.Type, YamlName: fieldInfo.YamlName, FieldDesc: fieldInfo.Desc, Creator: creator, CreatedAt: time.Now(), } records = append(records, record) } logger.Debug(fmt.Sprintf("配置 %s 生成 %d 个字段", configName, fieldCount)) } return records }