fix(ccdi-project): 修复审计字段和批量更新性能问题

1. 补充审计字段设置:
   - updateParamValue 添加 update_by 字段
   - insertBatch 添加 create_by 和 update_by 字段
   - Service 层手动设置审计字段

2. 优化批量更新性能:
   - 从循环单次更新改为批量更新
   - 使用 batchUpdateParamValues 方法
   - 减少数据库交互次数(从18次减少到1次)

影响:提升性能,完善审计追踪
This commit is contained in:
wkc
2026-03-09 09:49:05 +08:00
parent fb537ac0f2
commit c2a95e35ae
3 changed files with 48 additions and 21 deletions

View File

@@ -53,12 +53,14 @@ public interface CcdiModelParamMapper extends BaseMapper<CcdiModelParam> {
* @param modelCode 模型编码 * @param modelCode 模型编码
* @param paramCode 参数编码 * @param paramCode 参数编码
* @param paramValue 参数值 * @param paramValue 参数值
* @param updateBy 更新者
* @return 影响行数 * @return 影响行数
*/ */
int updateParamValue( int updateParamValue(
@Param("projectId") Long projectId, @Param("projectId") Long projectId,
@Param("modelCode") String modelCode, @Param("modelCode") String modelCode,
@Param("paramCode") String paramCode, @Param("paramCode") String paramCode,
@Param("paramValue") String paramValue @Param("paramValue") String paramValue,
@Param("updateBy") String updateBy
); );
} }

View File

