合并参数保存触发重打标后端改动
This commit is contained in:
@@ -116,6 +116,7 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String username = SecurityUtils.getUsername();
|
String username = SecurityUtils.getUsername();
|
||||||
|
int updatedCount = 0;
|
||||||
for (ModelParamSaveDTO.ParamValueItem item : saveDTO.getParams()) {
|
for (ModelParamSaveDTO.ParamValueItem item : saveDTO.getParams()) {
|
||||||
int updated = modelParamMapper.updateParamValue(
|
int updated = modelParamMapper.updateParamValue(
|
||||||
projectId,
|
projectId,
|
||||||
@@ -126,9 +127,12 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
|||||||
);
|
);
|
||||||
if (updated == 0) {
|
if (updated == 0) {
|
||||||
log.warn("参数不存在或未更新,paramCode={}", item.getParamCode());
|
log.warn("参数不存在或未更新,paramCode={}", item.getParamCode());
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
updatedCount += updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
submitAutoRebuildIfNeeded(projectId, updatedCount);
|
||||||
} catch (ServiceException e) {
|
} catch (ServiceException e) {
|
||||||
// 业务异常,直接抛出
|
// 业务异常,直接抛出
|
||||||
throw e;
|
throw e;
|
||||||
@@ -218,11 +222,7 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
|||||||
if (!updateList.isEmpty()) {
|
if (!updateList.isEmpty()) {
|
||||||
modelParamMapper.batchUpdateParamValues(updateList);
|
modelParamMapper.batchUpdateParamValues(updateList);
|
||||||
log.info("批量更新参数成功, count={}", updateList.size());
|
log.info("批量更新参数成功, count={}", updateList.size());
|
||||||
if (projectId > 0) {
|
submitAutoRebuildIfNeeded(projectId, updateList.size());
|
||||||
bankTagService.submitAutoRebuild(projectId, TriggerType.AUTO_PARAM_CHANGE);
|
|
||||||
log.info("项目参数保存成功,已触发流水自动重打标: projectId={}, updatedCount={}",
|
|
||||||
projectId, updateList.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (ServiceException e) {
|
} catch (ServiceException e) {
|
||||||
throw e;
|
throw e;
|
||||||
@@ -300,4 +300,13 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
|||||||
target.setUpdateBy(username);
|
target.setUpdateBy(username);
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void submitAutoRebuildIfNeeded(Long projectId, int updatedCount) {
|
||||||
|
if (projectId == null || projectId <= 0 || updatedCount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bankTagService.submitAutoRebuild(projectId, TriggerType.AUTO_PARAM_CHANGE);
|
||||||
|
log.info("项目参数保存成功,已触发流水自动重打标: projectId={}, updatedCount={}", projectId, updatedCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,16 @@ class CcdiBankTagServiceImplTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private ICcdiProjectService projectService;
|
private ICcdiProjectService projectService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ProjectBankTagRebuildCoordinator coordinator;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void submitAutoRebuild_shouldKeepAutoParamChangeTriggerType() {
|
||||||
|
service.submitAutoRebuild(40L, TriggerType.AUTO_PARAM_CHANGE);
|
||||||
|
|
||||||
|
verify(coordinator).submitAuto(40L, TriggerType.AUTO_PARAM_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void rebuildProject_shouldDeleteOldResultsBeforeSubmittingRuleTasks() {
|
void rebuildProject_shouldDeleteOldResultsBeforeSubmittingRuleTasks() {
|
||||||
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.ArgumentMatchers.anyList;
|
import static org.mockito.ArgumentMatchers.anyList;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.mockStatic;
|
import static org.mockito.Mockito.mockStatic;
|
||||||
@@ -154,6 +155,58 @@ class CcdiModelParamServiceImplTest {
|
|||||||
verify(bankTagService).submitAutoRebuild(40L, TriggerType.AUTO_PARAM_CHANGE);
|
verify(bankTagService).submitAutoRebuild(40L, TriggerType.AUTO_PARAM_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void saveParams_shouldSubmitAutoRebuildAfterProjectParamsUpdated() {
|
||||||
|
CcdiProject project = new CcdiProject();
|
||||||
|
project.setProjectId(40L);
|
||||||
|
project.setConfigType("custom");
|
||||||
|
when(projectMapper.selectById(40L)).thenReturn(project);
|
||||||
|
when(modelParamMapper.updateParamValue(40L, "LARGE_TRANSACTION", "SINGLE_TRANSACTION_AMOUNT", "2000", "admin"))
|
||||||
|
.thenReturn(1);
|
||||||
|
|
||||||
|
ModelParamSaveDTO saveDTO = new ModelParamSaveDTO();
|
||||||
|
saveDTO.setProjectId(40L);
|
||||||
|
saveDTO.setModelCode("LARGE_TRANSACTION");
|
||||||
|
ModelParamSaveDTO.ParamValueItem item = new ModelParamSaveDTO.ParamValueItem();
|
||||||
|
item.setParamCode("SINGLE_TRANSACTION_AMOUNT");
|
||||||
|
item.setParamValue("2000");
|
||||||
|
saveDTO.setParams(List.of(item));
|
||||||
|
|
||||||
|
try (MockedStatic<SecurityUtils> mocked = mockStatic(SecurityUtils.class)) {
|
||||||
|
mocked.when(SecurityUtils::getUsername).thenReturn("admin");
|
||||||
|
|
||||||
|
service.saveParams(saveDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(bankTagService).submitAutoRebuild(40L, TriggerType.AUTO_PARAM_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void saveParams_shouldNotSubmitAutoRebuildWhenNoProjectParamUpdated() {
|
||||||
|
CcdiProject project = new CcdiProject();
|
||||||
|
project.setProjectId(40L);
|
||||||
|
project.setConfigType("custom");
|
||||||
|
when(projectMapper.selectById(40L)).thenReturn(project);
|
||||||
|
when(modelParamMapper.updateParamValue(40L, "LARGE_TRANSACTION", "SINGLE_TRANSACTION_AMOUNT", "2000", "admin"))
|
||||||
|
.thenReturn(0);
|
||||||
|
|
||||||
|
ModelParamSaveDTO saveDTO = new ModelParamSaveDTO();
|
||||||
|
saveDTO.setProjectId(40L);
|
||||||
|
saveDTO.setModelCode("LARGE_TRANSACTION");
|
||||||
|
ModelParamSaveDTO.ParamValueItem item = new ModelParamSaveDTO.ParamValueItem();
|
||||||
|
item.setParamCode("SINGLE_TRANSACTION_AMOUNT");
|
||||||
|
item.setParamValue("2000");
|
||||||
|
saveDTO.setParams(List.of(item));
|
||||||
|
|
||||||
|
try (MockedStatic<SecurityUtils> mocked = mockStatic(SecurityUtils.class)) {
|
||||||
|
mocked.when(SecurityUtils::getUsername).thenReturn("admin");
|
||||||
|
|
||||||
|
service.saveParams(saveDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(bankTagService, never()).submitAutoRebuild(anyLong(), any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void saveAllParams_shouldNotSubmitAutoRebuildForGlobalDefaults() {
|
void saveAllParams_shouldNotSubmitAutoRebuildForGlobalDefaults() {
|
||||||
ModelParamSaveAllDTO saveAllDTO = buildSaveAllDto();
|
ModelParamSaveAllDTO saveAllDTO = buildSaveAllDto();
|
||||||
|
|||||||
@@ -1,36 +1,28 @@
|
|||||||
# 参数保存触发项目流水重打标实施记录
|
# 参数保存触发项目流水重打标后端实施记录
|
||||||
|
|
||||||
## 本次改动
|
## 本次改动
|
||||||
|
|
||||||
- 后端在项目参数批量保存成功后自动触发项目内流水重新打标
|
- 补齐项目级单模型参数保存成功后的自动重打标触发
|
||||||
- 自动重打标由同步执行改为后台异步排队执行
|
- 保持批量参数保存与单模型保存使用一致的触发语义
|
||||||
- 前端在项目参数提交前增加提醒弹窗,确认后再提交保存
|
- 增加触发类型透传测试与后端验证记录
|
||||||
|
|
||||||
## 修改内容
|
## 修改内容
|
||||||
|
|
||||||
### 后端
|
- 在 `CcdiModelParamServiceImpl.saveParams()` 中统计实际更新条数,仅在 `projectId > 0` 且存在实际更新时触发 `submitAutoRebuild`
|
||||||
|
- 抽取 `submitAutoRebuildIfNeeded` 私有方法,统一 `saveParams` 与 `saveAllParams` 的触发条件和日志
|
||||||
- 在 `TriggerType` 中新增 `AUTO_PARAM_CHANGE`
|
- 在 `CcdiModelParamServiceImplTest` 中新增:
|
||||||
- 在 `CcdiModelParamServiceImpl.saveAllParams()` 中,项目级参数保存成功且存在实际更新时触发 `submitAutoRebuild`
|
- 项目级单模型保存成功后触发自动重打标
|
||||||
- 在 `ProjectBankTagRebuildCoordinator` 中新增 `tagRebuildExecutor` 异步调度,自动重打标改为后台执行
|
- 无实际更新时不触发自动重打标
|
||||||
- 增加异步排队窗口的补跑标记,避免重复触发请求在任务创建前被吞掉
|
- 在 `CcdiBankTagServiceImplTest` 中新增 `AUTO_PARAM_CHANGE` 触发类型透传校验
|
||||||
- 在 `BankTagThreadPoolConfig` 中新增项目级重打标线程池配置
|
- 更新后端验证记录,覆盖单模型保存、批量保存、默认参数与未更新场景
|
||||||
|
|
||||||
### 前端
|
|
||||||
|
|
||||||
- 在 `ParamConfig.vue` 的 `handleSaveAll` 中增加确认弹窗
|
|
||||||
- 保存成功提示改为“已开始项目内流水重新打标”
|
|
||||||
- 保存成功后刷新参数列表,并向父页面发出 `refresh-project` 事件
|
|
||||||
|
|
||||||
## 测试与验证
|
## 测试与验证
|
||||||
|
|
||||||
- 后端:
|
```bash
|
||||||
`mvn -pl ccdi-project -Dtest=CcdiModelParamServiceImplTest,ProjectBankTagRebuildCoordinatorTest test`
|
mvn -pl ccdi-project -Dtest=CcdiModelParamServiceImplTest,CcdiBankTagServiceImplTest test
|
||||||
- 前端:
|
```
|
||||||
`cd ruoyi-ui && npm run build:prod`
|
|
||||||
|
|
||||||
## 结果
|
## 结果
|
||||||
|
|
||||||
- 后端相关单元测试全部通过
|
- 后端相关聚焦单元测试全部通过
|
||||||
- 前端生产构建通过
|
- 本次验证未启动额外前后端运行进程,无需清理测试进程
|
||||||
- 未启动额外前后端运行进程,因此无需额外清理测试进程
|
|
||||||
|
|||||||
@@ -2,25 +2,28 @@
|
|||||||
|
|
||||||
## 验证范围
|
## 验证范围
|
||||||
|
|
||||||
- 项目参数批量保存成功后自动提交异步重打标
|
- 项目级单模型参数保存成功后自动异步触发重打标
|
||||||
- 自动重打标通过后台执行器异步排队,不阻塞当前请求线程
|
- 项目级批量参数保存成功后自动异步触发重打标
|
||||||
- 自动重打标在已存在运行任务时仍可记录补跑信号
|
- 全局默认参数保存不触发项目重打标
|
||||||
|
- 参数未实际更新或保存失败时不触发重打标
|
||||||
|
- 自动触发来源透传为 `AUTO_PARAM_CHANGE`
|
||||||
|
|
||||||
## 验证命令
|
## 验证命令
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mvn -pl ccdi-project -Dtest=CcdiModelParamServiceImplTest,ProjectBankTagRebuildCoordinatorTest test
|
mvn -pl ccdi-project -Dtest=CcdiModelParamServiceImplTest,CcdiBankTagServiceImplTest test
|
||||||
```
|
```
|
||||||
|
|
||||||
## 验证结果
|
## 验证结果
|
||||||
|
|
||||||
- 结果:通过
|
- 结果:通过
|
||||||
- `CcdiModelParamServiceImplTest` 通过 6 个用例
|
- `CcdiModelParamServiceImplTest` 通过 8 个用例
|
||||||
- `ProjectBankTagRebuildCoordinatorTest` 通过 6 个用例
|
- `CcdiBankTagServiceImplTest` 通过 8 个用例
|
||||||
- 总计 12 个用例全部通过
|
- 总计 16 个用例全部通过
|
||||||
|
|
||||||
## 关键结论
|
## 关键结论
|
||||||
|
|
||||||
- `saveAllParams` 在项目级参数实际更新成功后会调用 `submitAutoRebuild(projectId, TriggerType.AUTO_PARAM_CHANGE)`
|
- `saveParams` 与 `saveAllParams` 在项目级参数实际更新成功后,都会调用 `submitAutoRebuild(projectId, TriggerType.AUTO_PARAM_CHANGE)`
|
||||||
- `submitAuto` 已改为通过 `tagRebuildExecutor` 异步提交后台执行
|
- `projectId=0` 的全局默认参数保存不会触发项目级重打标
|
||||||
- 当前实现不会为 `projectId=0` 的全局默认参数触发项目重打标
|
- `submitAutoRebuild` 会保持 `AUTO_PARAM_CHANGE` 触发类型透传到协调器
|
||||||
|
- 当参数未实际更新时,不会误触发自动重打标
|
||||||
|
|||||||
Reference in New Issue
Block a user