Files
ccdi/doc/plans/2026-02-11-staff-enterprise-relation-person-name-design.md
wkc fd9e208fa3 docs(staff-enterprise-relation): 更新API文档,添加员工姓名字段说明
- 新增员工实体关系管理API文档
- 在列表接口和详情接口响应中添加personName字段
- 说明personName通过LEFT JOIN ccdi_base_staff表获取
- 如果personId在员工信息表中不存在,personName为null
2026-02-11 15:27:40 +08:00

8.0 KiB

员工实体关系添加员工名称字段设计

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 中修改列表查询和详情查询:

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 确保即使员工信息不存在,关系记录也会返回
  • personIdccdi_base_staff 中不存在时,person_name 为 NULL
  • 数据库表结构不需要修改

3.3 索引优化

确保 ccdi_base_staff.id_card 字段有索引:

-- 检查索引
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

/** 身份证号 */
@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:

<select id="selectRelationList" resultType="CcdiStaffEnterpriseRelationVO">
    SELECT
        ser.id,
        ser.person_id,
        bs.name AS person_name,
        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>
        <if test="personId != null and personId != ''">
            AND ser.person_id LIKE CONCAT('%', #{personId}, '%')
        </if>
        <if test="enterpriseName != null and enterpriseName != ''">
            AND ser.enterprise_name LIKE CONCAT('%', #{enterpriseName}, '%')
        </if>
        <if test="status != null">
            AND ser.status = #{status}
        </if>
    </where>
    ORDER BY ser.create_time DESC
</select>

同样修改 selectRelationById 方法。

4.3 Service层

ICcdiStaffEnterpriseRelationService.java 和实现类无需大改,MyBatis Plus 会自动填充 JOIN 的字段。

5. 前端代码层设计

5.1 列表页面修改

文件: ruoyi-ui/src/views/ccdiStaffEnterpriseRelation/index.vue

在表格列定义中添加员工姓名列:

<el-table-column label="身份证号" align="center" prop="personId" width="180" />
<el-table-column label="员工姓名" align="center" prop="personName" width="100" />
<el-table-column label="职务" align="center" prop="relationPersonPost" width="120" />

位置建议: 放在"身份证号"列之后,方便用户对照查看

5.2 API接口

文件: ruoyi-ui/src/api/ccdiStaffEnterpriseRelation.js

无需修改,接口会自动返回新增的 personName 字段。

5.3 详情页面

如果存在详情对话框,同样添加员工姓名显示:

<el-form-item label="身份证号">{{ form.personId }}</el-form-item>
<el-form-item label="员工姓名">{{ form.personName }}</el-form-item>
<el-form-item label="职务">{{ form.relationPersonPost }}</el-form-item>

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 单元测试

创建测试用例覆盖以下场景:

// 测试场景1: 员工信息存在
assertEquals("张三", result.getPersonName());

// 测试场景2: 员工信息不存在
assertNull(result.getPersonName());

// 测试场景3: 姓名包含特殊字符
assertEquals("张三·李四", result.getPersonName());

// 测试场景4: 批量数据性能测试
List<CcdiStaffEnterpriseRelationVO> 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)