# 风险总览无风险人员负数修复记录 ## 问题现象 - 生产项目结果总览出现“无风险人员”为负数。 - 页面展示中“高风险 + 中风险 + 低风险”人数大于“总人数”。 ## 根因 - `ccdi_project.target_count` 原口径只统计 `ccdi_bank_statement.cret_no` 直接匹配到员工主数据的去重人数。 - 风险人员结果表 `ccdi_project_overview_employee_result` 的生成口径会把关系人流水、对象规则命中、账户归属等结果归并回员工。 - 当项目存在“关系人流水归属员工”或“项目流水账号归属员工”时,风险人数的员工范围大于总人数范围,导致 `target_count - high - medium - low` 出现负数。 ## 修改内容 - 调整 `CcdiBankStatementMapper.countMatchedStaffCountByProjectId`: - 直接员工:流水 `cret_no` 匹配员工身份证。 - 关系人归属员工:流水 `cret_no` 匹配员工关系人证件号后归属到员工。 - 账号归属员工:项目流水账号匹配员工账户信息后归属到员工。 - 调整 `CcdiProjectOverviewServiceImpl`: - 标签重算刷新结果总览员工结果后,同步刷新项目总人数和风险人数。 - 手动刷新项目风险人数时,同步刷新项目总人数。 - 调整 `CcdiProjectMapper.updateRiskCountsByProjectId`: - 更新风险人数时同时写回 `target_count`,保证总人数与风险人数使用同一项目员工范围口径。 - 新增生产回填脚本: - `sql/migration/2026-05-22-fix-project-target-count-employee-scope.sql` - 用新口径回填既有项目的 `target_count`。 ## 影响范围 - 后端结果总览统计。 - 项目列表中的目标人数。 - 生产既有项目需要执行新增 SQL 回填脚本,后续上传、历史导入、标签重算会自动按新口径刷新。 ## 验证 - 已补充 `CcdiBankStatementMapperXmlTest.targetCount_shouldUseResolvedProjectEmployeeScope`,约束总人数 SQL 必须包含直接员工、关系人归属员工、账号归属员工三类范围。 - 已更新 `CcdiProjectOverviewServiceImplTest`,约束刷新风险人数时同步写回总人数。