接入结果总览员工结果同步重算

This commit is contained in:
wkc
2026-03-22 11:47:37 +08:00
parent 0a58ac3251
commit f539c4ba27
6 changed files with 97 additions and 5 deletions

View File

@@ -56,6 +56,14 @@ public interface ICcdiProjectOverviewService {
return new CcdiProjectRiskModelPeopleVO();
}
/**
* 重算结果总览员工结果并同步项目风险人数
*
* @param projectId 项目ID
* @param operator 操作人
*/
void refreshOverviewEmployeeResults(Long projectId, String operator);
/**
* 刷新项目风险人数
*

View File

@@ -129,7 +129,7 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
resultMapper.insertBatch(allResults);
}
projectOverviewService.refreshProjectRiskCounts(projectId, operator);
projectOverviewService.refreshOverviewEmployeeResults(projectId, operator);
task.setStatus(STATUS_SUCCESS);
task.setSuccessRuleCount(rules.size());

View File

@@ -3,8 +3,10 @@ package com.ruoyi.ccdi.project.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.project.domain.CcdiProject;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewEmployeeHitRowVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewStatVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelCardsVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelPeopleItemVO;
@@ -14,6 +16,7 @@ import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskPeopleOverviewVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectTopRiskPeopleItemVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectTopRiskPeopleVO;
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewEmployeeResultMapper;
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewMapper;
import com.ruoyi.ccdi.project.service.ICcdiProjectOverviewService;
import com.ruoyi.common.exception.ServiceException;
@@ -37,6 +40,12 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
@Resource
private CcdiProjectMapper projectMapper;
@Resource
private CcdiProjectOverviewEmployeeResultMapper overviewEmployeeResultMapper;
@Resource
private CcdiProjectOverviewEmployeeResultBuilder overviewEmployeeResultBuilder;
@Override
public CcdiProjectOverviewDashboardVO getDashboard(Long projectId) {
CcdiProject project = overviewMapper.selectDashboardBaseByProjectId(projectId);
@@ -122,6 +131,29 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
return people;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void refreshOverviewEmployeeResults(Long projectId, String operator) {
getRequiredProject(projectId);
overviewEmployeeResultMapper.deleteByProjectId(projectId);
List<CcdiProjectOverviewEmployeeHitRowVO> hitRows =
overviewEmployeeResultMapper.selectEmployeeHitRowsByProjectId(projectId);
List<CcdiProjectOverviewEmployeeResult> results =
overviewEmployeeResultBuilder.build(projectId, hitRows, operator);
if (!results.isEmpty()) {
overviewEmployeeResultMapper.insertBatch(results);
}
projectMapper.updateRiskCountsByProjectId(
projectId,
countRiskLevel(results, "HIGH"),
countRiskLevel(results, "MEDIUM"),
countRiskLevel(results, "LOW"),
operator
);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void refreshProjectRiskCounts(Long projectId, String operator) {
@@ -196,6 +228,12 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
throw new ServiceException("项目风险人数统计结果类型异常");
}
private Integer countRiskLevel(List<CcdiProjectOverviewEmployeeResult> results, String riskLevelCode) {
return Math.toIntExact(results.stream()
.filter(item -> riskLevelCode.equals(item.getRiskLevelCode()))
.count());
}
private Integer defaultZero(Integer value) {
return value == null ? 0 : value;
}

View File

@@ -13,6 +13,7 @@ class CcdiProjectOverviewServiceStructureTest {
assertNotNull(clazz.getMethod("getDashboard", Long.class));
assertNotNull(clazz.getMethod("getRiskPeopleOverview", Long.class));
assertNotNull(clazz.getMethod("getTopRiskPeople", Long.class));
assertNotNull(clazz.getMethod("refreshOverviewEmployeeResults", Long.class, String.class));
assertNotNull(clazz.getMethod("refreshProjectRiskCounts", Long.class, String.class));
}
}

View File

@@ -62,7 +62,7 @@ class CcdiBankTagServiceRiskCountRefreshTest {
private ProjectBankTagRebuildCoordinator coordinator;
@Test
void shouldRefreshProjectRiskCountsAfterTagRebuildSuccess() {
void shouldRefreshOverviewEmployeeResultsAfterTagRebuildSuccess() {
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
CcdiBankTagRule rule = buildRule();
@@ -84,13 +84,13 @@ class CcdiBankTagServiceRiskCountRefreshTest {
inOrder.verify(projectService).updateProjectStatus(40L, "3", "tester");
inOrder.verify(resultMapper).deleteByProjectAndModel(40L, null);
inOrder.verify(resultMapper).insertBatch(anyList());
inOrder.verify(projectOverviewService).refreshProjectRiskCounts(40L, "tester");
inOrder.verify(projectOverviewService).refreshOverviewEmployeeResults(40L, "tester");
inOrder.verify(taskMapper).updateTask(argThat(task -> "SUCCESS".equals(task.getStatus())));
inOrder.verify(projectService).updateProjectStatus(40L, "1", "tester");
}
@Test
void shouldFailTaskWhenRiskCountRefreshFails() {
void shouldFailTaskWhenOverviewEmployeeResultRefreshFails() {
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
CcdiBankTagRule rule = buildRule();
@@ -105,7 +105,7 @@ class CcdiBankTagServiceRiskCountRefreshTest {
when(configResolver.resolve(40L, rule)).thenReturn(config);
when(analysisMapper.selectHouseOrCarExpenseStatements(40L)).thenReturn(List.of(buildHit()));
doThrow(new RuntimeException("refresh failed"))
.when(projectOverviewService).refreshProjectRiskCounts(40L, "tester");
.when(projectOverviewService).refreshOverviewEmployeeResults(40L, "tester");
assertThrows(RuntimeException.class,
() -> service.rebuildProject(40L, null, "tester", TriggerType.MANUAL));

View File

@@ -3,8 +3,10 @@ package com.ruoyi.ccdi.project.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.project.domain.CcdiProject;
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewEmployeeHitRowVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelCardVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelCardsVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelPeopleItemVO;
@@ -12,6 +14,7 @@ import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelPeopleVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskPeopleOverviewVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectTopRiskPeopleVO;
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewEmployeeResultMapper;
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewMapper;
import com.ruoyi.common.exception.ServiceException;
import java.math.BigDecimal;
@@ -44,6 +47,12 @@ class CcdiProjectOverviewServiceImplTest {
@Mock
private CcdiProjectMapper projectMapper;
@Mock
private CcdiProjectOverviewEmployeeResultMapper overviewEmployeeResultMapper;
@Mock
private CcdiProjectOverviewEmployeeResultBuilder overviewEmployeeResultBuilder;
@Test
void shouldBuildDashboardWithNoRiskCount() {
CcdiProject project = new CcdiProject();
@@ -182,6 +191,36 @@ class CcdiProjectOverviewServiceImplTest {
assertEquals("查看详情", result.getRows().getFirst().getActionLabel());
}
@Test
void shouldRefreshOverviewEmployeeResultsAndSyncRiskCounts() {
CcdiProject project = new CcdiProject();
project.setProjectId(43L);
when(projectMapper.selectById(43L)).thenReturn(project);
List<CcdiProjectOverviewEmployeeHitRowVO> hitRows = List.of(new CcdiProjectOverviewEmployeeHitRowVO());
List<CcdiProjectOverviewEmployeeResult> results = List.of(
buildEmployeeResult("HIGH"),
buildEmployeeResult("MEDIUM"),
buildEmployeeResult("LOW")
);
when(overviewEmployeeResultMapper.selectEmployeeHitRowsByProjectId(43L)).thenReturn(hitRows);
when(overviewEmployeeResultBuilder.build(43L, hitRows, "tester")).thenReturn(results);
service.refreshOverviewEmployeeResults(43L, "tester");
org.mockito.InOrder inOrder = org.mockito.Mockito.inOrder(
projectMapper,
overviewEmployeeResultMapper,
overviewEmployeeResultBuilder
);
inOrder.verify(projectMapper).selectById(43L);
inOrder.verify(overviewEmployeeResultMapper).deleteByProjectId(43L);
inOrder.verify(overviewEmployeeResultMapper).selectEmployeeHitRowsByProjectId(43L);
inOrder.verify(overviewEmployeeResultBuilder).build(43L, hitRows, "tester");
inOrder.verify(overviewEmployeeResultMapper).insertBatch(results);
inOrder.verify(projectMapper).updateRiskCountsByProjectId(43L, 1, 1, 1, "tester");
}
@Test
void shouldReturnEmptyCollectionsForRiskModelCardsAndPeople() {
CcdiProject project = new CcdiProject();
@@ -234,4 +273,10 @@ class CcdiProjectOverviewServiceImplTest {
queryDTO.setPageSize(10);
return queryDTO;
}
private CcdiProjectOverviewEmployeeResult buildEmployeeResult(String riskLevelCode) {
CcdiProjectOverviewEmployeeResult result = new CcdiProjectOverviewEmployeeResult();
result.setRiskLevelCode(riskLevelCode);
return result;
}
}