@@ -175,7 +175,8 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
projectId, projectId,
saveDTO.getModelCode(), saveDTO.getModelCode(),
item.getParamCode(), item.getParamCode(),
item.getParamValue() item.getParamValue(),
username
); );
if (updated == 0) { if (updated == 0) {
log.warn("参数不存在或未更新paramCode={}", item.getParamCode()); log.warn("参数不存在或未更新paramCode={}", item.getParamCode());
@@ -209,16 +210,17 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
} }
// 复制到项目 // 复制到项目
String username = SecurityUtils.getUsername();
List<CcdiModelParam> projectParams = defaultParams.stream() List<CcdiModelParam> projectParams = defaultParams.stream()
.map(param -> { .map(param -> {
CcdiModelParam newParam = new CcdiModelParam(); CcdiModelParam newParam = new CcdiModelParam();
BeanUtils.copyProperties(param, newParam); BeanUtils.copyProperties(param, newParam);
newParam.setId(null); // 清空ID让数据库自动生成 newParam.setId(null); // 清空ID让数据库自动生成
newParam.setProjectId(projectId); newParam.setProjectId(projectId);
newParam.setCreateBy(null); // 清空审计字段,让 MyBatis Plus 自动填充 // 设置审计字段
newParam.setCreateTime(null); newParam.setCreateBy(username);
newParam.setUpdateBy(null); newParam.setUpdateBy(username);
newParam.setUpdateTime(null); // create_time 和 update_time 由数据库 NOW() 自动设置
return newParam; return newParam;
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -317,16 +319,17 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
} }
// 2. 批量复制所有默认参数到项目 // 2. 批量复制所有默认参数到项目
String username = SecurityUtils.getUsername();
List<CcdiModelParam> projectParams = new ArrayList<>(); List<CcdiModelParam> projectParams = new ArrayList<>();
for (CcdiModelParam param : allDefaultParams) { for (CcdiModelParam param : allDefaultParams) {
CcdiModelParam newParam = new CcdiModelParam(); CcdiModelParam newParam = new CcdiModelParam();
BeanUtils.copyProperties(param, newParam); BeanUtils.copyProperties(param, newParam);
newParam.setId(null);
newParam.setProjectId(projectId); newParam.setProjectId(projectId);
// 清空审计字段,让 MyBatis Plus 自动填充 // 设置审计字段
newParam.setCreateBy(null); newParam.setCreateBy(username);
newParam.setCreateTime(null); newParam.setUpdateBy(username);
newParam.setUpdateBy(null); // create_time 和 update_time 由数据库 NOW() 自动设置
newParam.setUpdateTime(null);
projectParams.add(newParam); projectParams.add(newParam);
} }
@@ -342,22 +345,43 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
} }
} }
// 3. 批量更新所有模型的参数值 // 3. 批量更新所有模型的参数值(性能优化版本)
String username = SecurityUtils.getUsername();
List<CcdiModelParam> updateList = new ArrayList<>();
// 3.1 收集需要更新的参数
for (ModelParamGroupDTO modelGroup : saveAllDTO.getModels()) { for (ModelParamGroupDTO modelGroup : saveAllDTO.getModels()) {
for (ParamValueItem item : modelGroup.getParams()) { for (ParamValueItem item : modelGroup.getParams()) {
int updated = modelParamMapper.updateParamValue( // 查询参数ID用于批量更新
projectId, CcdiModelParam queryParam = new CcdiModelParam();
modelGroup.getModelCode(), queryParam.setProjectId(projectId);
item.getParamCode(), queryParam.setModelCode(modelGroup.getModelCode());
item.getParamValue() queryParam.setParamCode(item.getParamCode());
// 使用 MyBatis Plus 查询
CcdiModelParam existingParam = modelParamMapper.selectOne(
new LambdaQueryWrapper<CcdiModelParam>()
.eq(CcdiModelParam::getProjectId, projectId)
.eq(CcdiModelParam::getModelCode, modelGroup.getModelCode())
.eq(CcdiModelParam::getParamCode, item.getParamCode())
); );
if (updated == 0) {
log.warn("参数不存在或未更新, modelCode={}, paramCode={}", if (existingParam != null) {
existingParam.setParamValue(item.getParamValue());
existingParam.setUpdateBy(username);
updateList.add(existingParam);
} else {
log.warn("参数不存在,无法更新, modelCode={}, paramCode={}",
modelGroup.getModelCode(), item.getParamCode()); modelGroup.getModelCode(), item.getParamCode());
} }
} }
} }
// 3.2 批量更新(一次 SQL 执行)
if (!updateList.isEmpty()) {
modelParamMapper.batchUpdateParamValues(updateList);
log.info("批量更新参数成功, count={}", updateList.size());
}
} catch (ServiceException e) { } catch (ServiceException e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {

View File

@@ -70,6 +70,7 @@
<update id="updateParamValue"> <update id="updateParamValue">
UPDATE ccdi_model_param UPDATE ccdi_model_param
SET param_value = #{paramValue}, SET param_value = #{paramValue},
update_by = #{updateBy},
update_time = NOW() update_time = NOW()
WHERE project_id = #{projectId} WHERE project_id = #{projectId}
AND model_code = #{modelCode} AND model_code = #{modelCode}
@@ -81,14 +82,14 @@
INSERT INTO ccdi_model_param ( INSERT INTO ccdi_model_param (
project_id, model_code, model_name, param_code, param_name, project_id, model_code, model_name, param_code, param_name,
param_desc, param_value, param_unit, sort_order, remark, param_desc, param_value, param_unit, sort_order, remark,
create_time, update_time create_by, create_time, update_by, update_time
) VALUES ) VALUES
<foreach collection="list" item="item" separator=","> <foreach collection="list" item="item" separator=",">
( (
#{item.projectId}, #{item.modelCode}, #{item.modelName}, #{item.projectId}, #{item.modelCode}, #{item.modelName},
#{item.paramCode}, #{item.paramName}, #{item.paramDesc}, #{item.paramCode}, #{item.paramName}, #{item.paramDesc},
#{item.paramValue}, #{item.paramUnit}, #{item.sortOrder}, #{item.paramValue}, #{item.paramUnit}, #{item.sortOrder},
#{item.remark}, NOW(), NOW() #{item.remark}, #{item.createBy}, NOW(), #{item.updateBy}, NOW()
) )
</foreach> </foreach>
</insert> </insert>