Files
ccdi/docs/plans/backend/2026-03-20-results-overview-employee-result-table-backend-implementation.md

15 KiB
Raw Blame History

Results Overview Employee Result Table Backend Implementation Plan

For agentic workers: REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 为结果总览页新增按“项目 + 员工”维度沉淀的员工结果表,并将风险仪表盘、风险人员总览、模型预警次数统计、命中模型涉及人员 4 类后端查询切换为只读该结果表。

Architecture:ccdi-project 内新增结果总览员工结果表及其维护 Mapper保留当前“员工本人 + 亲属归并到员工本人”的归并口径,但把重连表归并从页面查询阶段前移到标签写库后的同事务重算阶段。页面查询继续沿用 CcdiProjectOverviewController + Service + Mapper 入口,不新增平行接口,只替换底层查询数据源。

Tech Stack: Java 21, Spring Boot 3, MyBatis XML, MyBatis-Plus, Maven, MySQL, JUnit 5, Mockito


Task 1: 新增结果总览员工结果表与基础映射

Files:

  • Create: sql/migration/2026-03-20-create-project-overview-employee-result-table.sql

  • Create: ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiProjectOverviewEmployeeResult.java

  • Create: ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewEmployeeResultMapper.java

  • Create: ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectOverviewEmployeeResultMapper.xml

  • Test: ccdi-project/src/test/java/com/ruoyi/ccdi/project/domain/entity/CcdiProjectOverviewEmployeeResultEntityTest.java

  • Test: ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewEmployeeResultMapperXmlTest.java

  • Step 1: Write the failing tests

新增实体与 XML 静态测试,锁定以下内容:

  • 结果表名为 ccdi_project_overview_employee_result

  • 唯一键包含 project_idstaff_id_card

  • 字段包含:

    • rule_count
    • model_count
    • hit_count
    • risk_level_code
    • model_codes_csv
    • model_names_json
    • hit_rules_json
    • model_hit_summary_json
  • Mapper XML 至少声明:

    • deleteByProjectId
    • insertBatch
    • selectByProjectId
  • Step 2: Run test to verify it fails

Run:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewEmployeeResultEntityTest,CcdiProjectOverviewEmployeeResultMapperXmlTest

Expected:

  • FAIL

  • 原因是结果表实体、Mapper 与 SQL 脚本尚未创建

  • Step 3: Write minimal implementation

创建结果表结构与基础映射,要求:

  • 表粒度固定为 project_id + staff_id_card
  • JSON 字段使用可承载结构化快照的类型
  • 审计字段与项目现有表风格保持一致
  • Mapper XML 只提供本轮需要的最小 CRUD
    • 按项目删除
    • 批量插入
    • 按项目查询

SQL 脚本如需执行,使用:

bin/mysql_utf8_exec.sh sql/migration/2026-03-20-create-project-overview-employee-result-table.sql
  • Step 4: Run test to verify it passes

Run:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewEmployeeResultEntityTest,CcdiProjectOverviewEmployeeResultMapperXmlTest

Expected:

  • PASS

  • Step 5: Commit

git add sql/migration/2026-03-20-create-project-overview-employee-result-table.sql ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/entity/CcdiProjectOverviewEmployeeResult.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewEmployeeResultMapper.java ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectOverviewEmployeeResultMapper.xml ccdi-project/src/test/java/com/ruoyi/ccdi/project/domain/entity/CcdiProjectOverviewEmployeeResultEntityTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewEmployeeResultMapperXmlTest.java
git commit -m "新增结果总览员工结果表结构"

Task 2: 实现员工归并明细查询与结果表聚合构建

Files:

  • Create: ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectOverviewEmployeeHitRowVO.java

  • Create: ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectOverviewEmployeeRuleSummaryVO.java

  • Create: ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectOverviewEmployeeModelSummaryVO.java

  • Create: ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewEmployeeResultBuilder.java

  • Modify: ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectOverviewEmployeeResultMapper.xml

  • Modify: ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewEmployeeResultMapper.java

  • Test: ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewEmployeeResultBuilderTest.java

  • Step 1: Write the failing test

