修复风险总览无风险人员负数问题

This commit is contained in:
wkc
2026-05-26 16:55:53 +08:00
parent 1b45296df3
commit a39594faf8
8 changed files with 167 additions and 10 deletions

View File

@@ -36,9 +36,10 @@ public interface CcdiProjectMapper extends BaseMapper<CcdiProject> {
List<CcdiProjectHistoryListItemVO> selectHistoryProjects(@Param("queryDTO") CcdiProjectQueryDTO queryDTO);
/**
* 更新项目风险人数
* 更新项目总人数与风险人数
*
* @param projectId 项目ID
* @param targetCount 总人数
* @param highRiskCount 高风险人数
* @param mediumRiskCount 中风险人数
* @param lowRiskCount 低风险人数
@@ -46,6 +47,7 @@ public interface CcdiProjectMapper extends BaseMapper<CcdiProject> {
* @return 更新行数
*/
int updateRiskCountsByProjectId(@Param("projectId") Long projectId,
@Param("targetCount") Integer targetCount,
@Param("highRiskCount") Integer highRiskCount,
@Param("mediumRiskCount") Integer mediumRiskCount,
@Param("lowRiskCount") Integer lowRiskCount,

View File

@@ -41,6 +41,7 @@ import com.ruoyi.ccdi.project.domain.vo.CcdiProjectSuspiciousTransactionPageVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectTopRiskPeopleItemVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectTopRiskPeopleVO;
import com.ruoyi.ccdi.project.mapper.CcdiModelParamMapper;
import com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper;
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
import com.ruoyi.ccdi.project.mapper.CcdiBankTagResultMapper;
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewEmployeeResultMapper;
@@ -74,6 +75,9 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
@Resource
private CcdiProjectMapper projectMapper;
@Resource
private CcdiBankStatementMapper bankStatementMapper;
@Resource
private CcdiModelParamMapper modelParamMapper;
@@ -371,6 +375,7 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
projectMapper.updateRiskCountsByProjectId(
projectId,
countProjectScopeStaff(projectId),
countRiskLevel(results, "HIGH"),
countRiskLevel(results, "MEDIUM"),
countRiskLevel(results, "LOW"),
@@ -385,6 +390,7 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
Map<String, Object> summary = overviewMapper.selectRiskCountSummaryByProjectId(projectId);
projectMapper.updateRiskCountsByProjectId(
projectId,
countProjectScopeStaff(projectId),
readCount(summary, "highRiskCount"),
readCount(summary, "mediumRiskCount"),
readCount(summary, "lowRiskCount"),
@@ -392,6 +398,10 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
);
}
private int countProjectScopeStaff(Long projectId) {
return defaultZero(bankStatementMapper.countMatchedStaffCountByProjectId(projectId));
}
private CcdiProjectRiskPeopleOverviewItemVO buildRiskPeopleItem(Long projectId, CcdiProjectEmployeeRiskAggregateVO aggregate) {
CcdiProjectRiskPeopleOverviewItemVO item = new CcdiProjectRiskPeopleOverviewItemVO();
item.setName(aggregate.getStaffName());

View File

@@ -117,12 +117,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<select id="countMatchedStaffCountByProjectId" resultType="java.lang.Integer">
select count(distinct trim(bs.cret_no))
from ccdi_bank_statement bs
inner join ccdi_base_staff staff on staff.id_card = bs.cret_no
where bs.project_id = #{projectId}
and bs.cret_no is not null
and trim(bs.cret_no) != ''
select count(distinct scope_staff.id_card)
from (
select staff.id_card
from ccdi_bank_statement bs
inner join ccdi_base_staff staff on staff.id_card = trim(bs.cret_no)
where bs.project_id = #{projectId}
and bs.cret_no is not null
and trim(bs.cret_no) != ''
union
select family_staff.id_card
from ccdi_bank_statement bs
inner join ccdi_staff_fmy_relation relation
on relation.relation_cert_no = trim(bs.cret_no)
and relation.status = 1
inner join ccdi_base_staff family_staff
on family_staff.id_card = relation.person_id
where bs.project_id = #{projectId}
and bs.cret_no is not null
and trim(bs.cret_no) != ''
union
select account_staff.id_card
from ccdi_bank_statement bs
inner join ccdi_account_info account
on trim(account.account_no) = trim(bs.LE_ACCOUNT_NO)
and account.owner_type = 'EMPLOYEE'
inner join ccdi_base_staff account_staff
on account_staff.id_card = account.owner_id
where bs.project_id = #{projectId}
and bs.LE_ACCOUNT_NO is not null
and trim(bs.LE_ACCOUNT_NO) != ''
) scope_staff
</select>
<sql id="parsedTrxDateExpr">

View File

@@ -70,7 +70,8 @@
<update id="updateRiskCountsByProjectId">
update ccdi_project
set high_risk_count = #{highRiskCount},
set target_count = #{targetCount},
high_risk_count = #{highRiskCount},
medium_risk_count = #{mediumRiskCount},
low_risk_count = #{lowRiskCount},
update_by = #{updateBy},

View File

@@ -220,6 +220,22 @@ class CcdiBankStatementMapperXmlTest {
}
}
@Test
void targetCount_shouldUseResolvedProjectEmployeeScope() throws Exception {
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(RESOURCE)) {
String xml = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
String selectSql = extractSelect(xml, "countMatchedStaffCountByProjectId");
assertTrue(selectSql.contains("select count(distinct scope_staff.id_card)"), selectSql);
assertTrue(selectSql.contains("inner join ccdi_base_staff staff on staff.id_card = trim(bs.cret_no)"), selectSql);
assertTrue(selectSql.contains("inner join ccdi_staff_fmy_relation relation"), selectSql);
assertTrue(selectSql.contains("family_staff.id_card = relation.person_id"), selectSql);
assertTrue(selectSql.contains("inner join ccdi_account_info account"), selectSql);
assertTrue(selectSql.contains("account.owner_type = 'EMPLOYEE'"), selectSql);
assertTrue(selectSql.contains("account_staff.id_card = account.owner_id"), selectSql);
}
}
private MappedStatement loadMappedStatement(String statementId) throws Exception {
Configuration configuration = new Configuration();
configuration.setEnvironment(new Environment("test", new JdbcTransactionFactory(), new NoOpDataSource()));
@@ -242,6 +258,15 @@ class CcdiBankStatementMapperXmlTest {
return boundSql.getSql().replaceAll("\\s+", " ").trim();
}
private String extractSelect(String xml, String selectId) {
String start = "<select id=\"" + selectId + "\"";
int startIndex = xml.indexOf(start);
assertTrue(startIndex >= 0, "missing select: " + selectId);
int endIndex = xml.indexOf("</select>", startIndex);
assertTrue(endIndex >= 0, "missing closing select tag: " + selectId);
return xml.substring(startIndex, endIndex);
}
private void registerTypeAliases(TypeAliasRegistry typeAliasRegistry) {
typeAliasRegistry.registerAlias("map", Map.class);
}

View File

@@ -29,6 +29,7 @@ import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelPeopleVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskPeopleOverviewVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectSuspiciousTransactionItemVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectTopRiskPeopleVO;
import com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper;
import com.ruoyi.ccdi.project.mapper.CcdiModelParamMapper;
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
import com.ruoyi.ccdi.project.mapper.CcdiBankTagResultMapper;
@@ -69,6 +70,9 @@ class CcdiProjectOverviewServiceImplTest {
@Mock
private CcdiProjectMapper projectMapper;
@Mock
private CcdiBankStatementMapper bankStatementMapper;
@Mock
private CcdiModelParamMapper modelParamMapper;
@@ -427,10 +431,11 @@ class CcdiProjectOverviewServiceImplTest {
summary.put("mediumRiskCount", new BigDecimal("1"));
summary.put("lowRiskCount", new BigDecimal("3"));
when(overviewMapper.selectRiskCountSummaryByProjectId(43L)).thenReturn(summary);
when(bankStatementMapper.countMatchedStaffCountByProjectId(43L)).thenReturn(6);
service.refreshProjectRiskCounts(43L, "tester");
verify(projectMapper).updateRiskCountsByProjectId(eq(43L), eq(2), eq(1), eq(3), eq("tester"));
verify(projectMapper).updateRiskCountsByProjectId(eq(43L), eq(6), eq(2), eq(1), eq(3), eq("tester"));
}
@Test
@@ -490,6 +495,7 @@ class CcdiProjectOverviewServiceImplTest {
);
when(overviewEmployeeResultMapper.selectEmployeeHitRowsByProjectId(43L)).thenReturn(hitRows);
when(overviewEmployeeResultBuilder.build(43L, hitRows, "tester")).thenReturn(results);
when(bankStatementMapper.countMatchedStaffCountByProjectId(43L)).thenReturn(3);
service.refreshOverviewEmployeeResults(43L, "tester");
@@ -503,7 +509,7 @@ class CcdiProjectOverviewServiceImplTest {
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");
inOrder.verify(projectMapper).updateRiskCountsByProjectId(43L, 3, 1, 1, 1, "tester");
}
@Test