# 员工资产信息维护设计 ## 背景 员工信息维护页面当前仅支持维护员工基础信息,不支持维护员工名下资产信息。现需在现有员工维护页面中补齐资产信息的新增、编辑、删除、详情展示和导入能力,并与现有员工导入交互保持一致。 本次设计基于 `2026-03-12` 确认了以下业务约束: - 资产表保留字段名 `person_id` - 资产表新增 `family_id` - `family_id` 存归属员工身份证号 - `person_id` 存资产实际持有人身份证号 - 员工本人资产:`family_id = person_id = 员工身份证号` - 员工亲属资产:`family_id = 员工身份证号`,`person_id = 亲属身份证号` - `asset_id` 改为数据库自增主键,不出现在导入模板中 - 资产导入模板不要求填写 `family_id` - 导入员工资产信息时,系统根据 `person_id` 自动填充归属员工的 `id_card` 到 `family_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` 自增主键 - `family_id`:`VARCHAR(18)`,保存归属员工身份证号,关联 `ccdi_base_staff.id_card` - `person_id`:`VARCHAR(18)`,保存资产实际持有人身份证号 - 审计字段沿用当前项目规范,由后端自动填充 建议字段如下: - `asset_id` - `family_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_family_id(family_id)` - `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` 查询 `family_id = 员工身份证号` 的全部资产并组装到 `assetInfoList` - 新增员工时,先保存员工,再以员工 `id_card` 回填资产列表中的 `family_id` - 编辑员工时,更新员工主信息,再按员工身份证号重建以 `family_id` 归户的资产列表 - 删除员工时,先按 `family_id` 删除资产再删员工,整个过程置于同一事务内 ### 编辑时的资产处理策略 编辑员工时不要求前端传递资产行状态,直接按“当前完整列表”覆盖: - 获取编辑前员工旧身份证号 - 更新员工主信息 - 如果身份证号变更,按旧身份证号删除 `family_id = 旧身份证号` 的旧资产 - 按当前最新身份证号删除 `family_id = 当前身份证号` 的对应资产 - 当前员工本人资产设置 `family_id = person_id = 当前员工身份证号` - 当前员工亲属资产设置 `family_id = 当前员工身份证号`,`person_id = 资产实际持有人身份证号` - 批量插入最新资产列表 该策略实现简单,能直接覆盖资产新增、编辑、删除三种变化。 ### 资产导入接口 新增独立资产导入接口: - `POST /ccdi/assetInfo/importTemplate` - `POST /ccdi/assetInfo/importData` - `GET /ccdi/assetInfo/importStatus/{taskId}` - `GET /ccdi/assetInfo/importFailures/{taskId}` 导入交互沿用现有员工导入设计: - 异步任务执行 - Redis 保存任务状态 - 失败记录单独缓存 - 前端轮询状态并显示通知 ### 校验规则 #### 员工保存时 - 员工基础信息仍沿用现有校验规则 - `assetInfoList` 中空行自动过滤 - 资产必填项:`personId`、`assetMainType`、`assetSubType`、`assetName`、`currentValue`、`assetStatus` - 数值和日期格式必须合法 - 后端强制回填 `family_id = 员工 id_card` - 当 `personId = 员工 id_card` 时,视为员工本人资产 - 当 `personId != 员工 id_card` 时,视为员工亲属资产 #### 资产导入时 - 模板中仅要求填写 `person_id`,不要求填写 `family_id` - 若 `person_id` 能匹配员工 `id_card`,视为员工本人资产,自动填充 `family_id = 该员工 id_card` - 若 `person_id` 不能匹配员工 `id_card`,则继续匹配员工亲属关系中的亲属身份证号,匹配成功后自动填充对应员工的 `id_card` 到 `family_id` - 若 `person_id` 同时匹配到多个员工家庭,则导入失败,原因标记为“资产归属员工不唯一” - 若 `person_id` 在员工和员工亲属关系中均无法匹配,则导入失败 - 模板中不包含 `asset_id` - 允许同一员工导入多条资产 - 失败记录仅返回失败数据,不返回成功数据 ## 前端设计 ### 列表页 在 `ruoyi-ui/src/views/ccdiBaseStaff/index.vue` 的按钮区新增: - “导入资产信息”按钮 - “查看员工资产导入失败记录”按钮 资产导入相关状态全部独立维护: - 独立弹窗状态 - 独立轮询定时器 - 独立任务 ID - 独立 localStorage key - 独立失败记录弹窗和分页状态 ### 新增和编辑弹窗 在现有员工弹窗的“基本信息”下方新增“资产信息”分区,采用可编辑子表形式。 子表字段: - 资产实际持有人身份证号 - 资产大类 - 资产小类 - 资产名称 - 产权占比 - 购买/评估日期 - 资产原值 - 当前估值 - 估值截止日期 - 资产状态 - 备注 - 操作 交互规则: - 分区右侧提供“新增资产”按钮 - 每行支持删除 - 编辑时回显 `assetInfoList` - 前端不展示 `asset_id`、`family_id` - 前端允许填写 `personId`,用于表示资产实际持有人身份证号 - 当 `personId` 与当前员工身份证号一致时,视为本人资产;不一致时,视为亲属资产 ### 详情弹窗 在“员工详情”弹窗中新增“资产信息”区域,使用只读表格展示全部资产。 若无资产数据,显示“暂无资产信息”空状态。 详情表格建议增加: - `personId`:资产实际持有人身份证号 - `ownerType`:本人 / 亲属 ## 数据流 ### 员工新增 前端提交员工基础信息和 `assetInfoList`,后端保存员工后按员工 `id_card` 为每条资产回填 `family_id`,再批量保存资产。 ### 员工编辑 前端拉取员工详情回显基础信息和资产列表,用户修改后提交完整列表,后端按最新员工身份证号重建 `family_id = 员工身份证号` 的资产明细。 ### 员工详情 后端查询员工主信息,再按 `family_id = 员工身份证号` 查询资产列表并一并返回。 ### 员工删除 后端先按 `family_id = 员工身份证号` 删除资产,再删除员工主记录。 ### 资产导入 前端上传资产 Excel,后端根据 `person_id` 自动识别归属员工并回填 `family_id`,异步校验并批量插入资产数据,失败记录通过独立入口查看。 ## 异常处理 - 资产导入时,若 `person_id` 无法匹配员工本人或员工亲属,记录失败原因 - 资产导入时,若 `person_id` 对应多个员工家庭,记录归属不唯一失败原因 - 员工编辑时若身份证号变更,必须同步处理旧资产清理和新资产重建 - 员工删除和员工编辑资产重建均使用事务,防止主从数据不一致 - 前端提示文案中明确区分“员工导入”和“员工资产导入” ## 验收标准 - 员工列表页新增“导入资产信息”按钮 - 资产导入失败时显示“查看员工资产导入失败记录”按钮 - 员工新增和编辑弹窗中可添加、编辑、删除资产信息 - 员工详情弹窗中可查看该员工全部资产信息 - 删除员工后,该员工资产信息同步删除 - 资产导入模板不包含 `asset_id` - 资产导入模板不填写 `family_id` - 资产导入使用 `person_id` 识别资产实际持有人,并自动回填归属员工的 `family_id`