为结果构建器新增单测,锁定以下聚合口径:

  • 同一员工多条命中按 staff_id_card 合并为一条结果

  • 亲属命中已归并到员工本人后再参与聚合

  • ruleCountrule_code 去重

  • modelCountmodel_code 去重

  • hitCount 为原始命中次数累计

  • riskLevelCode 沿用当前分级:

    • >= 5HIGH
    • 2-4MEDIUM
    • 其余为 LOW
  • model_hit_summary_json 中每个模型的 warningCount 为原始标签命中次数

  • Step 2: Run test to verify it fails

Run:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewEmployeeResultBuilderTest

Expected:

  • FAIL

  • 原因是构建器与原始命中明细类型尚未实现

  • Step 3: Write minimal implementation

实现以下内容:

  • 在结果表 Mapper 中新增“按项目查询员工归并命中明细”的内部查询
  • 该查询可以复用当前归并口径,但只供重算链路使用,不供页面查询直接调用
  • CcdiProjectOverviewEmployeeResultBuilder 中完成 Java 聚合,输出可批量入表的实体列表
  • 生成:
    • risk_point
    • model_codes_csv
    • model_names_json
    • hit_rules_json
    • model_hit_summary_json

不要在这一阶段改造 Controller 或页面查询 SQL。

  • Step 4: Run test to verify it passes

Run:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewEmployeeResultBuilderTest

Expected:

  • PASS

  • Step 5: Commit

git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectOverviewEmployeeHitRowVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectOverviewEmployeeRuleSummaryVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectOverviewEmployeeModelSummaryVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewEmployeeResultBuilder.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewEmployeeResultMapper.java ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectOverviewEmployeeResultMapper.xml ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewEmployeeResultBuilderTest.java
git commit -m "实现结果总览员工结果聚合构建"

Task 3: 接入标签写库后的同事务重算链路

Files:

  • Modify: ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectOverviewService.java

  • Modify: ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java

  • Modify: ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceImpl.java

  • Modify: ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/CcdiProjectOverviewServiceStructureTest.java

  • Modify: ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImplTest.java

  • Modify: ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceRiskCountRefreshTest.java

  • Step 1: Write the failing tests

调整服务结构与事务链路测试,锁定以下行为:

  • ICcdiProjectOverviewService 暴露“重算结果总览员工结果”的服务方法

  • 标签重算成功后,先写标签结果,再重算员工结果表,再同步项目风险人数

  • 如果员工结果表重算失败,标签任务整体失败并回滚

  • Step 2: Run test to verify it fails

Run:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewServiceStructureTest,CcdiProjectOverviewServiceImplTest,CcdiBankTagServiceRiskCountRefreshTest

Expected:

  • FAIL

  • 原因是当前只刷新项目风险人数,尚未维护结果总览员工结果表

  • Step 3: Write minimal implementation

实现以下最小改动:

  • CcdiProjectOverviewServiceImpl 中新增按项目重算员工结果表的方法
  • 方法内部顺序固定为:
    • 校验项目存在
    • 删除当前项目历史结果
    • 查询项目全量员工归并命中明细
    • 通过构建器聚合
    • 批量写入结果表
    • 基于结果表同步项目高/中/低风险人数
  • CcdiBankTagServiceImpl 中把成功链路切换为调用新方法

不要在这一步修改结果总览 Controller 对外接口。

  • Step 4: Run test to verify it passes

Run:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewServiceStructureTest,CcdiProjectOverviewServiceImplTest,CcdiBankTagServiceRiskCountRefreshTest

Expected:

  • PASS

  • Step 5: Commit

git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectOverviewService.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceImpl.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/CcdiProjectOverviewServiceStructureTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImplTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceRiskCountRefreshTest.java
git commit -m "接入结果总览员工结果同步重算"

Task 4: 将结果总览 4 类查询切换为只读结果表

