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

260 lines
9.0 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.
# 员工资产信息维护设计
## 背景
员工信息维护页面当前仅支持维护员工基础信息,不支持维护员工名下资产信息。现需在现有员工维护页面中补齐资产信息的新增、编辑、删除、详情展示和导入能力,并与现有员工导入交互保持一致。
本次设计基于 `2026-03-12` 确认了以下业务约束:
- 资产表保留字段名 `person_id`
- `person_id` 存员工身份证号,关联 `ccdi_base_staff.id_card`
- `asset_id` 改为数据库自增主键,不出现在导入模板中
- 资产导入失败记录入口需与员工导入失败记录入口明确区分,按钮文案为“查看员工资产导入失败记录”
## 目标
- 在员工信息维护页新增员工资产信息维护能力
- 在员工新增和编辑弹窗中支持员工资产信息的添加、编辑、删除
- 在员工详情弹窗中展示该员工全部资产信息
- 在员工列表页新增“导入资产信息”入口,并复用现有异步导入交互
- 删除员工时同步删除该员工全部资产信息
## 非目标
- 不新增独立的“员工资产信息管理”菜单页面
- 不在资产维护中暴露 `asset_id`
- 不允许用户在前端手工填写 `person_id`
- 不改造现有员工列表查询条件和分页结构
## 现状
当前员工维护能力主要集中在以下位置:
- 前端页面:`ruoyi-ui/src/views/ccdiBaseStaff/index.vue`
- 前端接口:`ruoyi-ui/src/api/ccdiBaseStaff.js`
- 后端控制器:`ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiBaseStaffController.java`
- 后端服务:`ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffServiceImpl.java`
- 导入服务:`ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiBaseStaffImportServiceImpl.java`
现有员工导入采用异步任务 + Redis 状态轮询 + 失败记录分页查询的模式,前端使用本地存储保存最近一次导入任务信息。
## 方案对比
### 方案一:员工页内嵌资产子表聚合维护
- 员工新增、编辑、详情接口返回员工主信息和资产列表聚合结果
- 员工弹窗内部直接维护资产子表
- 资产导入使用独立接口,但交互完全复用员工导入模式
优点:
- 最符合当前需求和现有页面使用习惯
- 用户一次打开员工弹窗即可维护完整信息
- 删除员工时做事务级联最直接
缺点:
- 员工 DTO、VO、Service、前端表单都需要联动调整
### 方案二:资产作为独立模块实现,员工页只嵌入调用
- 后端和前端都按独立资源建设资产模块
- 员工页通过额外接口拉取并嵌入展示
优点:
- 模块边界更清晰
- 未来扩展独立资产菜单更容易
缺点:
- 本次需求明显超出必要范围
- 页面状态和接口交互更复杂
### 方案三:员工页只加资产查看和导入,编辑改为二级弹窗
- 员工弹窗中通过二级弹窗维护资产
优点:
- 对现有员工表单侵入较小
缺点:
- 交互割裂
- 不符合“新增和编辑弹窗中支持添加、编辑、删除”的要求
## 最终方案
采用方案一:在员工信息维护页内嵌资产信息子表,员工接口作为聚合接口返回和保存资产列表;资产导入保持独立入口和独立后端接口,但沿用现有员工导入的上传、异步处理、结果通知、失败记录查询交互。
## 数据模型设计
### 数据表
新增 `ccdi_asset_info` 表,字段来源于 `assets/资产信息表.csv`,并做以下调整:
- `asset_id``BIGINT` 自增主键
- `person_id``VARCHAR(18)`,保存员工身份证号,关联 `ccdi_base_staff.id_card`
- 审计字段沿用当前项目规范,由后端自动填充
建议字段如下:
- `asset_id`
- `person_id`
- `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_person_id(person_id)`
- `idx_asset_main_type(asset_main_type)`
## 后端设计
### 新增资产信息模块对象
`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
- `CcdiBaseStaffAddDTO.assetInfoList`
- `CcdiBaseStaffEditDTO.assetInfoList`
- `CcdiBaseStaffVO.assetInfoList`
后端聚合规则:
- 查询员工详情时,按员工 `id_card` 查询全部资产并组装到 `assetInfoList`
- 新增员工时,先保存员工,再以员工 `id_card` 回填并保存资产列表
- 编辑员工时,更新员工主信息,再按员工身份证号重建资产列表
- 删除员工时,先删资产再删员工,整个过程置于同一事务内
### 编辑时的资产处理策略
编辑员工时不要求前端传递资产行状态,直接按“当前完整列表”覆盖:
- 获取编辑前员工旧身份证号
- 更新员工主信息
- 如果身份证号变更,按旧身份证号删除旧资产
- 按当前最新身份证号删除对应资产
- 将前端提交的资产列表统一设置 `person_id = 当前员工身份证号`
- 批量插入最新资产列表
该策略实现简单,能直接覆盖资产新增、编辑、删除三种变化。
### 资产导入接口
新增独立资产导入接口:
- `POST /ccdi/assetInfo/importTemplate`
- `POST /ccdi/assetInfo/importData`
- `GET /ccdi/assetInfo/importStatus/{taskId}`
- `GET /ccdi/assetInfo/importFailures/{taskId}`
导入交互沿用现有员工导入设计:
- 异步任务执行
- Redis 保存任务状态
- 失败记录单独缓存
- 前端轮询状态并显示通知
### 校验规则
#### 员工保存时
- 员工基础信息仍沿用现有校验规则
- `assetInfoList` 中空行自动过滤
- 资产必填项:`assetMainType``assetSubType``assetName``currentValue``assetStatus`
- 数值和日期格式必须合法
- 后端强制回填 `person_id = 员工 id_card`
#### 资产导入时
- `person_id` 必填,且必须能匹配到员工 `id_card`
- 模板中不包含 `asset_id`
- 允许同一员工导入多条资产
- 失败记录仅返回失败数据,不返回成功数据
## 前端设计
### 列表页
`ruoyi-ui/src/views/ccdiBaseStaff/index.vue` 的按钮区新增:
- “导入资产信息”按钮
- “查看员工资产导入失败记录”按钮
资产导入相关状态全部独立维护:
- 独立弹窗状态
- 独立轮询定时器
- 独立任务 ID
- 独立 localStorage key
- 独立失败记录弹窗和分页状态
### 新增和编辑弹窗
在现有员工弹窗的“基本信息”下方新增“资产信息”分区,采用可编辑子表形式。
子表字段:
- 资产大类
- 资产小类
- 资产名称
- 产权占比
- 购买/评估日期
- 资产原值
- 当前估值
- 估值截止日期
- 资产状态
- 备注
- 操作
交互规则:
- 分区右侧提供“新增资产”按钮
- 每行支持删除
- 编辑时回显 `assetInfoList`
- 前端不展示 `asset_id``person_id`
### 详情弹窗
在“员工详情”弹窗中新增“资产信息”区域,使用只读表格展示全部资产。
若无资产数据,显示“暂无资产信息”空状态。
## 数据流
### 员工新增
前端提交员工基础信息和 `assetInfoList`,后端保存员工后按 `id_card` 批量保存资产。
### 员工编辑
前端拉取员工详情回显基础信息和资产列表,用户修改后提交完整列表,后端按最新员工身份证号重建资产明细。
### 员工详情
后端查询员工主信息,再按 `id_card` 查询资产列表并一并返回。
### 员工删除
后端先按员工身份证号删除资产,再删除员工主记录。
### 资产导入
前端上传资产 Excel后端异步校验并批量插入资产数据失败记录通过独立入口查看。
## 异常处理
- 资产导入时,若 `person_id` 无法匹配员工,记录失败原因
- 员工编辑时若身份证号变更,必须同步处理旧资产清理和新资产重建
- 员工删除和员工编辑资产重建均使用事务,防止主从数据不一致
- 前端提示文案中明确区分“员工导入”和“员工资产导入”
## 验收标准
- 员工列表页新增“导入资产信息”按钮
- 资产导入失败时显示“查看员工资产导入失败记录”按钮
- 员工新增和编辑弹窗中可添加、编辑、删除资产信息
- 员工详情弹窗中可查看该员工全部资产信息
- 删除员工后,该员工资产信息同步删除
- 资产导入模板不包含 `asset_id`
- 资产导入使用 `person_id` 关联员工身份证号