Files
ccdi/docs/plans/2026-03-13-employee-family-asset-import-split-design.md

249 lines
7.9 KiB
Markdown
Raw Normal View History

2026-03-13 16:07:51 +08:00
# 员工资产导入与亲属资产导入拆分设计
## 背景
当前员工信息维护页 [ccdiBaseStaff/index.vue](/D:/ccdi/ccdi/ruoyi-ui/src/views/ccdiBaseStaff/index.vue) 与员工亲属关系维护页 [ccdiStaffFmyRelation/index.vue](/D:/ccdi/ccdi/ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue) 共用了 `/ccdi/assetInfo/*` 资产导入接口,导致两类业务边界混淆:
- 员工页的“导入资产信息”应只导入员工本人资产
- 亲属页的“导入亲属资产信息”应只导入员工亲属资产
- 当前共享接口无法同时满足这两条规则,模板、权限、失败文案也容易串用
用户已确认:
- 保留员工页“导入资产信息”按钮
- 员工资产导入与亲属资产导入必须彻底拆分
- 员工亲属资产导入功能只能导入员工亲属的资产信息,不能更新员工的
## 目标
- 将员工资产导入与亲属资产导入拆成两条独立链路
- 员工页只支持员工本人资产导入
- 亲属页只支持亲属资产导入
- 模板、接口、权限、失败提示、任务状态缓存全部分离
## 非目标
- 不改造员工资产手工维护功能
- 不改造亲属资产手工维护功能
- 不新增独立资产菜单页面
- 不调整 `ccdi_asset_info` 表结构
## 现状
当前共用资产导入能力集中在:
- 前端 API[ccdiAssetInfo.js](/D:/ccdi/ccdi/ruoyi-ui/src/api/ccdiAssetInfo.js)
- 员工页调用点:[ccdiBaseStaff/index.vue](/D:/ccdi/ccdi/ruoyi-ui/src/views/ccdiBaseStaff/index.vue)
- 亲属页调用点:[ccdiStaffFmyRelation/index.vue](/D:/ccdi/ccdi/ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue)
- 后端控制器:[CcdiAssetInfoController.java](/D:/ccdi/ccdi/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiAssetInfoController.java)
- 后端导入服务:[CcdiAssetInfoImportServiceImpl.java](/D:/ccdi/ccdi/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiAssetInfoImportServiceImpl.java)
问题点:
- 员工页与亲属页共用同一上传地址 `/ccdi/assetInfo/importData`
- 共用同一模板下载地址 `/ccdi/assetInfo/importTemplate`
- 共用同一任务状态与失败记录查询入口
- 共用同一导入匹配规则,无法表达“员工页仅员工本人、亲属页仅亲属”
## 方案对比
### 方案一:员工资产导入、亲属资产导入完全拆分
- 员工页新增一套独立导入接口
- 亲属页保留现有 `/ccdi/assetInfo/*`
- 两边各自使用独立模板、权限、校验和失败文案
优点:
- 业务边界最清晰
- 后续维护风险最低
- 模板与前端交互不再串用
缺点:
- 需要新增一套员工资产导入 controller/service/api
### 方案二:继续共用接口,通过 `mode` 区分
- 前端调用同一接口
- 后端通过 `mode=employee/family` 分支处理
优点:
- 代码新增较少
缺点:
- 控制器和 service 内分支复杂
- 模板、权限、提示文案仍容易混淆
- 后续扩展时回归风险高
### 方案三:仅修前端入口文案
优点:
- 改动最小
缺点:
- 业务问题未解决
- 实际导入规则仍然混乱
## 最终方案
采用方案一:员工资产导入与亲属资产导入完全拆分。
### 员工资产导入
- 页面入口:员工信息维护页
- 独立接口:
- `POST /ccdi/baseStaff/asset/importTemplate`
- `POST /ccdi/baseStaff/asset/importData`
- `GET /ccdi/baseStaff/asset/importStatus/{taskId}`
- `GET /ccdi/baseStaff/asset/importFailures/{taskId}`
- 独立前端 API 文件:`ruoyi-ui/src/api/ccdiBaseStaffAsset.js`
- 仅允许导入员工本人资产
- 模板第一列要求填写员工身份证号
- 导入成功后强制写入:
- `family_id = 员工身份证号`
- `person_id = 员工身份证号`
### 亲属资产导入
- 页面入口:员工亲属关系维护页
- 保留现有接口:
- `POST /ccdi/assetInfo/importTemplate`
- `POST /ccdi/assetInfo/importData`
- `GET /ccdi/assetInfo/importStatus/{taskId}`
- `GET /ccdi/assetInfo/importFailures/{taskId}`
- 仅允许导入员工亲属资产
- 模板第一列要求填写亲属证件号
- 导入成功后强制写入:
- `family_id = 关联员工证件号`
- `person_id = 亲属证件号`
## 后端设计
### 新增员工资产导入控制面
新增:
- `controller/CcdiBaseStaffAssetImportController.java`
- `service/ICcdiBaseStaffAssetImportService.java`
- `service/impl/CcdiBaseStaffAssetImportServiceImpl.java`
- `domain/excel/CcdiBaseStaffAssetInfoExcel.java`
- `domain/vo/BaseStaffAssetImportFailureVO.java`
员工资产导入匹配规则:
- 仅根据 `ccdi_base_staff.id_card` 匹配
- 若未匹配到员工,导入失败
- 不再兜底匹配亲属关系表
- 若命中员工,则写入 `family_id = person_id = id_card`
亲属资产导入规则调整:
- [CcdiAssetInfoImportServiceImpl.java](/D:/ccdi/ccdi/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiAssetInfoImportServiceImpl.java) 只保留亲属资产逻辑
- 仅根据 `ccdi_staff_fmy_relation.relation_cert_no` 匹配
- 不再匹配员工本人身份证号
### 权限设计
- 员工资产导入接口:`ccdi:employee:import`
- 亲属资产导入接口:`ccdi:staffFmyRelation:import`
禁止再使用同时兼容两个权限的写法,以免接口语义再次混淆。
## 前端设计
### 员工页
[ccdiBaseStaff/index.vue](/D:/ccdi/ccdi/ruoyi-ui/src/views/ccdiBaseStaff/index.vue) 改为:
- 上传地址改为员工资产专用接口
- 模板下载改为员工资产模板
- 任务状态和失败记录查询改为员工资产专用接口
- 提示文案明确为“员工资产数据导入”
### 亲属页
[ccdiStaffFmyRelation/index.vue](/D:/ccdi/ccdi/ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue) 保持:
- 上传地址仍为 `/ccdi/assetInfo/importData`
- 模板下载仍为亲属资产模板
- 文案继续强调“亲属资产”
## 模板设计
员工资产模板:
- 文件名:`员工资产信息模板_xxx.xlsx`
- 首列表头:`员工身份证号*`
亲属资产模板:
- 文件名:`亲属资产信息模板_xxx.xlsx`
- 首列表头:`亲属证件号*`
## 校验规则
### 员工资产导入
- 员工身份证号不能为空
- 资产必填字段不能为空
- 员工身份证号必须存在于 `ccdi_base_staff.id_card`
- 若填写的是亲属证件号或其他未命中的证件号,直接失败
建议失败文案:
- `未找到员工资产归属员工`
- 或更明确的 `员工资产导入仅支持员工本人证件号`
### 亲属资产导入
- 亲属证件号不能为空
- 资产必填字段不能为空
- 亲属证件号必须存在于 `ccdi_staff_fmy_relation.relation_cert_no`
- 若填写员工本人身份证号且不存在亲属关系映射,直接失败
- 若同一亲属证件号匹配多个员工关系,失败并提示归属不唯一
## 测试要求
后端:
- 员工资产导入:员工本人证件号成功
- 员工资产导入:亲属证件号失败
- 亲属资产导入:亲属证件号成功
- 亲属资产导入:员工本人证件号失败
- 两套模板标题和首列表头不同
- 两套接口权限分别正确
前端:
- 员工页使用员工资产专用上传地址
- 亲属页继续使用 `/ccdi/assetInfo/*`
- 员工页下载员工资产模板
- 亲属页下载亲属资产模板
- 员工页和亲属页的失败记录弹窗文案不混淆
## 风险与回滚
风险:
- 当前仓库内已有共享资产导入代码,拆分时容易遗漏某一处调用
- 若只拆后端不拆前端,页面会继续指向旧接口
- 若模板文案未同步,用户仍可能误用模板
回滚策略:
- 独立提交员工资产导入新增改动
- 独立提交亲属资产导入收敛改动
- 任一阶段出现回归,可按提交粒度回退
## 实现状态
- 2026-03-13 已完成后端拆分实现
- 已新增员工资产独立导入接口 `/ccdi/baseStaff/asset/*`
- 已将 `/ccdi/assetInfo/*` 收敛为亲属资产专用接口
- 已通过后端定向测试验证员工与亲属两套导入链路、模板名称和失败文案拆分生效