Files
ccdi/docs/plans/2026-03-12-staff-family-asset-maintenance-design.md

333 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 员工亲属资产维护设计
## 背景
现有员工亲属关系维护页面 `http://localhost/maintain/staffFmyRelation` 已支持员工亲属关系的新增、编辑、删除、详情、导入导出,但尚不支持维护亲属名下资产信息。
当前仓库中已有员工资产维护设计文档 [2026-03-12-employee-asset-maintenance-design.md](/D:/ccdi/ccdi/docs/plans/2026-03-12-employee-asset-maintenance-design.md),其核心约束是通过 `family_id` 表示归属员工,通过 `person_id` 表示资产实际持有人。本次需求需要将该能力调整到“员工亲属关系维护页面”中,并明确仅维护亲属资产,不包含员工本人资产。
本次设计于 2026-03-12 确认以下业务口径:
- 维护入口为员工亲属关系页面 `staffFmyRelation`
- 仅维护当前亲属关系对应的亲属资产,不包含员工本人资产
- 不新增独立的亲属资产菜单页面
- 不新增 `relation_id` 等额外资产归属字段
- `family_id` 存员工证件号,对应亲属关系中的 `person_id`
- `person_id` 存亲属证件号,对应亲属关系中的 `relation_cert_no`
- 亲属资产中的 `person_id` 不强制要求为身份证号,存证件号即可
- 编辑亲属关系时,`relationCertType``relationCertNo` 禁止修改
## 目标
- 在员工亲属关系维护页中新增亲属资产维护能力
- 在亲属关系新增/编辑弹窗中支持维护当前亲属名下资产
- 在亲属关系详情弹窗中展示当前亲属全部资产
- 在亲属关系列表页新增亲属资产导入入口,并复用现有异步导入交互
- 删除亲属关系时同步删除该亲属名下资产
## 非目标
- 不维护员工本人资产
- 不新增独立“亲属资产维护”菜单
- 不新增 `relation_id`
- 不在列表页直接展开显示资产明细
- 不改造现有亲属关系查询条件和分页结构
## 现状
当前员工亲属关系维护能力主要集中在以下位置:
- 前端页面:`ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue`
- 前端接口:`ruoyi-ui/src/api/ccdiStaffFmyRelation.js`
- 后端控制器:`ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiStaffFmyRelationController.java`
- 后端服务:`ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffFmyRelationServiceImpl.java`
- 后端映射:`ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiStaffFmyRelationMapper.xml`
当前一条亲属关系记录的关键字段如下:
- `person_id`:员工证件号
- `relation_cert_type`:亲属证件类型
- `relation_cert_no`:亲属证件号
数据库对 `ccdi_staff_fmy_relation` 设有唯一约束 `uk_person_cert(person_id, relation_cert_no)`,因此一条亲属关系在业务上可以稳定地通过“员工证件号 + 亲属证件号”定位,这也正好可以复用为亲属资产的归属键。
## 方案对比
### 方案一:在亲属关系弹窗内嵌资产子表聚合维护
- 亲属关系详情接口聚合返回 `assetInfoList`
- 亲属关系新增、编辑时同步保存资产列表
- 亲属资产导入采用独立接口,但交互复用现有导入模式
优点:
- 最符合“在亲属关系维护页面维护亲属资产”的使用预期
- 页面上下文最完整,用户不需要在多个弹窗间切换
- 删除亲属关系时级联删除资产最直接
缺点:
- 需要扩展 DTO、VO、Service 和前端弹窗结构
### 方案二:在亲属关系页增加“维护资产”二级弹窗
- 亲属关系页保留现状
- 通过“维护资产”按钮打开独立二级弹窗编辑资产
优点:
- 对现有亲属关系表单侵入较小
缺点:
- 交互割裂
- 用户维护一条亲属关系时无法同时看到关系信息与资产信息
### 方案三:只新增资产查看与导入,不支持页面内编辑
优点:
- 开发量最小
缺点:
- 不满足“添加维护功能”的核心诉求
## 最终方案
采用方案一:在员工亲属关系维护页的新增、编辑、详情弹窗中内嵌“亲属资产信息”分区,由亲属关系接口作为聚合接口返回和保存 `assetInfoList`;同时新增“亲属资产导入”独立接口,并沿用现有亲属关系导入的异步处理与失败记录交互。
## 数据模型设计
### 资产归属规则
亲属资产的归属键定义如下:
- `family_id = 当前亲属关系.person_id`
- `person_id = 当前亲属关系.relation_cert_no`
含义如下:
- `family_id` 表示归属员工
- `person_id` 表示亲属资产实际持有人
- 当前页面只查询和保存满足 `family_id = 员工证件号``person_id = 亲属证件号` 的资产
### 数据表
新增 `ccdi_asset_info` 表,字段来源参考资产设计文档和 `assets/资产信息表.csv`,本次继续沿用以下关键字段:
- `asset_id``BIGINT` 自增主键
- `family_id``VARCHAR(100)`,保存员工证件号
- `person_id``VARCHAR(100)`,保存亲属证件号
- `asset_main_type`
- `asset_sub_type`
- `asset_name`
- `ownership_ratio`
- `purchase_eval_date`
- `original_value`
- `current_value`
- `valuation_date`
- `asset_status`
- `remarks`
- `create_by`
- `create_time`
- `update_by`
- `update_time`
建议索引:
- `idx_family_id(family_id)`
- `idx_person_id(person_id)`
- `idx_family_person(family_id, person_id)`
## 后端设计
### 新增资产模块对象
`ccdi-info-collection` 中新增:
- `domain/CcdiAssetInfo.java`
- `domain/dto/CcdiAssetInfoDTO.java`
- `domain/vo/CcdiAssetInfoVO.java`
- `domain/excel/CcdiAssetInfoExcel.java`
- `domain/vo/AssetImportFailureVO.java`
- `mapper/CcdiAssetInfoMapper.java`
- `service/ICcdiAssetInfoService.java`
- `service/ICcdiAssetInfoImportService.java`
- `service/impl/CcdiAssetInfoServiceImpl.java`
- `service/impl/CcdiAssetInfoImportServiceImpl.java`
- `controller/CcdiAssetInfoController.java`
- `resources/mapper/info/collection/CcdiAssetInfoMapper.xml`
### 扩展亲属关系聚合接口
扩展现有亲属关系 DTO 和 VO
- `CcdiStaffFmyRelationAddDTO.assetInfoList`
- `CcdiStaffFmyRelationEditDTO.assetInfoList`
- `CcdiStaffFmyRelationVO.assetInfoList`
聚合规则:
- 查询详情时,按当前亲属关系的 `personId + relationCertNo` 查询资产列表并组装到 `assetInfoList`
- 新增亲属关系时,先保存关系,再为资产统一回填 `family_id``person_id`
- 编辑亲属关系时,更新关系主信息,再按当前固定归属键重建资产列表
- 删除亲属关系时,先删资产再删亲属关系,整体使用事务
### 编辑时的特殊约束
编辑亲属关系时:
- 前端禁止修改 `relationCertType`
- 前端禁止修改 `relationCertNo`
- 后端读取旧记录后做防御校验
- 若请求中的 `relationCertType``relationCertNo` 与旧值不一致,直接拒绝保存并提示“关系人证件类型/证件号码不允许修改”
### 资产保存策略
编辑当前亲属关系时不要求前端传资产行状态,直接按“当前完整列表覆盖”处理:
- 查询当前亲属关系旧记录
- 校验亲属证件类型、亲属证件号未被修改
- 更新亲属关系主信息
-`family_id = personId``person_id = relationCertNo` 删除旧资产
- 将当前提交的 `assetInfoList` 统一回填归属键后批量插入
由于编辑时禁止修改亲属证件类型和证件号,因此不需要处理资产跨亲属迁移问题。
### 资产导入接口
新增独立资产导入接口:
- `POST /ccdi/assetInfo/importTemplate`
- `POST /ccdi/assetInfo/importData`
- `GET /ccdi/assetInfo/importStatus/{taskId}`
- `GET /ccdi/assetInfo/importFailures/{taskId}`
导入归属规则:
- 模板中 `person_id` 填亲属证件号
- 模板中不要求填写 `family_id`
- 系统通过 `ccdi_staff_fmy_relation.relation_cert_no = person_id` 反查亲属关系
- 若能唯一匹配,则自动回填对应记录的 `person_id``family_id`
- 若找不到匹配关系,导入失败
- 若匹配到多条不同员工关系,导入失败,原因记为“亲属资产归属员工不唯一”
## 前端设计
### 列表页
`ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue` 按钮区新增:
- “导入亲属资产信息”按钮
- “查看亲属资产导入失败记录”按钮
资产导入状态全部独立维护:
- 独立上传弹窗状态
- 独立轮询定时器
- 独立任务 ID
- 独立 `localStorage key`
- 独立失败记录弹窗和分页状态
### 新增和编辑弹窗
在现有亲属关系弹窗的“基本信息”下方新增“亲属资产信息”分区,采用可编辑子表。
子表字段:
- 资产大类
- 资产小类
- 资产名称
- 产权占比
- 购买/评估日期
- 资产原值
- 当前估值
- 估值截止日期
- 资产状态
- 备注
- 操作
交互规则:
- 分区右侧提供“新增资产”按钮
- 每行支持删除
- 编辑时回显 `assetInfoList`
- 前端不展示 `asset_id``family_id``person_id`
- 新增资产前若当前尚未录入亲属证件类型或证件号码,则禁用新增资产并提示“请先填写关系人证件信息”
- 编辑时 `relationCertType``relationCertNo` 置灰禁用
### 详情弹窗
在详情弹窗中新增“亲属资产信息”区域,使用只读表格展示当前亲属名下资产。
若无资产数据,显示“暂无亲属资产信息”。
## 数据流
### 新增亲属关系
前端提交亲属关系基础信息和 `assetInfoList`,后端保存亲属关系后,按当前记录的 `personId``relationCertNo` 为每条资产回填 `family_id``person_id`,再批量保存。
### 编辑亲属关系
前端拉取详情回显基础信息和资产列表,用户修改后提交完整列表。后端校验证件类型、证件号码未变更后,按当前亲属关系归属键重建资产明细。
### 查询详情
后端查询亲属关系主信息,再按 `family_id = personId``person_id = relationCertNo` 查询资产列表并一并返回。
### 删除亲属关系
后端先删除当前亲属名下资产,再删除亲属关系主记录。
### 导入亲属资产
前端上传亲属资产 Excel后端根据 `person_id = 亲属证件号` 识别归属亲属关系并自动回填 `family_id`,异步校验并批量插入资产数据,失败记录通过独立入口查看。
## 校验规则
### 亲属关系保存时
- 沿用现有亲属关系校验规则
- 编辑时禁止修改 `relationCertType`
- 编辑时禁止修改 `relationCertNo`
- `assetInfoList` 中整行为空的数据自动过滤
### 亲属资产保存时
- 资产必填项:`assetMainType``assetSubType``assetName``currentValue``assetStatus`
- 数值字段必须合法
- 日期字段必须合法
- 后端不信任前端传入的归属字段,统一强制回填:
- `family_id = 当前亲属关系.personId`
- `person_id = 当前亲属关系.relationCertNo`
## 异常处理
- 编辑亲属关系时,若请求试图修改 `relationCertType``relationCertNo`,后端直接报错
- 删除亲属关系与删除资产使用同一事务,避免数据不一致
- 查询详情时若资产查询异常,整体接口返回失败,避免前端收到半残数据
- 亲属资产导入时,若亲属证件号无法匹配亲属关系,记录失败原因
- 亲属资产导入时,若一个亲属证件号匹配多个员工关系,记录“亲属资产归属员工不唯一”
- 前端提示文案中明确区分“亲属关系导入”和“亲属资产导入”
## 验收标准
- `staffFmyRelation` 新增/编辑弹窗中可新增、编辑、删除亲属资产
- 编辑亲属关系时,关系人证件类型和证件号码不可修改
- 详情弹窗中可查看该亲属全部资产信息
- 删除亲属关系后,对应亲属资产同步删除
- 亲属资产支持独立导入,并可查看亲属资产导入失败记录
- 亲属资产导入模板不要求填写 `family_id`
- 系统根据 `person_id = 亲属证件号` 自动回填归属员工证件号到 `family_id`
## 测试建议
- 新增亲属关系但不维护资产
- 新增亲属关系并维护单条、多条资产
- 编辑亲属关系时新增、修改、删除资产
- 验证编辑时不能修改亲属证件类型与证件号码
- 删除亲属关系时资产级联删除
- 亲属资产导入成功、无法匹配、匹配不唯一三类场景