package aliasmanagement import ( "context" "fmt" "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/google/uuid" "github.com/jmoiron/sqlx" ) // BatchSaveTableFieldAlias 批量保存字段别名字典 func BatchSaveTableFieldAlias(req *BatchTableFieldAliasRequest, ctx context.Context, dbFactory *database.DBFactory, reqCtx *ctx.RequestContext) *response.QueryResult[[]TableFieldAliasDetail] { logger.Debug(fmt.Sprintf("BatchSaveTableFieldAlias-开始批量保存字段别名字典,数量: %d", len(req.Items))) // 参数验证 if len(req.Items) == 0 { logger.ErrorC(reqCtx, "批量保存的字段别名字典列表不能为空") return util.CreateErrorResult[[]TableFieldAliasDetail]("批量保存的字段别名字典列表不能为空", reqCtx) } for i, item := range req.Items { if err := validateTableFieldAliasRequest(&item); err != nil { logger.ErrorC(reqCtx, fmt.Sprintf("第%d个字段别名参数验证失败: %v", i+1, err)) return util.CreateErrorResult[[]TableFieldAliasDetail](fmt.Sprintf("第%d个字段别名参数验证失败: %v", i+1, err), reqCtx) } } // 获取数据库连接并开始事务 db := dbFactory.GetDB() tx, err := db.BeginTxx(ctx, nil) if err != nil { logger.ErrorC(reqCtx, fmt.Sprintf("开始事务失败: %v", err)) return util.CreateErrorResult[[]TableFieldAliasDetail](fmt.Sprintf("开始事务失败: %v", err), reqCtx) } defer func() { if p := recover(); p != nil { tx.Rollback() panic(p) } }() // 获取当前用户 creator := reqCtx.UserID if creator == "" { creator = "system" } var savedItems []TableFieldAliasDetail var errors []string // 批量处理每个字段别名 for i, item := range req.Items { logger.Debug(fmt.Sprintf("处理第%d个字段别名: field_id=%s, table_id=%s, field_alias=%s", i+1, item.FieldID, item.TableID, item.FieldAlias)) var tableFieldAlias tables.DicTableFieldAliasDB var processErr error // 检查字段别名是否已存在(基于field_alias字段的唯一索引) aliasExists, err := checkTableFieldAliasExists(ctx, tx, item.FieldAlias) if err != nil { errors = append(errors, fmt.Sprintf("第%d个字段别名检查存在性失败: %v", i+1, err)) continue } if aliasExists { // 更新字段别名 tableFieldAlias, processErr = updateTableFieldAliasInBatch(ctx, tx, &item) if processErr != nil { errors = append(errors, fmt.Sprintf("第%d个字段别名更新失败: %v", i+1, processErr)) continue } logger.Debug(fmt.Sprintf("更新字段别名成功: %s", item.FieldAlias)) } else { // 检查是否有软删除的记录 softDeletedExists, err := checkSoftDeletedTableFieldAliasExists(ctx, tx, item.FieldAlias) if err != nil { errors = append(errors, fmt.Sprintf("第%d个字段别名检查软删除存在性失败: %v", i+1, err)) continue } if softDeletedExists { // 恢复软删除的字段别名 tableFieldAlias, processErr = restoreTableFieldAliasInBatch(ctx, tx, &item) if processErr != nil { errors = append(errors, fmt.Sprintf("第%d个字段别名恢复失败: %v", i+1, processErr)) continue } logger.Debug(fmt.Sprintf("恢复软删除字段别名成功: %s", item.FieldAlias)) } else { // 插入新的字段别名 tableFieldAlias, processErr = insertTableFieldAliasInBatch(ctx, tx, &item, creator) if processErr != nil { errors = append(errors, fmt.Sprintf("第%d个字段别名插入失败: %v", i+1, processErr)) continue } logger.Debug(fmt.Sprintf("插入字段别名成功: %s", item.FieldAlias)) } } // 添加保存成功的记录 detail := TableFieldAliasDetail{ TableFieldAlias: tableFieldAlias, } savedItems = append(savedItems, detail) } // 如果有错误,回滚事务 if len(errors) > 0 { tx.Rollback() errorMsg := "" for i, errMsg := range errors { if i > 0 { errorMsg += "; " } errorMsg += errMsg } logger.ErrorC(reqCtx, fmt.Sprintf("批量保存字段别名字典失败: %s", errorMsg)) return util.CreateErrorResult[[]TableFieldAliasDetail](fmt.Sprintf("批量保存字段别名字典失败: %s", errorMsg), reqCtx) } // 提交事务 if err := tx.Commit(); err != nil { logger.ErrorC(reqCtx, fmt.Sprintf("提交事务失败: %v", err)) return util.CreateErrorResult[[]TableFieldAliasDetail](fmt.Sprintf("提交事务失败: %v", err), reqCtx) } logger.Debug(fmt.Sprintf("成功批量保存 %d 个字段别名字典", len(savedItems))) return util.CreateSuccessResultData[[]TableFieldAliasDetail](savedItems, reqCtx) } // updateTableFieldAliasInBatch 批量更新中的字段别名更新 func updateTableFieldAliasInBatch(ctx context.Context, tx *sqlx.Tx, req *TableFieldAliasRequest) (tables.DicTableFieldAliasDB, error) { // 使用ID更新(如果提供ID),否则使用field_alias var query string var queryArgs []interface{} if req.ID != "" { query = ` UPDATE dic_table_field_alias SET field_id = ?, table_id = ?, field_name = ?, description = ?, where = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? AND deleted_at IS NULL ` queryArgs = []interface{}{req.FieldID, req.TableID, req.FieldName, req.Description, req.WhereCondition, req.ID} } else { query = ` UPDATE dic_table_field_alias SET field_id = ?, table_id = ?, field_name = ?, description = ?, where = ?, updated_at = CURRENT_TIMESTAMP WHERE field_alias = ? AND deleted_at IS NULL ` queryArgs = []interface{}{req.FieldID, req.TableID, req.FieldName, req.Description, req.WhereCondition, req.FieldAlias} } _, err := tx.ExecContext(ctx, query, queryArgs...) if err != nil { return tables.DicTableFieldAliasDB{}, err } // 查询更新后的记录 var tableFieldAlias tables.DicTableFieldAliasDB selectQuery := ` SELECT id, field_id, table_id, field_name, field_alias, description, where, created_at, updated_at, deleted_at FROM dic_table_field_alias WHERE field_alias = ? AND deleted_at IS NULL ` err = tx.GetContext(ctx, &tableFieldAlias, selectQuery, req.FieldAlias) return tableFieldAlias, err } // restoreTableFieldAliasInBatch 批量恢复中的字段别名恢复 func restoreTableFieldAliasInBatch(ctx context.Context, tx *sqlx.Tx, req *TableFieldAliasRequest) (tables.DicTableFieldAliasDB, error) { query := ` UPDATE dic_table_field_alias SET deleted_at = NULL, field_id = ?, table_id = ?, field_name = ?, description = ?, where = ?, updated_at = CURRENT_TIMESTAMP WHERE field_alias = ? AND deleted_at IS NOT NULL ` _, err := tx.ExecContext(ctx, query, req.FieldID, req.TableID, req.FieldName, req.Description, req.WhereCondition, req.FieldAlias, ) if err != nil { return tables.DicTableFieldAliasDB{}, err } // 查询恢复后的记录 var tableFieldAlias tables.DicTableFieldAliasDB selectQuery := ` SELECT id, field_id, table_id, field_name, field_alias, description, where, created_at, updated_at, deleted_at FROM dic_table_field_alias WHERE field_alias = ? AND deleted_at IS NULL ` err = tx.GetContext(ctx, &tableFieldAlias, selectQuery, req.FieldAlias) return tableFieldAlias, err } // insertTableFieldAliasInBatch 批量插入中的字段别名插入 func insertTableFieldAliasInBatch(ctx context.Context, tx *sqlx.Tx, req *TableFieldAliasRequest, creator string) (tables.DicTableFieldAliasDB, error) { // 生成ID id := req.ID if id == "" { id = uuid.New().String() } query := ` INSERT INTO dic_table_field_alias (id, field_id, table_id, field_name, field_alias, description, where, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) ` _, err := tx.ExecContext(ctx, query, id, req.FieldID, req.TableID, req.FieldName, req.FieldAlias, req.Description, req.WhereCondition, ) if err != nil { return tables.DicTableFieldAliasDB{}, err } // 查询刚插入的记录 var tableFieldAlias tables.DicTableFieldAliasDB selectQuery := ` SELECT id, field_id, table_id, field_name, field_alias, description, where, created_at, updated_at, deleted_at FROM dic_table_field_alias WHERE field_alias = ? AND deleted_at IS NULL ` err = tx.GetContext(ctx, &tableFieldAlias, selectQuery, req.FieldAlias) return tableFieldAlias, err }