修正风险仪表盘总人数员工匹配口径
This commit is contained in:
@@ -38,4 +38,6 @@ public interface CcdiBankStatementMapper extends BaseMapper<CcdiBankStatement> {
|
|||||||
CcdiBankStatementDetailVO selectStatementDetailById(@Param("bankStatementId") Long bankStatementId);
|
CcdiBankStatementDetailVO selectStatementDetailById(@Param("bankStatementId") Long bankStatementId);
|
||||||
|
|
||||||
CcdiBankStatementFilterOptionsVO selectFilterOptions(@Param("projectId") Long projectId);
|
CcdiBankStatementFilterOptionsVO selectFilterOptions(@Param("projectId") Long projectId);
|
||||||
|
|
||||||
|
Integer countMatchedStaffCountByProjectId(@Param("projectId") Long projectId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.ruoyi.ccdi.project.service.impl;
|
|||||||
|
|
||||||
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||||
import com.ruoyi.ccdi.project.domain.enums.TriggerType;
|
import com.ruoyi.ccdi.project.domain.enums.TriggerType;
|
||||||
@@ -954,13 +953,7 @@ public class CcdiFileUploadServiceImpl implements ICcdiFileUploadService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryWrapper<CcdiBankStatement> queryWrapper = new QueryWrapper<>();
|
int targetCount = bankStatementMapper.countMatchedStaffCountByProjectId(projectId);
|
||||||
queryWrapper.select("DISTINCT TRIM(cret_no)");
|
|
||||||
queryWrapper.eq("project_id", projectId);
|
|
||||||
queryWrapper.isNotNull("cret_no");
|
|
||||||
queryWrapper.apply("TRIM(cret_no) <> ''");
|
|
||||||
|
|
||||||
int targetCount = bankStatementMapper.selectObjs(queryWrapper).size();
|
|
||||||
project.setTargetCount(targetCount);
|
project.setTargetCount(targetCount);
|
||||||
projectMapper.updateById(project);
|
projectMapper.updateById(project);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
select="selectOurAccountOptions"/>
|
select="selectOurAccountOptions"/>
|
||||||
</resultMap>
|
</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>
|
||||||
|
|
||||||
<sql id="parsedTrxDateExpr">
|
<sql id="parsedTrxDateExpr">
|
||||||
CASE
|
CASE
|
||||||
WHEN bs.TRX_DATE IS NULL OR TRIM(bs.TRX_DATE) = '' THEN NULL
|
WHEN bs.TRX_DATE IS NULL OR TRIM(bs.TRX_DATE) = '' THEN NULL
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ class CcdiFileUploadServiceImplTest {
|
|||||||
CcdiProject project = new CcdiProject();
|
CcdiProject project = new CcdiProject();
|
||||||
project.setProjectId(PROJECT_ID);
|
project.setProjectId(PROJECT_ID);
|
||||||
when(projectMapper.selectById(PROJECT_ID)).thenReturn(project);
|
when(projectMapper.selectById(PROJECT_ID)).thenReturn(project);
|
||||||
when(bankStatementMapper.selectObjs(any())).thenReturn(List.of("110101199001018888"));
|
when(bankStatementMapper.countMatchedStaffCountByProjectId(PROJECT_ID)).thenReturn(1);
|
||||||
|
|
||||||
when(lsfxClient.uploadFile(eq(LSFX_PROJECT_ID), any())).thenReturn(buildUploadResponse());
|
when(lsfxClient.uploadFile(eq(LSFX_PROJECT_ID), any())).thenReturn(buildUploadResponse());
|
||||||
when(lsfxClient.checkParseStatus(LSFX_PROJECT_ID, String.valueOf(LOG_ID)))
|
when(lsfxClient.checkParseStatus(LSFX_PROJECT_ID, String.valueOf(LOG_ID)))
|
||||||
@@ -375,7 +375,7 @@ class CcdiFileUploadServiceImplTest {
|
|||||||
when(recordMapper.selectById(RECORD_ID)).thenReturn(record);
|
when(recordMapper.selectById(RECORD_ID)).thenReturn(record);
|
||||||
when(lsfxClient.deleteFiles(any())).thenReturn(buildDeleteFilesResponse());
|
when(lsfxClient.deleteFiles(any())).thenReturn(buildDeleteFilesResponse());
|
||||||
when(projectMapper.selectById(PROJECT_ID)).thenReturn(project);
|
when(projectMapper.selectById(PROJECT_ID)).thenReturn(project);
|
||||||
when(bankStatementMapper.selectObjs(any())).thenReturn(List.of("110101199001018888", "110101199001019999"));
|
when(bankStatementMapper.countMatchedStaffCountByProjectId(PROJECT_ID)).thenReturn(2);
|
||||||
when(recordMapper.updateById(any(CcdiFileUploadRecord.class))).thenReturn(1);
|
when(recordMapper.updateById(any(CcdiFileUploadRecord.class))).thenReturn(1);
|
||||||
|
|
||||||
String result = service.deleteFileUploadRecord(RECORD_ID, 9527L);
|
String result = service.deleteFileUploadRecord(RECORD_ID, 9527L);
|
||||||
@@ -562,14 +562,11 @@ class CcdiFileUploadServiceImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void refreshProjectTargetCount_shouldUpdateProjectWithDistinctIdCardCount() {
|
void refreshProjectTargetCount_shouldUseMatchedStaffCountOnly() {
|
||||||
CcdiProject project = new CcdiProject();
|
CcdiProject project = new CcdiProject();
|
||||||
project.setProjectId(PROJECT_ID);
|
project.setProjectId(PROJECT_ID);
|
||||||
when(projectMapper.selectById(PROJECT_ID)).thenReturn(project);
|
when(projectMapper.selectById(PROJECT_ID)).thenReturn(project);
|
||||||
when(bankStatementMapper.selectObjs(any())).thenReturn(List.of(
|
when(bankStatementMapper.countMatchedStaffCountByProjectId(PROJECT_ID)).thenReturn(2);
|
||||||
"110101199001018888",
|
|
||||||
"110101199001019999"
|
|
||||||
));
|
|
||||||
|
|
||||||
ReflectionTestUtils.invokeMethod(service, "refreshProjectTargetCount", PROJECT_ID);
|
ReflectionTestUtils.invokeMethod(service, "refreshProjectTargetCount", PROJECT_ID);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# 风险仪表盘总人数员工匹配口径修正记录
|
||||||
|
|
||||||
|
**日期**: 2026-03-19
|
||||||
|
**范围**: 后端
|
||||||
|
|
||||||
|
## 口径修正
|
||||||
|
|
||||||
|
- 原修复将 `target_count` 按项目流水中全部去重身份证号回写
|
||||||
|
- 用户确认后的正确口径为:
|
||||||
|
- 统计 `ccdi_bank_statement.cret_no`
|
||||||
|
- 仅保留能匹配 `ccdi_base_staff.id_card` 的记录
|
||||||
|
- 再按去重身份证号数量回写 `ccdi_project.target_count`
|
||||||
|
|
||||||
|
## 本次修改
|
||||||
|
|
||||||
|
1. 在 `CcdiBankStatementMapper` 新增“按项目统计匹配员工主数据后的去重身份证号人数”查询
|
||||||
|
2. 在 `CcdiFileUploadServiceImpl.refreshProjectTargetCount` 中改为调用该查询
|
||||||
|
3. 保持导入成功、删除成功后的目标人数刷新时机不变,仅修正统计口径
|
||||||
|
4. 新增增量脚本 `sql/migration/2026-03-19-fix-project-target-count-match-staff.sql`,用于修正已错误回填的项目人数
|
||||||
|
5. 调整单元测试,锁定“只统计能匹配员工主数据的人数”这一行为
|
||||||
|
|
||||||
|
## 验证
|
||||||
|
|
||||||
|
- 执行:`mvn -pl ccdi-project -Dtest=CcdiFileUploadServiceImplTest test`
|
||||||
|
- 结果:通过
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
-- 修正项目目标人数口径
|
||||||
|
-- 正确口径:银行流水中的身份证号在员工主数据中存在时,按去重身份证号数量回写 ccdi_project.target_count
|
||||||
|
|
||||||
|
UPDATE ccdi_project project
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT
|
||||||
|
bs.project_id,
|
||||||
|
COUNT(DISTINCT TRIM(bs.cret_no)) AS target_count
|
||||||
|
FROM ccdi_bank_statement bs
|
||||||
|
INNER JOIN ccdi_base_staff staff
|
||||||
|
ON staff.id_card = bs.cret_no
|
||||||
|
WHERE bs.cret_no IS NOT NULL
|
||||||
|
AND TRIM(bs.cret_no) <> ''
|
||||||
|
GROUP BY bs.project_id
|
||||||
|
) stats ON stats.project_id = project.project_id
|
||||||
|
SET project.target_count = COALESCE(stats.target_count, 0),
|
||||||
|
project.update_by = 'system',
|
||||||
|
project.update_time = NOW()
|
||||||
|
WHERE project.del_flag = '0';
|
||||||
Reference in New Issue
Block a user