- 新增员工实体关系管理API文档 - 在列表接口和详情接口响应中添加personName字段 - 说明personName通过LEFT JOIN ccdi_base_staff表获取 - 如果personId在员工信息表中不存在,personName为null
307 lines
8.0 KiB
Markdown
307 lines
8.0 KiB
Markdown
# 员工实体关系添加员工名称字段设计
|
|
|
|
## 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
|
|
<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`
|
|
|
|
在表格列定义中添加员工姓名列:
|
|
|
|
```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 详情页面
|
|
|
|
如果存在详情对话框,同样添加员工姓名显示:
|
|
|
|
```vue
|
|
<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 单元测试
|
|
|
|
创建测试用例覆盖以下场景:
|
|
|
|
```java
|
|
// 测试场景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)
|