diff --git a/docs/plans/backend/2026-04-23-staff-family-enterprise-relation-backend-implementation.md b/docs/plans/backend/2026-04-23-staff-family-enterprise-relation-backend-implementation.md new file mode 100644 index 00000000..cfe70962 --- /dev/null +++ b/docs/plans/backend/2026-04-23-staff-family-enterprise-relation-backend-implementation.md @@ -0,0 +1,174 @@ +# 员工亲属实体关联维护后端实施计划 + +> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 将现有员工实体关联后端链路切换为员工亲属实体关联,支持亲属维度查询展示、有效亲属校验、亲属下拉搜索、异步导入,以及亲属关系失效时自动把对应实体关联置为无效。 + +**Architecture:** 保留现有 `CcdiStaffEnterpriseRelation` 模块和 `ccdi_staff_enterprise_relation` 表,不新增平行模块或新表。查询链路改为 `ccdi_staff_enterprise_relation -> ccdi_staff_fmy_relation -> ccdi_base_staff`,新增和导入统一以有效员工亲属为准入条件,失效联动放在员工亲属关系保存事务内处理。 + +**Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus, Redis, EasyExcel, JUnit 5, MySQL, Markdown + +--- + +## 文件结构与职责 + +**员工亲属实体关联主链路** + +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiStaffEnterpriseRelationController.java` + 继续作为实体关联对外入口,补亲属下拉搜索接口,调整列表/详情/导入文案为亲属语义。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiStaffEnterpriseRelationService.java` + 补亲属下拉查询方法定义。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffEnterpriseRelationServiceImpl.java` + 负责列表、详情、新增、编辑、删除、导入任务提交,核心改动是把合法性校验从员工基础信息切到员工亲属关系。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiStaffEnterpriseRelationImportService.java` + 保持异步导入接口不变,只切换导入校验语义。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffEnterpriseRelationImportServiceImpl.java` + 调整导入校验、失败原因和导入日志文案,改为按有效亲属校验并回填亲属名称。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiStaffEnterpriseRelationMapper.java` + 补亲属下拉查询、按亲属身份证批量置无效的方法声明。 +- `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiStaffEnterpriseRelationMapper.xml` + 调整列表/详情 SQL,增加亲属名称、关联员工字段映射与亲属下拉查询 SQL。 + +**实体关联契约对象** + +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiStaffEnterpriseRelationQueryDTO.java` + 查询条件切到亲属语义,承接亲属身份证、亲属名称、关联员工、统一社会信用代码、企业名称、状态。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiStaffEnterpriseRelationAddDTO.java` + 保持 `personId + socialCreditCode` 主键语义,但 `personId` 改为亲属身份证号。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiStaffEnterpriseRelationEditDTO.java` + 保持编辑主键不可变。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiStaffEnterpriseRelationVO.java` + 补亲属名称、关联员工身份证、关联员工姓名字段,移除旧的员工本人姓名语义。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/StaffEnterpriseRelationImportFailureVO.java` + 补亲属名称字段,失败记录切到亲属语义。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiStaffEnterpriseRelationOptionVO.java` + 新增亲属下拉返回对象,承接亲属身份证、亲属名称、关联员工身份证、关联员工姓名。 +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffEnterpriseRelationExcel.java` + 模板标题与字段注释切换为亲属语义。 + +**员工亲属关系联动链路** + +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffFmyRelationServiceImpl.java` + 在亲属状态从有效变为无效时,联动调用实体关联 Mapper 把该亲属名下关联记录批量置无效。 + +**测试** + +- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiStaffEnterpriseRelationServiceImplTest.java` + 覆盖新增、编辑、亲属下拉查询和无效亲属拦截。 +- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiStaffEnterpriseRelationImportServiceImplTest.java` + 覆盖导入成功、亲属不存在失败、亲属无效失败、库内重复失败、Excel 内重复失败。 +- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiStaffFmyRelationServiceImplTest.java` + 增补亲属状态改无效后,实体关联自动改无效的事务联动测试。 +- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiStaffEnterpriseRelationMapperTest.java` + 覆盖列表 SQL 结果映射、亲属下拉查询与批量置无效 SQL。 + +## 实施任务 + +### Task 1: 调整实体关联 DTO / VO / Excel 契约为亲属语义 + +**Files:** + +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiStaffEnterpriseRelationQueryDTO.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiStaffEnterpriseRelationAddDTO.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiStaffEnterpriseRelationEditDTO.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiStaffEnterpriseRelationVO.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/StaffEnterpriseRelationImportFailureVO.java` +- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiStaffEnterpriseRelationOptionVO.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffEnterpriseRelationExcel.java` +- Reference: `docs/superpowers/specs/2026-04-23-staff-family-enterprise-relation-design.md` + +- [ ] 更新 QueryDTO 字段,新增 `relationName`、`staffPersonName`,保留 `personId` 但注释明确为亲属身份证号。 +- [ ] 更新 AddDTO / EditDTO 注释和校验提示,把所有“身份证号”语义改为“亲属身份证号”。 +- [ ] 在 VO 中增加 `relationName`、`staffPersonId`、`staffPersonName`,移除或停用旧 `personName` 员工本人语义。 +- [ ] 新建下拉 VO,字段至少包含 `relationCertNo`、`relationName`、`staffPersonId`、`staffPersonName`。 +- [ ] 调整 Excel 导入对象标题、注释和列头说明,保证“身份证号”明确指亲属身份证号。 + +### Task 2: 改造 Mapper 查询链路与亲属下拉 SQL + +**Files:** + +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiStaffEnterpriseRelationMapper.java` +- Modify: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiStaffEnterpriseRelationMapper.xml` +- Reference: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiStaffFmyRelationMapper.xml` + +- [ ] 在 Mapper 接口中新增 `selectFamilyOptions(query)` 方法,返回 `CcdiStaffEnterpriseRelationOptionVO` 列表。 +- [ ] 在 Mapper 接口中新增 `invalidateByFamilyCertNo(personId)` 批量置无效方法。 +- [ ] 重写列表 SQL,按 `ser.person_id = sfr.relation_cert_no` 回补 `relation_name`、`staff_person_id`、`staff_person_name`。 +- [ ] 重写详情 SQL,确保详情回显与列表字段口径完全一致。 +- [ ] 给查询区补动态条件:亲属身份证号、亲属名称、关联员工、统一社会信用代码、企业名称、状态。 +- [ ] 实现亲属下拉 SQL,仅返回 `is_emp_family = 1 and status = 1` 的有效亲属,并支持 `relation_cert_no` 模糊匹配。 + +### Task 3: 改造 Service / Controller 的查询、新增、编辑与下拉搜索 + +**Files:** + +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiStaffEnterpriseRelationService.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffEnterpriseRelationServiceImpl.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiStaffEnterpriseRelationController.java` +- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiBaseStaffController.java` + +- [ ] 在 Service 接口中新增亲属下拉查询方法定义。 +- [ ] 在 ServiceImpl 中新增“按亲属身份证查询有效亲属关系”的私有校验方法,统一给新增和导入复用。 +- [ ] 将新增逻辑从“校验员工身份证存在”改为“校验有效亲属存在”,失败时返回亲属语义错误提示。 +- [ ] 保持编辑逻辑中 `personId` 和 `socialCreditCode` 不可修改,只切换错误文案为亲属语义。 +- [ ] 在 Controller 中新增亲属下拉搜索接口,建议路径为 `/familyOptions`。 +- [ ] 调整导入模板接口标题、列表/详情 Swagger 注释和日志标题,全部切换为“员工亲属实体关联”口径。 + +### Task 4: 改造异步导入校验与失败记录 + +**Files:** + +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffEnterpriseRelationImportServiceImpl.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiStaffEnterpriseRelationImportService.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/StaffEnterpriseRelationImportFailureVO.java` +- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffFmyRelationImportServiceImpl.java` + +- [ ] 去掉当前导入里对 `ccdi_base_staff` 的存在性校验,改为批量查询有效员工亲属。 +- [ ] 批量缓存有效亲属集合,避免导入时逐行查库。 +- [ ] 对亲属不存在、亲属无效、库内重复、Excel 内重复分别生成明确失败原因。 +- [ ] 在失败记录 VO 中回填亲属名称,便于前端失败弹窗展示。 +- [ ] 更新导入日志标题和 Redis 提示文案,统一为亲属实体关联口径。 + +### Task 5: 在员工亲属关系保存链路中加入失效联动 + +**Files:** + +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffFmyRelationServiceImpl.java` +- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiStaffEnterpriseRelationMapper.java` +- Modify: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiStaffEnterpriseRelationMapper.xml` + +- [ ] 在 `CcdiStaffFmyRelationServiceImpl.updateRelation` 中保留旧记录查询,识别“有效 -> 无效”状态变更。 +- [ ] 注入 `CcdiStaffEnterpriseRelationMapper`,在状态收缩时按 `relation_cert_no` 批量更新实体关联 `status = 0`。 +- [ ] 保证该联动与亲属关系更新处于同一事务内,避免亲属已失效但实体关联仍有效。 +- [ ] 不实现“无效 -> 有效”反向恢复,严格遵守设计范围。 + +### Task 6: 补后端测试与验证命令 + +**Files:** + +- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiStaffEnterpriseRelationServiceImplTest.java` +- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiStaffEnterpriseRelationImportServiceImplTest.java` +- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiStaffFmyRelationServiceImplTest.java` +- Modify or Create: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiStaffEnterpriseRelationMapperTest.java` + +- [ ] 为新增接口补“有效亲属可新增、无效亲属不可新增、亲属不存在不可新增”三组测试。 +- [ ] 为列表查询补“能回填亲属名称和关联员工”的 SQL 映射测试。 +- [ ] 为亲属下拉补“只返回有效员工亲属且支持身份证模糊搜索”的测试。 +- [ ] 为导入补“成功、亲属不存在失败、亲属无效失败、库内重复、文件内重复”五组测试。 +- [ ] 为员工亲属关系状态变更补“有效改无效后自动将实体关联置无效”的事务测试。 + +## 验证命令 + +```bash +mvn -pl ccdi-info-collection -am -Dtest=CcdiStaffEnterpriseRelationServiceImplTest,CcdiStaffEnterpriseRelationImportServiceImplTest,CcdiStaffFmyRelationServiceImplTest,CcdiStaffEnterpriseRelationMapperTest test +mvn -pl ccdi-info-collection -am -DskipTests compile +``` + +## 完成标准 + +- 列表和详情返回亲属身份证、亲属名称、关联员工字段 +- 新增和导入只允许使用有效员工亲属 +- 亲属下拉搜索接口可按身份证模糊查询有效亲属 +- 导入失败记录可展示亲属名称和亲属语义错误原因 +- 亲属关系从有效改为无效后,对应实体关联自动改为无效 +- 后端定向测试和编译命令可通过 diff --git a/docs/plans/frontend/2026-04-23-staff-family-enterprise-relation-frontend-implementation.md b/docs/plans/frontend/2026-04-23-staff-family-enterprise-relation-frontend-implementation.md new file mode 100644 index 00000000..7a79cb72 --- /dev/null +++ b/docs/plans/frontend/2026-04-23-staff-family-enterprise-relation-frontend-implementation.md @@ -0,0 +1,129 @@ +# 员工亲属实体关联维护前端实施计划 + +> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 将现有员工实体关联前端页面切换为员工亲属实体关联页面,支持亲属身份证模糊搜索下拉、自动带出亲属名称和关联员工、亲属维度列表展示、异步导入与失败记录查看,并完成真实页面测试。 + +**Architecture:** 继续沿用现有 `ccdiStaffEnterpriseRelation/index.vue` 单页实现,不新建平行页面。前端只改字段语义、查询区、列表列、编辑弹窗和导入文案;下拉搜索改为请求新的有效亲属接口,页面验证继续复用现有导入轮询与失败记录交互骨架。 + +**Tech Stack:** Vue 2, Element UI, JavaScript, npm, nvm, Playwright, Markdown + +--- + +## 文件结构与职责 + +**前端页面与 API** + +- `ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue` + 员工亲属实体关联主页面,负责查询区、表格、详情、编辑弹窗、亲属下拉搜索、导入轮询和失败记录弹窗。 +- `ruoyi-ui/src/api/ccdiStaffEnterpriseRelation.js` + 继续封装实体关联接口,新增亲属下拉搜索接口方法。 + +**真实页面测试产物** + +- `output/playwright/` + 保存浏览器测试截图、录屏或导出文件,不纳入 git。 +- `output/spreadsheet/` + 保存从真实页面模板生成的导入测试文件,不纳入 git。 + +**测试记录** + +- `docs/tests/records/2026-04-23-staff-family-enterprise-relation-browser-test-record.md` + 实施阶段记录真实页面测试步骤、样本和结果。 + +## 实施任务 + +### Task 1: 调整前端 API 契约为亲属语义 + +**Files:** + +- Modify: `ruoyi-ui/src/api/ccdiStaffEnterpriseRelation.js` +- Reference: `ruoyi-ui/src/api/ccdiBaseStaff.js` + +- [ ] 保留现有列表、详情、新增、编辑、删除、导入、状态查询、失败记录接口方法。 +- [ ] 新增亲属下拉接口方法,建议命名为 `listFamilyOptions(query)`,请求后端 `/ccdi/staffEnterpriseRelation/familyOptions`。 +- [ ] 调整接口注释,把“员工实体关系”全部改成“员工亲属实体关联”。 +- [ ] 保持导入接口和轮询接口签名不变,避免页面额外重构。 + +### Task 2: 重构查询区、列表和详情展示 + +**Files:** + +- Modify: `ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue` +- Reference: `docs/superpowers/specs/2026-04-23-staff-family-enterprise-relation-design.md` + +- [ ] 将查询区字段调整为亲属身份证号、亲属名称、关联员工、统一社会信用代码、企业名称、状态。 +- [ ] 将列表列调整为亲属身份证、亲属名称、关联员工、企业名称、关联人在企业的职务、状态、数据来源、创建时间。 +- [ ] 将“关联员工”格式化为 `员工姓名(员工身份证号)`,避免只显示姓名。 +- [ ] 详情弹窗基础信息改为亲属口径,移除旧的员工本人姓名展示。 +- [ ] 所有标题、按钮文案、空提示、通知文案统一切换为“员工亲属实体关联”。 + +### Task 3: 改造新增/编辑弹窗为亲属下拉选择 + +**Files:** + +- Modify: `ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue` + +- [ ] 将现有 `searchStaff` / `staffOptions` 逻辑替换为亲属下拉逻辑,例如 `searchFamilyOptions` / `familyOptions`。 +- [ ] 下拉项展示为“亲属身份证号 + 亲属名称 / 关联员工姓名”。 +- [ ] 选中亲属后,自动回填并只读展示亲属名称、关联员工。 +- [ ] 编辑态下保持亲属身份证号不可改,统一社会信用代码不可改。 +- [ ] 将表单规则中的身份证号提示改为亲属身份证号提示。 + +### Task 4: 调整导入模板、轮询与失败记录展示 + +**Files:** + +- Modify: `ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue` + +- [ ] 导入弹窗标题改为“员工亲属实体关联数据导入”。 +- [ ] 模板下载文件名改为亲属实体关联口径。 +- [ ] 导入结果通知和失败提示改为亲属语义。 +- [ ] 将本地缓存 key 从旧语义改成新的独立 key,例如 `staff_family_enterprise_relation_import_last_task`,避免与历史员工语义缓存混淆。 +- [ ] 失败记录表格调整为亲属身份证号、亲属名称、企业名称、统一社会信用代码、失败原因。 +- [ ] 保留现有轮询节奏和失败记录清理按钮,不增加额外交互分支。 + +### Task 5: 补页面级验证与格式化细节 + +**Files:** + +- Modify: `ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue` + +- [ ] 更新 `reset()` 初始化结构,增加 `relationName`、`staffPersonId`、`staffPersonName` 只读回显字段。 +- [ ] 提交前保持最短路径,不额外引入转换层,只剔除展示态字段或在提交前做最小数据拷贝。 +- [ ] 对失败记录、详情弹窗和表格统一复用同一组字段格式化逻辑,避免页面口径分裂。 +- [ ] 确认页面在桌面端与常见笔记本分辨率下不出现标题换行、按钮挤压和表格列错位。 + +### Task 6: 执行前端构建与真实页面测试 + +**Files:** + +- Create: `docs/tests/records/2026-04-23-staff-family-enterprise-relation-browser-test-record.md` +- Output only: `output/playwright/` +- Output only: `output/spreadsheet/` + +- [ ] 先在 `ruoyi-ui` 目录执行 `source ~/.nvm/nvm.sh && nvm use`,确认 Node 版本符合仓库要求。 +- [ ] 执行 `npm run build:prod`,确认前端构建通过。 +- [ ] 启动真实前端页面后,使用 Playwright 打开实际业务页面 `ccdiStaffEnterpriseRelation`,禁止使用 prototype 页面。 +- [ ] 在真实页面验证查询、新增、编辑、删除、详情、导入入口、失败记录入口。 +- [ ] 导入测试必须先从页面下载当前模板,再基于模板在 `output/spreadsheet/` 生成测试文件。 +- [ ] 覆盖至少三类导入样本:有效亲属成功导入、无效亲属失败、亲属不存在失败。 +- [ ] 记录页面提示、导入状态变化、失败记录弹窗内容与列表状态是否正确。 +- [ ] 测试完成后关闭本轮启动的前后端进程,并确保 `output/` 测试文件不纳入 git。 + +## 验证命令 + +```bash +cd /Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui +source ~/.nvm/nvm.sh && nvm use +npm run build:prod +``` + +## 完成标准 + +- 查询区、列表和详情全部切换为亲属语义 +- 新增弹窗可按亲属身份证模糊搜索有效亲属,并自动带出亲属名称和关联员工 +- 编辑态保持亲属身份证号和统一社会信用代码不可修改 +- 导入弹窗、模板文件名、轮询通知和失败记录全部切换为亲属语义 +- 本地缓存 key 与历史员工语义隔离 +- 已完成 `nvm` 切换、前端构建和 Playwright 真实页面测试