Sin descripción
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.

create_config_meta.go 5.7KB

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