254 lines
10 KiB
Markdown
254 lines
10 KiB
Markdown
# 员工资产导入与亲属资产导入拆分后端实施计划
|
||
|
||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||
|
||
**Goal:** 将员工资产导入与亲属资产导入拆成两套独立后端接口与服务,确保员工页仅导入本人资产、亲属页仅导入亲属资产。
|
||
|
||
**Architecture:** 保留现有亲属资产导入控制器与服务作为“亲属专用导入链路”,新增一套员工资产专用导入控制器、Excel 模型、失败记录 VO 与异步导入服务。两套链路分别使用不同权限、模板和归属匹配规则,不再共享“本人/亲属兜底识别”逻辑。
|
||
|
||
**Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus, Redis, EasyExcel, JUnit 5, Mockito
|
||
|
||
---
|
||
|
||
### Task 1: 固化拆分后的导入规则测试
|
||
|
||
**Files:**
|
||
- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiAssetInfoImportServiceImplTest.java`
|
||
- Create: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiBaseStaffAssetImportServiceImplTest.java`
|
||
- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiAssetInfoControllerTest.java`
|
||
- Create: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiBaseStaffAssetImportControllerTest.java`
|
||
|
||
**Step 1: 写亲属资产导入失败测试**
|
||
|
||
- 为 `CcdiAssetInfoImportServiceImplTest` 增加用例:
|
||
- 员工本人身份证号导入时失败
|
||
- 失败文案为亲属资产专用文案
|
||
- 为 `CcdiAssetInfoControllerTest` 校验模板标题为“亲属资产信息”
|
||
|
||
**Step 2: 运行测试确认当前失败**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
mvn test -pl ccdi-info-collection -am "-Dtest=CcdiAssetInfoImportServiceImplTest,CcdiAssetInfoControllerTest" "-Dsurefire.failIfNoSpecifiedTests=false"
|
||
```
|
||
|
||
Expected:
|
||
|
||
- 新增断言失败
|
||
- 失败原因是当前实现仍允许员工本人资产命中
|
||
|
||
**Step 3: 写员工资产导入测试**
|
||
|
||
- 新增 `CcdiBaseStaffAssetImportServiceImplTest`
|
||
- 覆盖以下场景:
|
||
- 员工本人身份证号导入成功
|
||
- 亲属证件号导入失败
|
||
- Redis key 使用员工资产独立前缀
|
||
- 新增 `CcdiBaseStaffAssetImportControllerTest`
|
||
- 覆盖模板标题、任务创建、状态与失败记录查询
|
||
|
||
**Step 4: 再次运行测试确认失败点准确**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
mvn test -pl ccdi-info-collection -am "-Dtest=CcdiBaseStaffAssetImportServiceImplTest,CcdiBaseStaffAssetImportControllerTest" "-Dsurefire.failIfNoSpecifiedTests=false"
|
||
```
|
||
|
||
Expected:
|
||
|
||
- 因类与实现尚不存在而失败
|
||
|
||
**Step 5: 提交测试脚手架**
|
||
|
||
```bash
|
||
git add ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiAssetInfoImportServiceImplTest.java ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiBaseStaffAssetImportServiceImplTest.java ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiAssetInfoControllerTest.java ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiBaseStaffAssetImportControllerTest.java
|
||
git commit -m "补充资产导入拆分后端失败测试"
|
||
```
|
||
|
||
### Task 2: 收敛亲属资产导入为亲属专用链路
|
||
|
||
**Files:**
|
||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiAssetInfoController.java`
|
||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiAssetInfoImportServiceImpl.java`
|
||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiAssetInfoExcel.java`
|
||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/AssetImportFailureVO.java`
|
||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiAssetInfoMapper.java`
|
||
- Modify: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAssetInfoMapper.xml`
|
||
|
||
**Step 1: 最小实现修改**
|
||
|
||
- 将 `CcdiAssetInfoImportServiceImpl` 的归属匹配改为只调用 `selectOwnerCandidatesByRelationCertNos`
|
||
- 删除员工本人兜底逻辑
|
||
- 恢复亲属资产专用错误文案
|
||
- 将 Excel 首列表头改为“亲属证件号*”
|
||
- 将 controller 标题、swagger 文案、日志标题改回亲属资产专用表述
|
||
- 权限仅保留 `ccdi:staffFmyRelation:import`
|
||
|
||
**Step 2: 运行亲属资产相关测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
mvn test -pl ccdi-info-collection -am "-Dtest=CcdiAssetInfoImportServiceImplTest,CcdiAssetInfoControllerTest" "-Dsurefire.failIfNoSpecifiedTests=false"
|
||
```
|
||
|
||
Expected:
|
||
|
||
- 亲属资产测试全部通过
|
||
|
||
**Step 3: 检查无多余员工导入逻辑残留**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
git grep -n "selectOwnerCandidatesByPersonIds|hasAnyPermi('ccdi:employee:import" -- "ccdi-info-collection/src/main/java/**/*.java" "ccdi-info-collection/src/main/resources/**/*.xml"
|
||
```
|
||
|
||
Expected:
|
||
|
||
- `CcdiAssetInfo*` 相关文件不再包含员工资产导入特有逻辑
|
||
|
||
**Step 4: 提交**
|
||
|
||
```bash
|
||
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiAssetInfoController.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiAssetInfoImportServiceImpl.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiAssetInfoExcel.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/AssetImportFailureVO.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiAssetInfoMapper.java ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAssetInfoMapper.xml
|
||
git commit -m "收敛亲属资产导入为亲属专用逻辑"
|
||
```
|
||
|
||
### Task 3: 新增员工资产导入后端接口与模型
|
||
|
||
**Files:**
|
||
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiBaseStaffAssetImportController.java`
|
||
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiBaseStaffAssetImportService.java`
|
||
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffAssetImportServiceImpl.java`
|
||
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffAssetInfoExcel.java`
|
||
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/BaseStaffAssetImportFailureVO.java`
|
||
|
||
**Step 1: 写最小接口定义**
|
||
|
||
- 定义员工资产导入 service 接口:
|
||
- `importAssetInfo`
|
||
- `importAssetInfoAsync`
|
||
- `getImportStatus`
|
||
- `getImportFailures`
|
||
|
||
**Step 2: 写 controller 最小实现**
|
||
|
||
- 提供以下接口:
|
||
- `POST /ccdi/baseStaff/asset/importTemplate`
|
||
- `POST /ccdi/baseStaff/asset/importData`
|
||
- `GET /ccdi/baseStaff/asset/importStatus/{taskId}`
|
||
- `GET /ccdi/baseStaff/asset/importFailures/{taskId}`
|
||
- 权限使用 `ccdi:employee:import`
|
||
|
||
**Step 3: 写 Excel 与失败记录模型**
|
||
|
||
- `CcdiBaseStaffAssetInfoExcel` 首列使用“员工身份证号*”
|
||
- `BaseStaffAssetImportFailureVO` 字段与员工资产模板保持一致
|
||
|
||
**Step 4: 运行员工资产 controller 测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
mvn test -pl ccdi-info-collection -am "-Dtest=CcdiBaseStaffAssetImportControllerTest" "-Dsurefire.failIfNoSpecifiedTests=false"
|
||
```
|
||
|
||
Expected:
|
||
|
||
- controller 测试通过
|
||
|
||
**Step 5: 提交**
|
||
|
||
```bash
|
||
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiBaseStaffAssetImportController.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiBaseStaffAssetImportService.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffAssetImportServiceImpl.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffAssetInfoExcel.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/BaseStaffAssetImportFailureVO.java
|
||
git commit -m "新增员工资产导入后端接口"
|
||
```
|
||
|
||
### Task 4: 实现员工资产归属匹配与异步导入
|
||
|
||
**Files:**
|
||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffAssetImportServiceImpl.java`
|
||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiAssetInfoMapper.java`
|
||
- Modify: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAssetInfoMapper.xml`
|
||
|
||
**Step 1: 写最小匹配实现**
|
||
|
||
- 在 mapper 中新增 `selectOwnerCandidatesByBaseStaffIdCards`
|
||
- SQL 只查询 `ccdi_base_staff.id_card`
|
||
- service 只按员工身份证号匹配
|
||
- 不查亲属关系表
|
||
|
||
**Step 2: 写导入成功逻辑**
|
||
|
||
- 复制 Excel 到 `CcdiAssetInfo`
|
||
- 强制 `familyId = personId = 员工身份证号`
|
||
- 使用独立 Redis 前缀,例如 `import:baseStaffAsset:`
|
||
|
||
**Step 3: 写失败逻辑**
|
||
|
||
- 未命中员工表时报错
|
||
- 失败文案使用员工资产专用文案
|
||
|
||
**Step 4: 运行员工资产 service 测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
mvn test -pl ccdi-info-collection -am "-Dtest=CcdiBaseStaffAssetImportServiceImplTest" "-Dsurefire.failIfNoSpecifiedTests=false"
|
||
```
|
||
|
||
Expected:
|
||
|
||
- 员工资产 service 测试通过
|
||
|
||
**Step 5: 提交**
|
||
|
||
```bash
|
||
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffAssetImportServiceImpl.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiAssetInfoMapper.java ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAssetInfoMapper.xml
|
||
git commit -m "实现员工资产导入归属匹配"
|
||
```
|
||
|
||
### Task 5: 执行回归验证
|
||
|
||
**Files:**
|
||
- Modify: `docs/plans/2026-03-13-employee-family-asset-import-split-design.md`
|
||
|
||
**Step 1: 运行后端定向测试**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
mvn test -pl ccdi-info-collection -am "-Dtest=CcdiAssetInfoImportServiceImplTest,CcdiAssetInfoControllerTest,CcdiBaseStaffAssetImportServiceImplTest,CcdiBaseStaffAssetImportControllerTest" "-Dsurefire.failIfNoSpecifiedTests=false"
|
||
```
|
||
|
||
Expected:
|
||
|
||
- 相关测试全部通过
|
||
|
||
**Step 2: 做源码断言检查**
|
||
|
||
Run:
|
||
|
||
```bash
|
||
git grep -n "/ccdi/baseStaff/asset|/ccdi/assetInfo" -- "ccdi-info-collection/src/main/java/**/*.java"
|
||
```
|
||
|
||
Expected:
|
||
|
||
- 员工与亲属两套接口都存在
|
||
- 路由职责清晰
|
||
|
||
**Step 3: 更新设计文档的实现状态说明**
|
||
|
||
- 在设计文档末尾补充“已完成实现验证”的简短说明
|
||
|
||
**Step 4: 提交**
|
||
|
||
```bash
|
||
git add docs/plans/2026-03-13-employee-family-asset-import-split-design.md
|
||
git commit -m "完成资产导入拆分后端验证"
|
||
```
|