Files:

  • Modify: ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapper.java

  • Modify: ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml

  • Modify: ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperSqlTest.java

  • Modify: ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperRiskModelCardsTest.java

  • Modify: ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperRiskModelPeopleTest.java

  • Modify: ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImplTest.java

  • Step 1: Write the failing tests

补充或调整 Mapper/Service 测试,锁定以下要求:

  • 风险仪表盘查询不再依赖 resolvedEmployeeRiskBaseSql

  • 风险人员总览从结果表返回 riskLevelmodelCountriskPoint

  • 模型卡片 warningCount 取自结果表中的模型汇总快照

  • 模型人员列表继续支持:

    • ANY
    • ALL
    • keyword
    • deptId
    • pageNum
    • pageSize
  • 4 类页面查询都改为读 ccdi_project_overview_employee_result

  • Step 2: Run test to verify it fails

Run:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewMapperSqlTest,CcdiProjectOverviewMapperRiskModelCardsTest,CcdiProjectOverviewMapperRiskModelPeopleTest,CcdiProjectOverviewServiceImplTest

Expected:

  • FAIL

  • 原因是当前结果总览查询仍直接读取重连表聚合 SQL

  • Step 3: Write minimal implementation

CcdiProjectOverviewMapper.xml 中:

  • 风险仪表盘按结果表风险等级统计
  • 风险人员总览改为单表排序查询
  • 模型卡片基于 model_hit_summary_json 或等价结构展开聚合
  • 模型人员分页基于结果表完成 ANY / ALL / keyword / deptId 过滤,并从快照字段组装 modelNameshitTagList

CcdiProjectOverviewServiceImpl 中只做最小适配,不新增新接口,不改前端响应结构。

不要改动:

  • 风险明细相关逻辑

  • 已移出页面范围之外的 TOP10 逻辑

  • Step 4: Run test to verify it passes

Run:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewMapperSqlTest,CcdiProjectOverviewMapperRiskModelCardsTest,CcdiProjectOverviewMapperRiskModelPeopleTest,CcdiProjectOverviewServiceImplTest

Expected:

  • PASS

  • Step 5: Commit

git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapper.java ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperSqlTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperRiskModelCardsTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperRiskModelPeopleTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImplTest.java
git commit -m "切换结果总览查询到员工结果表"

Task 5: 补充后端实施与验证文档

Files:

  • Create: docs/reports/implementation/2026-03-20-results-overview-employee-result-table-backend-implementation.md

  • Create: docs/tests/records/2026-03-20-results-overview-employee-result-table-backend-verification.md

  • Verify: docs/design/2026-03-20-results-overview-employee-result-table-design.md

  • Step 1: Write implementation record

记录以下内容:

  • 新增结果总览员工结果表

  • 命中结果写库后同事务重算

  • 结果总览 4 类查询改为只读结果表

  • 保持模型卡片 warningCount 为原始标签命中次数

  • Step 2: Write verification record

记录执行过的命令、日期、结果和结论,至少包含:

mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewEmployeeResultEntityTest,CcdiProjectOverviewEmployeeResultMapperXmlTest
mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewEmployeeResultBuilderTest
mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewServiceStructureTest,CcdiProjectOverviewServiceImplTest,CcdiBankTagServiceRiskCountRefreshTest
mvn test -pl ccdi-project -Dtest=CcdiProjectOverviewMapperSqlTest,CcdiProjectOverviewMapperRiskModelCardsTest,CcdiProjectOverviewMapperRiskModelPeopleTest,CcdiProjectOverviewServiceImplTest

如执行 SQL 脚本,记录:

bin/mysql_utf8_exec.sh sql/migration/2026-03-20-create-project-overview-employee-result-table.sql
  • Step 3: Commit
git add docs/reports/implementation/2026-03-20-results-overview-employee-result-table-backend-implementation.md docs/tests/records/2026-03-20-results-overview-employee-result-table-backend-verification.md
git commit -m "补充结果总览员工结果表后端实施记录"