# 员工实体关系添加员工名称字段设计 ## 1. 需求概述 在员工实体关系列表和详情中添加员工名称字段,通过身份证号(personId)关联员工信息表(ccdi_base_staff)获取姓名。 **涉及模块:** 员工实体关系 (ccdi_staff_enterprise_relation) **展示位置:** - 列表页面 (table 列) - 详情接口返回 **数据来源:** 通过 personId 关联 ccdi_base_staff 表的 id_card 字段获取 name 字段 **空值处理:** 当 personId 在员工信息表中不存在时,显示为空 ## 2. 技术方案 采用 MyBatis 关联查询(JOIN)方式,在查询时动态获取员工姓名,不修改表结构。 ### 2.1 优势 - ✅ 无需修改数据库表结构 - ✅ 数据始终与员工信息表同步 - ✅ 实施简单,风险低 - ✅ 性能影响可控 ## 3. 数据库层设计 ### 3.1 SQL查询改造 在 `CcdiStaffEnterpriseRelationMapper.xml` 中修改列表查询和详情查询: ```sql SELECT ser.id, ser.person_id, bs.name AS person_name, -- 通过JOIN获取员工姓名 ser.relation_person_post, ser.social_credit_code, ser.enterprise_name, ser.status, ser.remark, ser.data_source, ser.is_employee, ser.is_emp_family, ser.is_customer, ser.is_cust_family, ser.create_time, ser.update_time, ser.created_by, ser.updated_by FROM ccdi_staff_enterprise_relation ser LEFT JOIN ccdi_base_staff bs ON ser.person_id = bs.id_card WHERE ser.status = 1 ``` ### 3.2 关键点 - 使用 `LEFT JOIN` 确保即使员工信息不存在,关系记录也会返回 - 当 `personId` 在 `ccdi_base_staff` 中不存在时,`person_name` 为 NULL - 数据库表结构不需要修改 ### 3.3 索引优化 确保 `ccdi_base_staff.id_card` 字段有索引: ```sql -- 检查索引 SHOW INDEX FROM ccdi_base_staff WHERE Key_name = 'idx_id_card'; -- 如果没有索引,创建 CREATE INDEX idx_id_card ON ccdi_base_staff(id_card); ``` ## 4. 后端代码层设计 ### 4.1 VO层修改 **文件:** `ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/vo/CcdiStaffEnterpriseRelationVO.java` ```java /** 身份证号 */ @Schema(description = "身份证号") private String personId; /** 员工姓名 */ @Schema(description = "员工姓名") private String personName; /** 关联人在企业的职务 */ @Schema(description = "关联人在企业的职务") private String relationPersonPost; ``` ### 4.2 Mapper接口 **文件:** `ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiStaffEnterpriseRelationMapper.xml` 修改查询方法,添加 LEFT JOIN: ```xml ``` 同样修改 `selectRelationById` 方法。 ### 4.3 Service层 `ICcdiStaffEnterpriseRelationService.java` 和实现类无需大改,MyBatis Plus 会自动填充 JOIN 的字段。 ## 5. 前端代码层设计 ### 5.1 列表页面修改 **文件:** `ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue` 在表格列定义中添加员工姓名列: ```vue ``` **位置建议:** 放在"身份证号"列之后,方便用户对照查看 ### 5.2 API接口 **文件:** `ruoyi-ui/src/api/ccdiStaffEnterpriseRelation.js` 无需修改,接口会自动返回新增的 `personName` 字段。 ### 5.3 详情页面 如果存在详情对话框,同样添加员工姓名显示: ```vue {{ form.personId }} {{ form.personName }} {{ form.relationPersonPost }} ``` ## 6. 错误处理和边界情况 ### 6.1 数据空值处理 - **场景**: personId 在 `ccdi_base_staff` 表中不存在 - **处理**: `personName` 为 NULL,前端显示为空字符串 - **前端展示**: Element UI table 会自动将 null 显示为空 ### 6.2 数据一致性 - **场景**: 员工信息表的姓名后续被修改 - **影响**: 下次查询时自动获取最新姓名,无需同步 - **优势**: JOIN 方案天然保证数据一致性 ### 6.3 性能考虑 - **索引**: 确保 `ccdi_base_staff.id_card` 字段有索引 - **查询优化**: LEFT JOIN 对性能影响较小 - **分页**: 已有分页机制,单页数据量有限 ### 6.4 特殊字符处理 - 员工姓名可能包含特殊字符,MyBatis 和 JSON 序列化会自动处理 - 无需额外转义逻辑 ## 7. 测试策略 ### 7.1 单元测试 创建测试用例覆盖以下场景: ```java // 测试场景1: 员工信息存在 assertEquals("张三", result.getPersonName()); // 测试场景2: 员工信息不存在 assertNull(result.getPersonName()); // 测试场景3: 姓名包含特殊字符 assertEquals("张三·李四", result.getPersonName()); // 测试场景4: 批量数据性能测试 List list = mapper.selectRelationList(query); assertTrue(list.size() > 0); ``` ### 7.2 接口测试 使用测试脚本验证: - 列表接口返回 `personName` 字段 - 详情接口返回 `personName` 字段 - 分页查询正常工作 - 空值处理正确 ### 7.3 前端测试 手动验证: - 列表页面正确显示员工姓名 - 空值显示为空 - 列表排序、筛选功能正常 ### 7.4 数据准备测试 准备测试数据: - 已有员工的关系记录 - 无对应员工的关系记录 - 批量数据的性能测试 ## 8. 实施步骤 ### 步骤1: 修改 VO 类 - 文件: `CcdiStaffEnterpriseRelationVO.java` - 添加 `personName` 字段及注解 ### 步骤2: 修改 Mapper XML - 文件: `CcdiStaffEnterpriseRelationMapper.xml` - 修改列表查询和详情查询,添加 LEFT JOIN ### 步骤3: 修改前端列表页 - 文件: `ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue` - 在表格中添加员工姓名列 ### 步骤4: 检查数据库索引 - 检查 `ccdi_base_staff.id_card` 是否有索引 - 如果没有,执行创建索引 SQL ### 步骤5: 测试验证 - 运行后端,测试接口返回 - 运行前端,验证页面显示 - 生成测试报告 ### 步骤6: 更新文档 - 更新 API 文档 - 更新数据库设计文档 ## 9. 影响范围 **修改文件:** - 后端: 2个文件 (VO + Mapper XML) - 前端: 1个文件 (列表页面) - 数据库: 0个表结构修改 **涉及模块:** - 员工实体关系 (ccdi_staff_enterprise_relation) **风险评估:** - 低风险: 仅查询层面的改动,不影响数据写入 - 性能影响可控: 通过索引优化 - 兼容性好: 新增字段不影响现有功能 ## 10. 后续优化建议 ### 10.1 缓存优化 如果员工信息表数据量大且变动不频繁,可以考虑: - 使用 Redis 缓存员工信息 - 减少数据库查询次数 ### 10.2 搜索增强 可以支持按员工姓名搜索关系记录: - 在查询条件中添加姓名搜索 - 需要修改查询 DTO 和 Mapper XML ### 10.3 其他模块 如果其他模块也有类似需求,可以复用此方案: - 员工亲属关系 (ccdi_staff_fmy_relation) - 已有 personName 字段 - 员工招聘 (ccdi_staff_recruitment) - 员工调动 (ccdi_staff_transfer)