Няма описание
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package register
  2. import (
  3. "context"
  4. "fmt"
  5. "strings"
  6. "time"
  7. "git.x2erp.com/qdy/go-base/config/core"
  8. _ "git.x2erp.com/qdy/go-base/config/subconfigs"
  9. "git.x2erp.com/qdy/go-base/ctx"
  10. "git.x2erp.com/qdy/go-base/logger"
  11. "git.x2erp.com/qdy/go-base/model/response"
  12. "git.x2erp.com/qdy/go-base/util"
  13. "git.x2erp.com/qdy/go-db/factory/database"
  14. "git.x2erp.com/qdy/go-svc-configure/internal/tables"
  15. "github.com/jmoiron/sqlx"
  16. )
  17. // / RegisterConfigMeta 注册所有配置元信息到数据库
  18. func RegisterConfigMeta(ctx context.Context, dbFactory *database.DBFactory, reqCtx *ctx.RequestContext) *response.QueryResult[map[string]interface{}] {
  19. logger.Debug("SyncAllConfigMeta-开始同步配置元信息")
  20. creator := reqCtx.UserID
  21. allMeta := core.GetAllConfigsMeta()
  22. // 记录获取到的配置数量
  23. logger.Debug(fmt.Sprintf("获取到 %d 个配置的元数据", len(allMeta)))
  24. // 1. 获取数据库连接
  25. db := dbFactory.GetDB()
  26. // 2. 开始事务
  27. tx, err := db.BeginTxx(ctx, nil)
  28. if err != nil {
  29. logger.ErrorC(reqCtx, fmt.Sprintf("开始事务失败: %v", err))
  30. return util.CreateErrorResult[map[string]interface{}](fmt.Sprintf("开始事务失败: %v", err), reqCtx)
  31. }
  32. // 确保事务要么提交要么回滚
  33. defer func() {
  34. if p := recover(); p != nil {
  35. tx.Rollback()
  36. panic(p)
  37. }
  38. }()
  39. // 3. 遍历每个配置,先删除后插入
  40. logger.Debug("开始删除各个配置的旧数据")
  41. for configName := range allMeta {
  42. logger.Debug(fmt.Sprintf("正在删除配置: %s", configName))
  43. if err := deleteConfigMetaByName(ctx, tx, configName); err != nil {
  44. tx.Rollback()
  45. logger.ErrorC(reqCtx, fmt.Sprintf("删除配置 %s 失败: %v", configName, err))
  46. return util.CreateErrorResult[map[string]interface{}](fmt.Sprintf("删除配置 %s 失败: %v", configName, err), reqCtx)
  47. }
  48. logger.Debug(fmt.Sprintf("已删除配置: %s", configName))
  49. }
  50. logger.Debug(fmt.Sprintf("已完成删除 %d 个配置的旧数据", len(allMeta)))
  51. // 4. 生成所有记录
  52. logger.Debug("开始生成配置记录")
  53. records := generateConfigMetaRecords(allMeta, creator)
  54. logger.Debug(fmt.Sprintf("生成了 %d 条配置记录", len(records)))
  55. // 记录每个配置的字段数量
  56. configFieldCounts := make(map[string]int)
  57. for _, record := range records {
  58. configFieldCounts[record.ConfigName]++
  59. }
  60. for configName, count := range configFieldCounts {
  61. logger.Debug(fmt.Sprintf("配置 %s 有 %d 个字段", configName, count))
  62. }
  63. // 5. 批量插入所有记录
  64. logger.Debug("开始批量插入配置记录")
  65. if err := batchInsertConfigMeta(ctx, tx, records); err != nil {
  66. tx.Rollback()
  67. logger.ErrorC(reqCtx, fmt.Sprintf("批量插入失败: %v", err))
  68. return util.CreateErrorResult[map[string]interface{}](fmt.Sprintf("批量插入失败: %v", err), reqCtx)
  69. }
  70. logger.Debug(fmt.Sprintf("成功插入 %d 条记录", len(records)))
  71. // 6. 提交事务
  72. logger.Debug("正在提交事务")
  73. if err := tx.Commit(); err != nil {
  74. logger.ErrorC(reqCtx, fmt.Sprintf("提交事务失败: %v", err))
  75. return util.CreateErrorResult[map[string]interface{}](fmt.Sprintf("提交事务失败: %v", err), reqCtx)
  76. }
  77. logger.Debug("配置元信息同步完成")
  78. return util.CreateSuccessResult[map[string]interface{}](reqCtx)
  79. }
  80. // deleteConfigMetaByName 删除指定配置名称的所有记录
  81. func deleteConfigMetaByName(ctx context.Context, tx *sqlx.Tx, configName string) error {
  82. query := "DELETE FROM config_meta WHERE config_name = ?"
  83. _, err := tx.ExecContext(ctx, query, configName)
  84. if err != nil {
  85. return fmt.Errorf("删除配置 %s 失败: %w", configName, err)
  86. }
  87. return nil
  88. }
  89. // batchInsertConfigMeta 批量插入配置元信息
  90. func batchInsertConfigMeta(ctx context.Context, tx *sqlx.Tx, records []tables.ConfigMetaDB) error {
  91. if len(records) == 0 {
  92. return nil
  93. }
  94. logger.Debug(fmt.Sprintf("执行批量插入,记录数: %d", len(records)))
  95. // 使用真正的批量VALUES语法
  96. query := `
  97. INSERT INTO config_meta
  98. (id, config_name,field_name,field_type, yaml_name, field_desc, creator, created_at)
  99. VALUES
  100. `
  101. // 生成占位符和参数
  102. var placeholders []string
  103. var args []interface{}
  104. for _, record := range records {
  105. placeholders = append(placeholders, "(?,?, ?, ?, ?, ?, ?, ?)")
  106. args = append(args,
  107. record.ID,
  108. record.ConfigName,
  109. record.FieldName,
  110. record.FieldType,
  111. record.YamlName,
  112. record.FieldDesc,
  113. record.Creator,
  114. record.CreatedAt,
  115. )
  116. }
  117. // 拼接VALUES部分
  118. query += strings.Join(placeholders, ",")
  119. // 执行批量插入
  120. _, err := tx.ExecContext(ctx, query, args...)
  121. if err != nil {
  122. return fmt.Errorf("批量插入失败: %w", err)
  123. }
  124. logger.Debug("批量插入执行成功")
  125. return nil
  126. }
  127. // GenerateConfigMetaRecords 将配置元信息转换为数据库记录
  128. func generateConfigMetaRecords(configs map[string]*core.ConfigMeta, creator string) []tables.ConfigMetaDB {
  129. var records []tables.ConfigMetaDB
  130. for configName, configInfo := range configs {
  131. fieldCount := 0
  132. for fieldName, fieldInfo := range configInfo.Fields {
  133. fieldCount++
  134. // 生成唯一ID:配置名:字段名
  135. id := fmt.Sprintf("%s.%s", configName, fieldInfo.YamlName)
  136. record := tables.ConfigMetaDB{
  137. ID: id,
  138. ConfigName: configName,
  139. FieldName: fieldName,
  140. FieldType: fieldInfo.Type,
  141. YamlName: fieldInfo.YamlName,
  142. FieldDesc: fieldInfo.Desc,
  143. Creator: creator,
  144. CreatedAt: time.Now(),
  145. }
  146. records = append(records, record)
  147. }
  148. logger.Debug(fmt.Sprintf("配置 %s 生成 %d 个字段", configName, fieldCount))
  149. }
  150. return records
  151. }