# Risk Detail Employee Credit Negative 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. > > **Repo note:** 本仓库 `AGENTS.md` 明确禁止开启 subagent,执行本计划时请在当前会话使用 `superpowers:executing-plans`。 **Goal:** 为结果总览“风险明细”新增项目维度的员工负面征信分页查询能力,保证页面可以按当前项目结果总览员工口径展示负面征信列表。 **Architecture:** 后端继续收敛到 `CcdiProjectOverviewController -> ICcdiProjectOverviewService -> CcdiProjectOverviewMapper` 这一条结果总览链路,不复用全局征信维护接口。查询以 `ccdi_project_overview_employee_result` 限定项目员工范围,再与 `ccdi_credit_negative_info` 关联,仅输出存在负面征信记录的员工,并按 `query_date desc, person_id asc` 分页返回。 **Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus `Page`, MyBatis XML, Maven, JUnit 5, Mockito, Swagger/OpenAPI --- ### Task 1: 建立结果总览员工负面征信接口契约 **Files:** - Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiProjectEmployeeCreditNegativeQueryDTO.java` - Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectEmployeeCreditNegativeItemVO.java` - Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectEmployeeCreditNegativePageVO.java` - Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectOverviewService.java` - Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewController.java` - Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/CcdiProjectOverviewServiceStructureTest.java` - Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewControllerContractTest.java` - Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewControllerTest.java` - [ ] **Step 1: 先写失败测试,锁定新 DTO、VO、Service 方法和 Controller 路由** ```java assertNotNull(clazz.getMethod( "getEmployeeCreditNegative", Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO") )); ``` ```java assertEquals("/employee-credit-negative", getMapping.value()[0]); assertEquals(List.of("projectId", "pageNum", "pageSize"), fieldNames); ``` - [ ] **Step 2: 运行结构测试和控制器契约测试,确认当前仓库尚未暴露该能力** Run: ```bash mvn -pl ccdi-project -Dtest=CcdiProjectOverviewServiceStructureTest,CcdiProjectOverviewControllerContractTest,CcdiProjectOverviewControllerTest test ``` Expected: - `CcdiProjectOverviewServiceStructureTest` 报 `NoSuchMethodException` - `CcdiProjectOverviewControllerContractTest` 提示缺少 `/employee-credit-negative` - `CcdiProjectOverviewControllerTest` 还没有对应控制器方法 - [ ] **Step 3: 写最小 DTO / VO / Controller / Service 签名** ```java public class CcdiProjectEmployeeCreditNegativeQueryDTO { private Long projectId; private Integer pageNum; private Integer pageSize; } ``` ```java @GetMapping("/employee-credit-negative") public AjaxResult getEmployeeCreditNegative(CcdiProjectEmployeeCreditNegativeQueryDTO queryDTO) { return AjaxResult.success(overviewService.getEmployeeCreditNegative(queryDTO)); } ``` - [ ] **Step 4: 回跑接口契约测试,确保新接口已被正确暴露** Run: ```bash mvn -pl ccdi-project -Dtest=CcdiProjectOverviewServiceStructureTest,CcdiProjectOverviewControllerContractTest,CcdiProjectOverviewControllerTest test ``` Expected: PASS - [ ] **Step 5: 提交本任务** ```bash git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiProjectEmployeeCreditNegativeQueryDTO.java \ ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectEmployeeCreditNegativeItemVO.java \ ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectEmployeeCreditNegativePageVO.java \ ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectOverviewService.java \ ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewController.java \ ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/CcdiProjectOverviewServiceStructureTest.java \ ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewControllerContractTest.java \ ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewControllerTest.java git commit -m "新增结果总览员工负面征信接口契约" ``` ### Task 2: 落地项目员工负面征信 SQL 查询与分页服务 **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/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java` - Test: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperSqlTest.java` - Create: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceEmployeeCreditNegativeTest.java` - [ ] **Step 1: 先写 SQL 结构测试和服务测试,锁定项目范围、负面字段与排序规则** ```java assertTrue(employeeCreditSql.contains("from ccdi_project_overview_employee_result"), employeeCreditSql); assertTrue(employeeCreditSql.contains("inner join ccdi_credit_negative_info"), employeeCreditSql); assertTrue(employeeCreditSql.contains("result.project_id = #{query.projectId}"), employeeCreditSql); assertTrue(employeeCreditSql.contains("order by neg.query_date desc, neg.person_id asc"), employeeCreditSql); assertFalse(employeeCreditSql.contains("ccdi_debts_info"), employeeCreditSql); ``` ```java verify(overviewMapper).selectEmployeeCreditNegativePage( any(Page.class), argThat(query -> query.getProjectId().equals(40L)) ); ``` - [ ] **Step 2: 运行测试,确认当前查询链路还不存在** Run: ```bash mvn -pl ccdi-project -Dtest=CcdiProjectOverviewMapperSqlTest,CcdiProjectOverviewServiceEmployeeCreditNegativeTest test ``` Expected: - SQL 测试提示缺少 `selectEmployeeCreditNegativePage` - Service 测试编译失败或断言失败,提示未新增 mapper / service 能力 - [ ] **Step 3: 写最小 SQL 与服务实现** ```xml ``` ```java Page page = new Page<>( defaultPageNum(queryDTO.getPageNum()), defaultPageSize(queryDTO.getPageSize()) ); Page resultPage = overviewMapper.selectEmployeeCreditNegativePage(page, queryDTO); ``` - [ ] **Step 4: 回跑 SQL 与服务测试,验证只返回项目内有负面征信的员工** Run: ```bash mvn -pl ccdi-project -Dtest=CcdiProjectOverviewMapperSqlTest,CcdiProjectOverviewServiceEmployeeCreditNegativeTest test ``` Expected: - SQL 测试确认不关联 `ccdi_debts_info` - Service 测试确认分页结果包含 `rows` 和 `total` - 项目不存在时继续抛 `ServiceException("项目不存在")` - [ ] **Step 5: 提交本任务** ```bash 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/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java \ ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiProjectOverviewMapperSqlTest.java \ ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceEmployeeCreditNegativeTest.java git commit -m "实现结果总览员工负面征信分页查询" ``` ### Task 3: 补齐控制器返回与回归验证 **Files:** - Modify: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewControllerTest.java` - Modify: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewControllerContractTest.java` - Modify: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/CcdiProjectOverviewServiceStructureTest.java` - Reference: `docs/superpowers/specs/2026-03-28-risk-detail-employee-credit-negative-design.md` - [ ] **Step 1: 在控制器测试里锁定返回字段和权限沿用** ```java CcdiProjectEmployeeCreditNegativePageVO pageVO = new CcdiProjectEmployeeCreditNegativePageVO(); pageVO.setRows(List.of(item)); pageVO.setTotal(1L); when(overviewService.getEmployeeCreditNegative(queryDTO)).thenReturn(pageVO); AjaxResult result = controller.getEmployeeCreditNegative(queryDTO); assertEquals(pageVO, result.get("data")); ``` - [ ] **Step 2: 回跑控制器相关测试,确认没有破坏既有结果总览契约** Run: ```bash mvn -pl ccdi-project -Dtest=CcdiProjectOverviewControllerTest,CcdiProjectOverviewControllerContractTest,CcdiProjectOverviewServiceStructureTest test ``` Expected: PASS - [ ] **Step 3: 做一次后端最小回归** Run: ```bash mvn -pl ccdi-project -Dtest=CcdiProjectOverviewMapperSqlTest,CcdiProjectOverviewServiceEmployeeCreditNegativeTest,CcdiProjectOverviewControllerTest test ``` Expected: - 新增员工负面征信链路测试全部通过 - 结果总览既有涉疑交易和项目分析控制器测试不回归 - [ ] **Step 4: 记录实施边界** 将以下结论补到提交说明或实施记录中: - 本次只新增项目维度负面征信列表 - 未改动全局征信维护接口 - 未接入负债明细 - [ ] **Step 5: 提交本任务** ```bash git add ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewControllerTest.java \ ccdi-project/src/test/java/com/ruoyi/ccdi/project/controller/CcdiProjectOverviewControllerContractTest.java \ ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/CcdiProjectOverviewServiceStructureTest.java git commit -m "补充结果总览员工负面征信后端回归测试" ```