实现项目打标状态联动并执行前后端适配
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package com.ruoyi.ccdi.project.constants;
|
||||
|
||||
/**
|
||||
* 项目状态常量
|
||||
*/
|
||||
public final class CcdiProjectStatusConstants {
|
||||
|
||||
public static final String PROCESSING = "0";
|
||||
public static final String COMPLETED = "1";
|
||||
public static final String ARCHIVED = "2";
|
||||
public static final String TAGGING = "3";
|
||||
|
||||
private CcdiProjectStatusConstants() {
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public class CcdiProject implements Serializable {
|
||||
/** 配置方式:default-全局默认,custom-自定义 */
|
||||
private String configType;
|
||||
|
||||
/** 项目状态:0-进行中,1-已完成,2-已归档 */
|
||||
/** 项目状态:0-进行中,1-已完成,2-已归档,3-打标中 */
|
||||
private String status;
|
||||
|
||||
/** 是否归档:0-未归档,1-已归档 */
|
||||
|
||||
@@ -20,4 +20,7 @@ public class CcdiProjectStatusCountsVO {
|
||||
|
||||
/** 已归档项目数(状态2) */
|
||||
private Long status2;
|
||||
|
||||
/** 打标中项目数(状态3) */
|
||||
private Long status3;
|
||||
}
|
||||
|
||||
@@ -59,4 +59,28 @@ public interface ICcdiProjectService {
|
||||
* @return 状态统计
|
||||
*/
|
||||
CcdiProjectStatusCountsVO getStatusCounts();
|
||||
|
||||
/**
|
||||
* 更新项目状态
|
||||
*
|
||||
* @param projectId 项目ID
|
||||
* @param status 状态编码
|
||||
* @param operator 操作人
|
||||
*/
|
||||
void updateProjectStatus(Long projectId, String status, String operator);
|
||||
|
||||
/**
|
||||
* 校验项目是否允许进入打标流程
|
||||
*
|
||||
* @param projectId 项目ID
|
||||
*/
|
||||
void ensureProjectCanStartTagging(Long projectId);
|
||||
|
||||
/**
|
||||
* 校验项目是否允许写入
|
||||
*
|
||||
* @param projectId 项目ID
|
||||
* @param message 拒绝文案
|
||||
*/
|
||||
void ensureProjectWritable(Long projectId, String message);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.ruoyi.ccdi.project.service.impl;
|
||||
|
||||
import com.ruoyi.ccdi.project.constants.CcdiProjectStatusConstants;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiBankTagRebuildDTO;
|
||||
import com.ruoyi.ccdi.project.domain.entity.CcdiBankTagResult;
|
||||
import com.ruoyi.ccdi.project.domain.entity.CcdiBankTagRule;
|
||||
@@ -13,6 +14,7 @@ import com.ruoyi.ccdi.project.mapper.CcdiBankTagResultMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiBankTagRuleMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiBankTagTaskMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiBankTagService;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -54,6 +56,9 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
|
||||
@Resource
|
||||
private BankTagRuleConfigResolver configResolver;
|
||||
|
||||
@Resource
|
||||
private ICcdiProjectService projectService;
|
||||
|
||||
@Resource
|
||||
@Qualifier("tagRuleExecutor")
|
||||
private Executor tagRuleExecutor;
|
||||
@@ -88,6 +93,7 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
|
||||
*/
|
||||
public Long rebuildProject(Long projectId, String modelCode, String operator, TriggerType triggerType) {
|
||||
long taskStartTime = System.currentTimeMillis();
|
||||
projectService.updateProjectStatus(projectId, CcdiProjectStatusConstants.TAGGING, operator);
|
||||
CcdiBankTagTask task = buildRunningTask(projectId, modelCode, operator, triggerType);
|
||||
taskMapper.insertTask(task);
|
||||
log.info("【流水标签】任务创建成功: taskId={}, projectId={}, modelCode={}, triggerType={}, operator={}",
|
||||
@@ -128,6 +134,7 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
|
||||
task.setUpdateBy(operator);
|
||||
task.setUpdateTime(new Date());
|
||||
taskMapper.updateTask(task);
|
||||
projectService.updateProjectStatus(projectId, CcdiProjectStatusConstants.COMPLETED, operator);
|
||||
log.info("【流水标签】任务执行成功: taskId={}, projectId={}, modelCode={}, triggerType={}, ruleCount={}, hitCount={}, costMs={}",
|
||||
task.getId(), projectId, modelCode, triggerType, rules.size(), allResults.size(),
|
||||
System.currentTimeMillis() - taskStartTime);
|
||||
@@ -140,6 +147,7 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
|
||||
task.setUpdateBy(operator);
|
||||
task.setUpdateTime(new Date());
|
||||
taskMapper.updateTask(task);
|
||||
projectService.updateProjectStatus(projectId, CcdiProjectStatusConstants.PROCESSING, operator);
|
||||
log.error("【流水标签】任务执行失败: taskId={}, projectId={}, modelCode={}, triggerType={}, error={}",
|
||||
task.getId(), projectId, modelCode, triggerType, ex.getMessage(), ex);
|
||||
throw ex;
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.ruoyi.ccdi.project.mapper.CcdiFileUploadRecordMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiBankTagService;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiFileUploadService;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import com.ruoyi.lsfx.client.LsfxAnalysisClient;
|
||||
import com.ruoyi.lsfx.constants.LsfxConstants;
|
||||
import com.ruoyi.lsfx.domain.request.FetchInnerFlowRequest;
|
||||
@@ -96,6 +97,9 @@ public class CcdiFileUploadServiceImpl implements ICcdiFileUploadService {
|
||||
@Resource
|
||||
private ICcdiBankTagService bankTagService;
|
||||
|
||||
@Resource
|
||||
private ICcdiProjectService projectService;
|
||||
|
||||
/**
|
||||
* 获取临时文件存储目录
|
||||
*/
|
||||
@@ -165,6 +169,8 @@ public class CcdiFileUploadServiceImpl implements ICcdiFileUploadService {
|
||||
throw new IllegalArgumentException("开始日期不能晚于结束日期");
|
||||
}
|
||||
|
||||
projectService.ensureProjectWritable(projectId, "当前项目正在进行银行流水打标,暂不允许上传或拉取数据");
|
||||
|
||||
CcdiProject project = projectMapper.selectById(projectId);
|
||||
if (project == null) {
|
||||
throw new IllegalArgumentException("项目不存在: projectId=" + projectId);
|
||||
@@ -311,6 +317,8 @@ public class CcdiFileUploadServiceImpl implements ICcdiFileUploadService {
|
||||
log.info("【文件上传】开始批量上传: projectId={}, 文件数量={}, username={}",
|
||||
projectId, files.length, username);
|
||||
|
||||
projectService.ensureProjectWritable(projectId, "当前项目正在进行银行流水打标,暂不允许上传或拉取数据");
|
||||
|
||||
// 1. 生成批次ID
|
||||
String batchId = UUID.randomUUID().toString().replace("-", "");
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.ruoyi.ccdi.project.domain.vo.ModelGroupVO;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiModelParamMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiModelParamService;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -46,6 +47,9 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
||||
@Resource
|
||||
private CcdiProjectMapper projectMapper;
|
||||
|
||||
@Resource
|
||||
private ICcdiProjectService projectService;
|
||||
|
||||
@Override
|
||||
public List<ModelListVO> selectModelList(Long projectId) {
|
||||
log.info("selectModelList 被调用,projectId={}", projectId);
|
||||
@@ -102,6 +106,7 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
||||
Long projectId = saveDTO.getProjectId();
|
||||
|
||||
if (projectId > 0) {
|
||||
projectService.ensureProjectWritable(projectId, "当前项目正在进行银行流水打标,暂不允许修改参数");
|
||||
switchToCustomConfigIfNeeded(getRequiredProject(projectId));
|
||||
}
|
||||
|
||||
@@ -178,6 +183,7 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
||||
Long projectId = saveAllDTO.getProjectId();
|
||||
|
||||
if (projectId > 0) {
|
||||
projectService.ensureProjectWritable(projectId, "当前项目正在进行银行流水打标,暂不允许修改参数");
|
||||
switchToCustomConfigIfNeeded(getRequiredProject(projectId));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.ruoyi.ccdi.project.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.ccdi.project.constants.CcdiProjectStatusConstants;
|
||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectQueryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSaveDTO;
|
||||
@@ -18,6 +19,8 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 项目Service实现类
|
||||
*
|
||||
@@ -43,7 +46,7 @@ public class CcdiProjectServiceImpl implements ICcdiProjectService {
|
||||
BeanUtils.copyProperties(dto, project);
|
||||
|
||||
// 3. 设置默认值和流水分析平台ID
|
||||
project.setStatus("0"); // 进行中
|
||||
project.setStatus(CcdiProjectStatusConstants.PROCESSING);
|
||||
project.setIsArchived(0); // 未归档
|
||||
project.setTargetCount(0);
|
||||
project.setHighRiskCount(0);
|
||||
@@ -115,27 +118,70 @@ public class CcdiProjectServiceImpl implements ICcdiProjectService {
|
||||
// 统计进行中项目(状态0)
|
||||
Long status0Count = projectMapper.selectCount(
|
||||
new LambdaQueryWrapper<CcdiProject>()
|
||||
.eq(CcdiProject::getStatus, "0")
|
||||
.eq(CcdiProject::getStatus, CcdiProjectStatusConstants.PROCESSING)
|
||||
);
|
||||
vo.setStatus0(status0Count);
|
||||
|
||||
// 统计已完成项目(状态1)
|
||||
Long status1Count = projectMapper.selectCount(
|
||||
new LambdaQueryWrapper<CcdiProject>()
|
||||
.eq(CcdiProject::getStatus, "1")
|
||||
.eq(CcdiProject::getStatus, CcdiProjectStatusConstants.COMPLETED)
|
||||
);
|
||||
vo.setStatus1(status1Count);
|
||||
|
||||
// 统计已归档项目(状态2)
|
||||
Long status2Count = projectMapper.selectCount(
|
||||
new LambdaQueryWrapper<CcdiProject>()
|
||||
.eq(CcdiProject::getStatus, "2")
|
||||
.eq(CcdiProject::getStatus, CcdiProjectStatusConstants.ARCHIVED)
|
||||
);
|
||||
vo.setStatus2(status2Count);
|
||||
|
||||
Long status3Count = projectMapper.selectCount(
|
||||
new LambdaQueryWrapper<CcdiProject>()
|
||||
.eq(CcdiProject::getStatus, CcdiProjectStatusConstants.TAGGING)
|
||||
);
|
||||
vo.setStatus3(status3Count);
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProjectStatus(Long projectId, String status, String operator) {
|
||||
CcdiProject project = getRequiredProject(projectId);
|
||||
if (CcdiProjectStatusConstants.ARCHIVED.equals(project.getStatus())
|
||||
&& !CcdiProjectStatusConstants.ARCHIVED.equals(status)) {
|
||||
throw new ServiceException("已归档项目不允许重新进入打标流程");
|
||||
}
|
||||
project.setStatus(status);
|
||||
project.setUpdateBy(operator);
|
||||
project.setUpdateTime(new Date());
|
||||
projectMapper.updateById(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureProjectCanStartTagging(Long projectId) {
|
||||
CcdiProject project = getRequiredProject(projectId);
|
||||
if (CcdiProjectStatusConstants.ARCHIVED.equals(project.getStatus())) {
|
||||
throw new ServiceException("已归档项目不允许重新进入打标流程");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureProjectWritable(Long projectId, String message) {
|
||||
CcdiProject project = getRequiredProject(projectId);
|
||||
if (CcdiProjectStatusConstants.TAGGING.equals(project.getStatus())) {
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private CcdiProject getRequiredProject(Long projectId) {
|
||||
CcdiProject project = projectMapper.selectById(projectId);
|
||||
if (project == null) {
|
||||
throw new ServiceException("项目不存在");
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用流水分析平台获取projectId
|
||||
*
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.ruoyi.ccdi.project.service.impl;
|
||||
import com.ruoyi.ccdi.project.domain.entity.CcdiBankTagTask;
|
||||
import com.ruoyi.ccdi.project.domain.enums.TriggerType;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiBankTagTaskMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -27,6 +28,9 @@ public class ProjectBankTagRebuildCoordinator {
|
||||
@Resource
|
||||
private CcdiBankTagServiceImpl bankTagService;
|
||||
|
||||
@Resource
|
||||
private ICcdiProjectService projectService;
|
||||
|
||||
/**
|
||||
* 提交手动重算
|
||||
*
|
||||
@@ -43,6 +47,7 @@ public class ProjectBankTagRebuildCoordinator {
|
||||
throw new ServiceException("当前项目标签正在重算中,请稍后再试");
|
||||
}
|
||||
|
||||
projectService.ensureProjectCanStartTagging(projectId);
|
||||
executeWithLock(projectId, () -> bankTagService.rebuildProject(projectId, modelCode, operator, TriggerType.MANUAL));
|
||||
}
|
||||
|
||||
@@ -62,6 +67,7 @@ public class ProjectBankTagRebuildCoordinator {
|
||||
}
|
||||
|
||||
executeWithLock(projectId, () -> {
|
||||
projectService.ensureProjectCanStartTagging(projectId);
|
||||
boolean needRerun;
|
||||
do {
|
||||
Long taskId = bankTagService.rebuildProject(projectId, null, "system", triggerType);
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.ruoyi.ccdi.project.mapper.CcdiBankTagAnalysisMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiBankTagResultMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiBankTagRuleMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiBankTagTaskMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InOrder;
|
||||
@@ -56,6 +57,9 @@ class CcdiBankTagServiceImplTest {
|
||||
@Mock
|
||||
private BankTagRuleConfigResolver configResolver;
|
||||
|
||||
@Mock
|
||||
private ICcdiProjectService projectService;
|
||||
|
||||
@Test
|
||||
void rebuildProject_shouldDeleteOldResultsBeforeSubmittingRuleTasks() {
|
||||
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
||||
@@ -218,6 +222,42 @@ class CcdiBankTagServiceImplTest {
|
||||
verify(taskMapper).updateTask(argThat(task -> "SUCCESS".equals(task.getStatus()) && task.getFailedRuleCount() == 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldMarkProjectTaggingBeforeExecutingAndCompletedAfterSuccess() {
|
||||
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
||||
|
||||
CcdiBankTagRule rule = buildRule("LARGE_TRANSACTION", "大额交易",
|
||||
"HOUSE_OR_CAR_EXPENSE", "房车消费支出交易", "STATEMENT");
|
||||
BankTagRuleExecutionConfig config = buildConfig(40L, rule);
|
||||
|
||||
when(ruleMapper.selectEnabledRules(null)).thenReturn(List.of(rule));
|
||||
when(configResolver.resolve(40L, rule)).thenReturn(config);
|
||||
when(analysisMapper.selectHouseOrCarExpenseStatements(40L)).thenReturn(List.of());
|
||||
|
||||
service.rebuildProject(40L, null, "tester", TriggerType.MANUAL);
|
||||
|
||||
InOrder inOrder = inOrder(projectService, taskMapper);
|
||||
inOrder.verify(projectService).updateProjectStatus(40L, "3", "tester");
|
||||
inOrder.verify(taskMapper).updateTask(argThat(task -> "SUCCESS".equals(task.getStatus())));
|
||||
inOrder.verify(projectService).updateProjectStatus(40L, "1", "tester");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRollbackProjectStatusToProcessingWhenRebuildFails() {
|
||||
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
|
||||
|
||||
CcdiBankTagRule rule = buildRule("LARGE_TRANSACTION", "大额交易",
|
||||
"HOUSE_OR_CAR_EXPENSE", "房车消费支出交易", "STATEMENT");
|
||||
|
||||
when(ruleMapper.selectEnabledRules(null)).thenReturn(List.of(rule));
|
||||
when(configResolver.resolve(40L, rule)).thenThrow(new RuntimeException("threshold missing"));
|
||||
|
||||
assertThrows(RuntimeException.class,
|
||||
() -> service.rebuildProject(40L, null, "tester", TriggerType.MANUAL));
|
||||
|
||||
verify(projectService).updateProjectStatus(40L, "0", "tester");
|
||||
}
|
||||
|
||||
private CcdiBankTagRule buildRule(String modelCode, String modelName, String ruleCode, String ruleName, String resultType) {
|
||||
CcdiBankTagRule rule = new CcdiBankTagRule();
|
||||
rule.setModelCode(modelCode);
|
||||
|
||||
@@ -12,6 +12,8 @@ import com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiFileUploadRecordMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiBankTagService;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.lsfx.client.LsfxAnalysisClient;
|
||||
import com.ruoyi.lsfx.domain.request.GetBankStatementRequest;
|
||||
import com.ruoyi.lsfx.domain.response.CheckParseStatusResponse;
|
||||
@@ -89,6 +91,9 @@ class CcdiFileUploadServiceImplTest {
|
||||
@Mock
|
||||
private ICcdiBankTagService bankTagService;
|
||||
|
||||
@Mock
|
||||
private ICcdiProjectService projectService;
|
||||
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@@ -154,6 +159,38 @@ class CcdiFileUploadServiceImplTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectPullBankInfoWhenProjectIsTagging() {
|
||||
org.mockito.Mockito.doThrow(new ServiceException("当前项目正在进行银行流水打标,暂不允许上传或拉取数据"))
|
||||
.when(projectService).ensureProjectWritable(PROJECT_ID, "当前项目正在进行银行流水打标,暂不允许上传或拉取数据");
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> service.submitPullBankInfo(
|
||||
PROJECT_ID,
|
||||
List.of("3301"),
|
||||
"2026-01-01",
|
||||
"2026-01-31",
|
||||
1L,
|
||||
"tester"
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectBatchUploadWhenProjectIsTagging() {
|
||||
org.mockito.Mockito.doThrow(new ServiceException("当前项目正在进行银行流水打标,暂不允许上传或拉取数据"))
|
||||
.when(projectService).ensureProjectWritable(PROJECT_ID, "当前项目正在进行银行流水打标,暂不允许上传或拉取数据");
|
||||
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"files",
|
||||
"test.xlsx",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"content".getBytes()
|
||||
);
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> service.batchUploadFiles(PROJECT_ID, new MultipartFile[]{file}, "tester"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void submitTasksAsync_shouldNotCreateLocalBatchLogFiles() throws Exception {
|
||||
setField("uploadPath", tempDir.toString());
|
||||
|
||||
@@ -2,10 +2,15 @@ package com.ruoyi.ccdi.project.service.impl;
|
||||
|
||||
import com.ruoyi.ccdi.project.domain.CcdiModelParam;
|
||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||
import com.ruoyi.ccdi.project.domain.dto.ModelParamGroupDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.ModelParamSaveDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.ModelParamSaveAllDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.ParamValueItem;
|
||||
import com.ruoyi.ccdi.project.domain.vo.ModelParamAllVO;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiModelParamMapper;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -18,6 +23,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -37,6 +43,9 @@ class CcdiModelParamServiceImplTest {
|
||||
@Mock
|
||||
private CcdiProjectMapper projectMapper;
|
||||
|
||||
@Mock
|
||||
private ICcdiProjectService projectService;
|
||||
|
||||
@Test
|
||||
void selectAllParams_shouldReadSystemDefaultsForDefaultProject() {
|
||||
CcdiProject project = new CcdiProject();
|
||||
@@ -95,6 +104,30 @@ class CcdiModelParamServiceImplTest {
|
||||
verify(modelParamMapper).updateParamValue(123L, "LARGE_TRANSACTION", "SINGLE_TRANSACTION_AMOUNT", "2222", "admin");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectSaveAllParamsWhenProjectIsTagging() {
|
||||
org.mockito.Mockito.doThrow(new ServiceException("当前项目正在进行银行流水打标,暂不允许修改参数"))
|
||||
.when(projectService).ensureProjectWritable(40L, "当前项目正在进行银行流水打标,暂不允许修改参数");
|
||||
|
||||
assertThrows(ServiceException.class, () -> service.saveAllParams(buildSaveAllDto()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectSaveParamsWhenProjectIsTagging() {
|
||||
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));
|
||||
|
||||
org.mockito.Mockito.doThrow(new ServiceException("当前项目正在进行银行流水打标,暂不允许修改参数"))
|
||||
.when(projectService).ensureProjectWritable(40L, "当前项目正在进行银行流水打标,暂不允许修改参数");
|
||||
|
||||
assertThrows(ServiceException.class, () -> service.saveParams(saveDTO));
|
||||
}
|
||||
|
||||
private CcdiModelParam buildParam(
|
||||
Long id,
|
||||
Long projectId,
|
||||
@@ -114,4 +147,19 @@ class CcdiModelParamServiceImplTest {
|
||||
param.setSortOrder(1);
|
||||
return param;
|
||||
}
|
||||
|
||||
private ModelParamSaveAllDTO buildSaveAllDto() {
|
||||
ParamValueItem item = new ParamValueItem();
|
||||
item.setParamCode("SINGLE_TRANSACTION_AMOUNT");
|
||||
item.setParamValue("2000");
|
||||
|
||||
ModelParamGroupDTO group = new ModelParamGroupDTO();
|
||||
group.setModelCode("LARGE_TRANSACTION");
|
||||
group.setParams(List.of(item));
|
||||
|
||||
ModelParamSaveAllDTO dto = new ModelParamSaveAllDTO();
|
||||
dto.setProjectId(40L);
|
||||
dto.setModels(List.of(group));
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.ruoyi.ccdi.project.service.impl;
|
||||
|
||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectStatusCountsVO;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.lsfx.client.LsfxAnalysisClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiProjectServiceImplTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiProjectServiceImpl service;
|
||||
|
||||
@Mock
|
||||
private CcdiProjectMapper projectMapper;
|
||||
|
||||
@Mock
|
||||
private LsfxAnalysisClient lsfxAnalysisClient;
|
||||
|
||||
@Test
|
||||
void shouldCountTaggingProjectsSeparately() {
|
||||
when(projectMapper.selectCount(any())).thenReturn(10L, 3L, 4L, 2L, 1L);
|
||||
|
||||
CcdiProjectStatusCountsVO counts = service.getStatusCounts();
|
||||
|
||||
assertEquals(1L, counts.getStatus3());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectUpdatingArchivedProjectToTagging() {
|
||||
CcdiProject archived = new CcdiProject();
|
||||
archived.setProjectId(99L);
|
||||
archived.setStatus("2");
|
||||
when(projectMapper.selectById(99L)).thenReturn(archived);
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> service.updateProjectStatus(99L, "3", "system"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectWritingWhenProjectIsTagging() {
|
||||
CcdiProject tagging = new CcdiProject();
|
||||
tagging.setProjectId(40L);
|
||||
tagging.setStatus("3");
|
||||
when(projectMapper.selectById(40L)).thenReturn(tagging);
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> service.ensureProjectWritable(40L, "当前项目正在进行银行流水打标,暂不允许修改参数"));
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import ch.qos.logback.core.read.ListAppender;
|
||||
import com.ruoyi.ccdi.project.domain.entity.CcdiBankTagTask;
|
||||
import com.ruoyi.ccdi.project.domain.enums.TriggerType;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiBankTagTaskMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -33,6 +34,9 @@ class ProjectBankTagRebuildCoordinatorTest {
|
||||
@Mock
|
||||
private CcdiBankTagServiceImpl bankTagService;
|
||||
|
||||
@Mock
|
||||
private ICcdiProjectService projectService;
|
||||
|
||||
@Test
|
||||
void submitManualRebuild_shouldRejectWhenProjectAlreadyRunning() {
|
||||
CcdiBankTagTask runningTask = new CcdiBankTagTask();
|
||||
@@ -109,4 +113,13 @@ class ProjectBankTagRebuildCoordinatorTest {
|
||||
logger.detachAppender(logAppender);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectSubmittingRebuildForArchivedProject() {
|
||||
org.mockito.Mockito.doThrow(new ServiceException("已归档项目不允许重新进入打标流程"))
|
||||
.when(projectService).ensureProjectCanStartTagging(40L);
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> coordinator.submitManual(40L, null, "tester"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ruoyi.ccdi.project.sql;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class CcdiProjectStatusSqlTest {
|
||||
|
||||
@Test
|
||||
void shouldContainTaggingStatusInInitAndMigrationSql() throws IOException {
|
||||
Path repoRoot = Path.of("..");
|
||||
String initSql = Files.readString(repoRoot.resolve("sql/ccdi_project.sql"));
|
||||
String migrationSql = Files.readString(repoRoot.resolve("sql/migration/2026-03-18-add-project-tagging-status.sql"));
|
||||
|
||||
assertTrue(initSql.contains("打标中"));
|
||||
assertTrue(initSql.contains("'3'"));
|
||||
assertTrue(migrationSql.contains("ccdi_project_status"));
|
||||
assertTrue(migrationSql.contains("打标中"));
|
||||
assertTrue(migrationSql.contains("'3'"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user