diff --git a/docs/plans/2026-03-12-staff-family-asset-maintenance-backend-implementation.md b/docs/plans/2026-03-12-staff-family-asset-maintenance-backend-implementation.md new file mode 100644 index 0000000..8f6229f --- /dev/null +++ b/docs/plans/2026-03-12-staff-family-asset-maintenance-backend-implementation.md @@ -0,0 +1,310 @@ +# 员工亲属资产维护后端实施计划 + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** 为员工亲属关系维护页面补齐亲属资产的后端聚合保存、详情查询、删除级联和异步导入能力。 + +**Architecture:** 以 `CcdiStaffFmyRelation` 为聚合根扩展 `assetInfoList`,由资产模块负责持久化和导入,由亲属关系服务负责在新增、编辑、删除、详情等场景中协调资产数据。编辑时通过固定的 `family_id + person_id` 覆盖重建亲属资产,不引入额外关联字段。 + +**Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus, MyBatis XML, Redis, EasyExcel, Lombok + +--- + +### Task 1: 补齐资产表 SQL 与索引设计 + +**Files:** +- Create: `D:\ccdi\ccdi\sql\ccdi_asset_info.sql` +- Check: `D:\ccdi\ccdi\docs\plans\2026-03-12-staff-family-asset-maintenance-design.md` + +**Step 1: 写出资产表建表 SQL** + +- 新增 `ccdi_asset_info` +- 主键使用 `asset_id BIGINT AUTO_INCREMENT` +- 字段包含 `family_id`、`person_id` 和资产业务字段 +- 审计字段遵循项目现有风格 + +**Step 2: 为归属查询补索引** + +- 添加 `idx_family_id` +- 添加 `idx_person_id` +- 添加联合索引 `idx_family_person` + +**Step 3: 自查字段口径** + +- 确认 `family_id` 保存员工证件号 +- 确认 `person_id` 保存亲属证件号 +- 确认不新增 `relation_id` + +**Step 4: 记录执行命令** + +Run: `Get-Content 'D:\ccdi\ccdi\sql\ccdi_asset_info.sql'` +Expected: 能看到完整建表语句与索引定义 + +**Step 5: 提交** + +```bash +git add sql/ccdi_asset_info.sql +git commit -m "新增亲属资产表结构设计" +``` + +### Task 2: 创建资产领域对象与映射接口 + +**Files:** +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\domain\CcdiAssetInfo.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\domain\dto\CcdiAssetInfoDTO.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\domain\vo\CcdiAssetInfoVO.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\domain\excel\CcdiAssetInfoExcel.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\domain\vo\AssetImportFailureVO.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\mapper\CcdiAssetInfoMapper.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\resources\mapper\info\collection\CcdiAssetInfoMapper.xml` + +**Step 1: 创建领域实体与 DTO/VO** + +- `CcdiAssetInfo` 映射表字段 +- `CcdiAssetInfoDTO` 承载亲属关系聚合保存时的子表数据 +- `CcdiAssetInfoVO` 用于详情回显 + +**Step 2: 创建 Excel 与失败记录对象** + +- `CcdiAssetInfoExcel` 用于模板下载与导入解析 +- `AssetImportFailureVO` 仅返回失败记录 + +**Step 3: 定义 Mapper 能力** + +- 按 `family_id + person_id` 查询资产列表 +- 按 `family_id + person_id` 删除资产 +- 批量插入资产 +- 导入场景下按亲属证件号查询归属员工候选 + +**Step 4: 运行编译检查** + +Run: `mvn -pl ccdi-info-collection -am -DskipTests compile` +Expected: 新增类与 XML 能被正常加载,无编译错误 + +**Step 5: 提交** + +```bash +git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAssetInfoMapper.xml +git commit -m "新增亲属资产领域对象与映射" +``` + +### Task 3: 实现资产服务与导入服务 + +**Files:** +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\service\ICcdiAssetInfoService.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\service\ICcdiAssetInfoImportService.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\service\impl\CcdiAssetInfoServiceImpl.java` +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\service\impl\CcdiAssetInfoImportServiceImpl.java` + +**Step 1: 实现基础资产服务** + +- 查询当前亲属资产列表 +- 按归属键删除资产 +- 批量保存资产 +- 过滤空行并校验必填字段、数值、日期 + +**Step 2: 实现资产导入异步服务** + +- 初始化 Redis 状态 +- 解析 Excel 数据 +- 通过 `relation_cert_no` 反查亲属关系 +- 识别无法匹配和归属不唯一场景 +- 仅缓存失败记录 + +**Step 3: 明确 Redis Key 规则** + +- 状态 key:`import:assetInfo:{taskId}` +- 失败 key:`import:assetInfo:{taskId}:failures` + +**Step 4: 运行编译检查** + +Run: `mvn -pl ccdi-info-collection -am -DskipTests compile` +Expected: 服务接口与实现均编译通过 + +**Step 5: 提交** + +```bash +git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service +git commit -m "实现亲属资产服务与导入服务" +``` + +### Task 4: 扩展亲属关系 DTO 与 VO 聚合资产列表 + +**Files:** +- Modify: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\domain\dto\CcdiStaffFmyRelationAddDTO.java` +- Modify: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\domain\dto\CcdiStaffFmyRelationEditDTO.java` +- Modify: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\domain\vo\CcdiStaffFmyRelationVO.java` + +**Step 1: 为新增 DTO 增加 `assetInfoList`** + +- 类型使用 `List` +- 保持与前端子表数据结构一致 + +**Step 2: 为编辑 DTO 增加 `assetInfoList`** + +- 与新增 DTO 保持一致 +- 保留现有校验规则 + +**Step 3: 为详情 VO 增加 `assetInfoList`** + +- 类型使用 `List` +- 用于详情和编辑回显 + +**Step 4: 编译验证** + +Run: `mvn -pl ccdi-info-collection -am -DskipTests compile` +Expected: DTO、VO 依赖关系正常 + +**Step 5: 提交** + +```bash +git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiStaffFmyRelationAddDTO.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiStaffFmyRelationEditDTO.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiStaffFmyRelationVO.java +git commit -m "扩展亲属关系聚合资产字段" +``` + +### Task 5: 改造亲属关系服务聚合保存与详情查询 + +**Files:** +- Modify: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\service\impl\CcdiStaffFmyRelationServiceImpl.java` +- Check: `D:\ccdi\ccdi\ccdi-info-collection\src\main\resources\mapper\info\collection\CcdiStaffFmyRelationMapper.xml` + +**Step 1: 注入资产服务** + +- 在服务实现中注入 `ICcdiAssetInfoService` + +**Step 2: 改造详情查询** + +- 查询亲属关系主记录 +- 按 `personId + relationCertNo` 查询资产列表 +- 回填 `assetInfoList` + +**Step 3: 改造新增逻辑** + +- 保存亲属关系 +- 回填资产归属键 +- 批量保存资产 + +**Step 4: 改造编辑逻辑** + +- 查询旧记录 +- 校验证件类型、证件号码未被修改 +- 更新主记录 +- 删除旧资产 +- 保存新资产列表 + +**Step 5: 改造删除逻辑** + +- 根据待删 ID 先查询关系记录 +- 循环按 `family_id + person_id` 删除资产 +- 再批量删除亲属关系 + +**Step 6: 编译验证** + +Run: `mvn -pl ccdi-info-collection -am -DskipTests compile` +Expected: 亲属关系服务改造后可通过编译 + +**Step 7: 提交** + +```bash +git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffFmyRelationServiceImpl.java +git commit -m "改造亲属关系聚合保存亲属资产" +``` + +### Task 6: 新增资产导入控制器并接入下载模板与状态查询 + +**Files:** +- Create: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\controller\CcdiAssetInfoController.java` + +**Step 1: 添加模板下载接口** + +- `POST /ccdi/assetInfo/importTemplate` + +**Step 2: 添加导入接口** + +- `POST /ccdi/assetInfo/importData` +- 解析 Excel 后提交异步任务 + +**Step 3: 添加状态与失败记录接口** + +- `GET /ccdi/assetInfo/importStatus/{taskId}` +- `GET /ccdi/assetInfo/importFailures/{taskId}` + +**Step 4: 核对权限标识** + +- 使用 `ccdi:staffFmyRelation:import` 还是新增独立权限 +- 若采用独立权限,记录需同步补菜单 SQL + +**Step 5: 编译验证** + +Run: `mvn -pl ccdi-info-collection -am -DskipTests compile` +Expected: 控制器注册正常 + +**Step 6: 提交** + +```bash +git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiAssetInfoController.java +git commit -m "新增亲属资产导入控制器" +``` + +### Task 7: 补充亲属关系编辑防御校验 + +**Files:** +- Modify: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\service\impl\CcdiStaffFmyRelationServiceImpl.java` + +**Step 1: 查询旧记录** + +- 编辑保存前按 `id` 查询旧关系 + +**Step 2: 比较证件类型与证件号码** + +- 若值发生变化,抛出业务异常 + +**Step 3: 明确错误文案** + +- 返回“关系人证件类型/证件号码不允许修改” + +**Step 4: 编译验证** + +Run: `mvn -pl ccdi-info-collection -am -DskipTests compile` +Expected: 校验逻辑编译通过 + +**Step 5: 提交** + +```bash +git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffFmyRelationServiceImpl.java +git commit -m "限制编辑亲属证件信息变更" +``` + +### Task 8: 执行后端回归验证 + +**Files:** +- Check: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\controller\CcdiStaffFmyRelationController.java` +- Check: `D:\ccdi\ccdi\ccdi-info-collection\src\main\java\com\ruoyi\info\collection\controller\CcdiAssetInfoController.java` + +**Step 1: 编译后端模块** + +Run: `mvn -pl ccdi-info-collection -am clean compile` +Expected: BUILD SUCCESS + +**Step 2: 启动应用后手工验证接口** + +Run: `mvn -pl ruoyi-admin -am spring-boot:run` +Expected: 应用可正常启动 + +**Step 3: 验证关键场景** + +- 查询亲属关系详情返回 `assetInfoList` +- 新增/编辑亲属关系能保存资产 +- 删除亲属关系后资产被同步删除 +- 亲属资产导入可生成任务状态和失败记录 + +**Step 4: 整理验证记录** + +- 将实际验证结果补充到开发记录或 PR 描述 + +**Step 5: 提交** + +```bash +git add . +git commit -m "完成亲属资产后端联调验证" +``` diff --git a/docs/plans/2026-03-12-staff-family-asset-maintenance-design.md b/docs/plans/2026-03-12-staff-family-asset-maintenance-design.md new file mode 100644 index 0000000..2808c28 --- /dev/null +++ b/docs/plans/2026-03-12-staff-family-asset-maintenance-design.md @@ -0,0 +1,332 @@ +# 员工亲属资产维护设计 + +## 背景 + +现有员工亲属关系维护页面 `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` + +## 测试建议 + +- 新增亲属关系但不维护资产 +- 新增亲属关系并维护单条、多条资产 +- 编辑亲属关系时新增、修改、删除资产 +- 验证编辑时不能修改亲属证件类型与证件号码 +- 删除亲属关系时资产级联删除 +- 亲属资产导入成功、无法匹配、匹配不唯一三类场景 diff --git a/docs/plans/2026-03-12-staff-family-asset-maintenance-frontend-implementation.md b/docs/plans/2026-03-12-staff-family-asset-maintenance-frontend-implementation.md new file mode 100644 index 0000000..222402a --- /dev/null +++ b/docs/plans/2026-03-12-staff-family-asset-maintenance-frontend-implementation.md @@ -0,0 +1,314 @@ +# 员工亲属资产维护前端实施计划 + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** 在员工亲属关系维护页面中增加亲属资产的可视化维护、详情展示和资产导入交互能力。 + +**Architecture:** 保持 `ccdiStaffFmyRelation` 为唯一页面入口,在现有新增、编辑、详情弹窗中扩展亲属资产子表,并新增独立的亲属资产导入状态、弹窗和失败记录视图。资产归属字段不在前端暴露,提交时仅上传资产业务字段列表。 + +**Tech Stack:** Vue 2, Element UI, 若依前端脚手架, Axios request 封装 + +--- + +### Task 1: 扩展前端 API 封装资产导入与聚合保存字段 + +**Files:** +- Modify: `D:\ccdi\ccdi\ruoyi-ui\src\api\ccdiStaffFmyRelation.js` +- Create: `D:\ccdi\ccdi\ruoyi-ui\src\api\ccdiAssetInfo.js` + +**Step 1: 保持亲属关系 API 支持传递 `assetInfoList`** + +- `addRelation` +- `updateRelation` +- `getRelation` + +**Step 2: 新增资产导入 API 文件** + +- 下载模板 +- 提交导入 +- 查询状态 +- 查询失败记录 + +**Step 3: 自查接口路径** + +- 使用 `/ccdi/assetInfo/*` +- 与现有 `staffFmyRelation` API 区分清楚 + +**Step 4: 运行构建检查** + +Run: `npm run build:prod` +Expected: API 引用路径无语法错误 + +**Step 5: 提交** + +```bash +git add ruoyi-ui/src/api/ccdiStaffFmyRelation.js ruoyi-ui/src/api/ccdiAssetInfo.js +git commit -m "新增亲属资产前端接口封装" +``` + +### Task 2: 扩展亲属关系表单模型与重置逻辑 + +**Files:** +- Modify: `D:\ccdi\ccdi\ruoyi-ui\src\views\ccdiStaffFmyRelation\index.vue` + +**Step 1: 为 `form` 增加 `assetInfoList`** + +- 默认值设为空数组 +- 重置时同步清空 + +**Step 2: 处理详情与编辑回显** + +- `getRelation` 返回后回填 `assetInfoList` +- 保证空值时回退为 `[]` + +**Step 3: 在提交前过滤空资产行** + +- 仅保留有实际内容的资产 +- 不在前端传 `familyId`、`personId` + +**Step 4: 本地验证** + +Run: `npm run build:prod` +Expected: 页面脚本编译通过 + +**Step 5: 提交** + +```bash +git add ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue +git commit -m "扩展亲属关系表单资产模型" +``` + +### Task 3: 在新增/编辑弹窗中加入亲属资产子表 + +**Files:** +- Modify: `D:\ccdi\ccdi\ruoyi-ui\src\views\ccdiStaffFmyRelation\index.vue` + +**Step 1: 新增“亲属资产信息”分区** + +- 放在基本信息下方 +- 右侧增加“新增资产”按钮 + +**Step 2: 渲染可编辑子表** + +- 字段包含资产大类、资产小类、资产名称、产权占比、购买/评估日期、资产原值、当前估值、估值截止日期、资产状态、备注、操作 + +**Step 3: 支持资产行增删** + +- 新增空白行 +- 删除当前行 + +**Step 4: 对新增资产按钮加前置限制** + +- 新增模式下未填写 `relationCertType` 或 `relationCertNo` 时禁用 +- 提示“请先填写关系人证件信息” + +**Step 5: 构建验证** + +Run: `npm run build:prod` +Expected: 模板与脚本通过编译 + +**Step 6: 提交** + +```bash +git add ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue +git commit -m "新增亲属资产编辑子表" +``` + +### Task 4: 锁定编辑场景下的亲属证件字段 + +**Files:** +- Modify: `D:\ccdi\ccdi\ruoyi-ui\src\views\ccdiStaffFmyRelation\index.vue` + +**Step 1: 将 `relationCertType` 在编辑场景下置灰** + +- `:disabled="!isAdd"` + +**Step 2: 将 `relationCertNo` 在编辑场景下置灰** + +- `:disabled="!isAdd"` + +**Step 3: 核对员工身份证号选择器** + +- 保持当前新增可选、编辑禁改逻辑 + +**Step 4: 构建验证** + +Run: `npm run build:prod` +Expected: 字段禁用逻辑无模板错误 + +**Step 5: 提交** + +```bash +git add ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue +git commit -m "锁定亲属证件字段编辑能力" +``` + +### Task 5: 在详情弹窗展示亲属资产信息 + +**Files:** +- Modify: `D:\ccdi\ccdi\ruoyi-ui\src\views\ccdiStaffFmyRelation\index.vue` + +**Step 1: 增加详情分区** + +- 标题为“亲属资产信息” + +**Step 2: 使用只读表格展示资产** + +- 展示关键资产字段 +- 不展示归属键和主键 + +**Step 3: 增加空状态** + +- 无资产时显示“暂无亲属资产信息” + +**Step 4: 构建验证** + +Run: `npm run build:prod` +Expected: 详情模板渲染通过 + +**Step 5: 提交** + +```bash +git add ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue +git commit -m "新增亲属资产详情展示" +``` + +### Task 6: 新增亲属资产导入入口与状态管理 + +**Files:** +- Modify: `D:\ccdi\ccdi\ruoyi-ui\src\views\ccdiStaffFmyRelation\index.vue` + +**Step 1: 在按钮区新增入口** + +- “导入亲属资产信息” +- “查看亲属资产导入失败记录” + +**Step 2: 新增独立上传弹窗状态** + +- `assetUpload` +- `assetImportPollingTimer` +- `assetCurrentTaskId` + +**Step 3: 新增独立 localStorage key** + +- 例如 `staff_fmy_asset_import_last_task` + +**Step 4: 新增资产导入失败记录弹窗与分页状态** + +- 与现有亲属关系导入分开维护 + +**Step 5: 构建验证** + +Run: `npm run build:prod` +Expected: 导入状态变量与模板绑定正常 + +**Step 6: 提交** + +```bash +git add ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue +git commit -m "新增亲属资产导入交互状态" +``` + +### Task 7: 接通资产导入上传、轮询与失败记录查询 + +**Files:** +- Modify: `D:\ccdi\ccdi\ruoyi-ui\src\views\ccdiStaffFmyRelation\index.vue` +- Check: `D:\ccdi\ccdi\ruoyi-ui\src\api\ccdiAssetInfo.js` + +**Step 1: 实现模板下载** + +- 调用资产导入模板接口 + +**Step 2: 实现上传成功回调** + +- 校验返回的 `taskId` +- 保存任务状态 +- 启动轮询 + +**Step 3: 实现轮询完成处理** + +- 根据成功/失败数展示通知 +- 刷新页面列表 +- 控制失败记录按钮显示 + +**Step 4: 实现失败记录查询** + +- 独立调用资产失败记录接口 +- 处理记录过期和网络错误提示 + +**Step 5: 构建验证** + +Run: `npm run build:prod` +Expected: 资产导入流程相关方法通过编译 + +**Step 6: 提交** + +```bash +git add ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue +git commit -m "接通亲属资产导入轮询与失败记录" +``` + +### Task 8: 调整样式与交互可读性 + +**Files:** +- Modify: `D:\ccdi\ccdi\ruoyi-ui\src\views\ccdiStaffFmyRelation\index.vue` + +**Step 1: 为资产分区补样式** + +- 表格区间距 +- 空状态样式 +- 分区标题样式 + +**Step 2: 检查弹窗宽度** + +- 保证新增/编辑/详情在资产表加入后仍可读 + +**Step 3: 检查移动端/窄屏降级** + +- 避免列宽完全挤压 + +**Step 4: 构建验证** + +Run: `npm run build:prod` +Expected: 样式变更不影响构建 + +**Step 5: 提交** + +```bash +git add ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue +git commit -m "优化亲属资产页面样式与布局" +``` + +### Task 9: 执行前端联调验证 + +**Files:** +- Check: `D:\ccdi\ccdi\ruoyi-ui\src\views\ccdiStaffFmyRelation\index.vue` + +**Step 1: 运行生产构建** + +Run: `cd ruoyi-ui && npm run build:prod` +Expected: 构建成功 + +**Step 2: 启动前端开发环境** + +Run: `cd ruoyi-ui && npm run dev` +Expected: 本地页面可访问 + +**Step 3: 手工验证页面场景** + +- 新增亲属关系并添加资产 +- 编辑亲属关系并维护资产 +- 验证证件类型、证件号码禁改 +- 查看详情资产区 +- 触发亲属资产导入和失败记录查看 + +**Step 4: 整理验证结果** + +- 记录已验证场景和遗留问题 + +**Step 5: 提交** + +```bash +git add . +git commit -m "完成亲属资产前端联调验证" +```