634 lines
24 KiB
Markdown
634 lines
24 KiB
Markdown
# 政治面貌、职务、出境事由字段修复报告
|
||
|
||
## 修复时间
|
||
2025-10-08
|
||
|
||
## 问题描述
|
||
|
||
**用户反馈**:
|
||
1. ✅ **职称(professionalTitle)** - 已显示(之前修复已生效)
|
||
2. ❌ **职务(position)** - 未显示到列表中
|
||
3. ❌ **政治面貌(politicalStatus)** - 未正确存入数据库
|
||
4. ❌ **出境事由(exitReason)** - 未显示到列表中
|
||
|
||
## 问题分析
|
||
|
||
### 问题1:政治面貌未存入数据库 🔴 严重
|
||
|
||
**根本原因**:Service层的`buildEntityFromBo`方法中缺少`politicalStatus`字段映射
|
||
|
||
```java
|
||
// ❌ 修复前:缺少政治面貌字段映射
|
||
entity.setApplicantName(bo.getApplicantName());
|
||
entity.setDepartment(bo.getDepartment());
|
||
// entity.setPoliticalStatus(bo.getPoliticalStatus()); // 缺失!
|
||
```
|
||
|
||
**影响**:
|
||
- 前端提交的政治面貌数据无法保存到数据库
|
||
- 数据库`rs_overseas_application.political_status`字段为NULL
|
||
- 影响党籍保留判断逻辑(需要根据政治面貌判断是否为党员)
|
||
|
||
### 问题2:职务和出境事由未显示到列表 🔴 严重
|
||
|
||
**根本原因**:前端列表页面的列定义字段绑定错误
|
||
|
||
```vue
|
||
<!-- ❌ 修复前:字段绑定错误 -->
|
||
<el-table-column label="职称" align="center" prop="position" />
|
||
<!-- label是"职称",但prop绑定的是position(职务字段),应该绑定professionalTitle -->
|
||
|
||
<el-table-column label="出境事由" align="center" prop="purposeText" />
|
||
<!-- label是"出境事由",但prop绑定的是purposeText(出国目的),应该绑定exitReason -->
|
||
```
|
||
|
||
**影响**:
|
||
- 列表页面"职称"列显示的是职务数据(position)
|
||
- 列表页面"出境事由"列显示的是出国目的数据(purpose)
|
||
- 真正的职务和出境事由字段被隐藏,用户无法看到
|
||
|
||
### 问题3:Service层缺少基础字段映射 🔴 严重
|
||
|
||
经过全面检查,发现Service层的`buildEntityFromBo`和`updateByBo`方法中缺少大量基础字段的映射:
|
||
|
||
**缺失的基础字段**:
|
||
1. `gender` - 性别
|
||
2. `birthDate` - 出生日期
|
||
3. `photo` - 照片
|
||
4. `idNumber` - 公民身份号码
|
||
5. `politicalStatus` - 政治面貌 ⬅️ 关键
|
||
6. `registeredAddress` - 户籍所在地
|
||
7. `administrativeLevel` - 行政职级
|
||
8. `personnelCategory` - 人员类别代码
|
||
9. `registrationUnit` - 登记备案责任单位
|
||
10. `unitLeaderSignature` - 单位负责人签名
|
||
11. `unitContact` - 单位联系人
|
||
12. `officePhone` - 办公电话
|
||
13. `mobilePhone` - 移动电话
|
||
|
||
**影响**:
|
||
- 这些字段在前端填写后无法保存到数据库
|
||
- 导致出国登记信息不完整
|
||
- 影响后续的出国登记生成和审批流程
|
||
|
||
## 修复内容
|
||
|
||
### 1. Service层字段映射修复 ✅
|
||
|
||
#### 文件:`RsOverseasApplicationServiceImpl.java`
|
||
|
||
#### ① buildEntityFromBo方法(新增时的字段映射)
|
||
|
||
**修复前**:只有部分字段映射,缺少13个基础字段
|
||
|
||
**修复后**:完整的字段映射,按业务分类组织
|
||
|
||
```java
|
||
private RsOverseasApplication buildEntityFromBo(RsOverseasApplicationBo bo) {
|
||
RsOverseasApplication entity = new RsOverseasApplication();
|
||
entity.setApplicationId(bo.getApplicationId());
|
||
|
||
// ==================== 基本信息 ====================
|
||
entity.setApplicantId(bo.getApplicantId());
|
||
entity.setApplicantName(bo.getApplicantName());
|
||
entity.setGender(bo.getGender()); // ✅ 新增:性别
|
||
entity.setBirthDate(bo.getBirthDate()); // ✅ 新增:出生日期
|
||
entity.setPhoto(bo.getPhoto()); // ✅ 新增:照片
|
||
entity.setIdNumber(bo.getIdNumber()); // ✅ 新增:公民身份号码
|
||
entity.setPoliticalStatus(bo.getPoliticalStatus()); // ✅ 新增:政治面貌(关键)
|
||
entity.setRegisteredAddress(bo.getRegisteredAddress()); // ✅ 新增:户籍所在地
|
||
|
||
// ==================== 工作信息 ====================
|
||
entity.setDepartment(bo.getDepartment());
|
||
entity.setPosition(bo.getPosition()); // 职务
|
||
entity.setProfessionalTitle(bo.getProfessionalTitle()); // 职称
|
||
entity.setAdministrativeLevel(bo.getAdministrativeLevel()); // ✅ 新增:行政职级
|
||
entity.setPersonnelCategory(bo.getPersonnelCategory()); // ✅ 新增:人员类别代码
|
||
|
||
// ==================== 单位和联系信息 ====================
|
||
entity.setRegistrationUnit(bo.getRegistrationUnit()); // ✅ 新增:登记备案责任单位
|
||
entity.setUnitLeaderSignature(bo.getUnitLeaderSignature()); // ✅ 新增:单位负责人签名
|
||
entity.setUnitContact(bo.getUnitContact()); // ✅ 新增:单位联系人
|
||
entity.setOfficePhone(bo.getOfficePhone()); // ✅ 新增:办公电话
|
||
entity.setMobilePhone(bo.getMobilePhone()); // ✅ 新增:移动电话
|
||
entity.setContactPhone(bo.getContactPhone()); // 联系电话(兼容字段)
|
||
|
||
// ==================== 出国目的和行程 ====================
|
||
entity.setPurpose(bo.getPurpose());
|
||
entity.setPurposeDetail(bo.getPurposeDetail());
|
||
entity.setDestination(bo.getDestination());
|
||
entity.setDestinationCountry(bo.getDestinationCountry());
|
||
entity.setDestinationCity(bo.getDestinationCity());
|
||
entity.setStartDate(bo.getStartDate());
|
||
entity.setEndDate(bo.getEndDate());
|
||
entity.setDuration(bo.getDuration());
|
||
entity.setBudget(bo.getBudget());
|
||
|
||
// ==================== 证件和文档 ====================
|
||
entity.setInvitation(bo.getInvitation());
|
||
entity.setDocumentName(bo.getDocumentName());
|
||
entity.setDocumentNumber(bo.getDocumentNumber());
|
||
entity.setItinerary(bo.getItinerary());
|
||
entity.setAccommodationPlan(bo.getAccommodationPlan());
|
||
entity.setTransportationPlan(bo.getTransportationPlan());
|
||
|
||
// ==================== 出境事由和备注 ====================
|
||
entity.setExitReason(bo.getExitReason()); // 出境事由(关键)
|
||
entity.setVisitRelationship(bo.getVisitRelationship());
|
||
entity.setRemarks(bo.getRemarks());
|
||
entity.setApplicantRemark(bo.getApplicantRemark());
|
||
|
||
// ==================== 盖章文件相关字段 ====================
|
||
entity.setStampedRegistrationFilePath(bo.getStampedRegistrationFilePath());
|
||
entity.setStampedRegistrationFileName(bo.getStampedRegistrationFileName());
|
||
entity.setStampedFileUploadTime(bo.getStampedFileUploadTime());
|
||
entity.setStampedFileUploadStatus(bo.getStampedFileUploadStatus());
|
||
|
||
return entity;
|
||
}
|
||
```
|
||
|
||
**修复要点**:
|
||
- ✅ 补全13个基础字段映射
|
||
- ✅ 按业务逻辑分组组织代码
|
||
- ✅ 添加清晰的注释标识新增字段
|
||
- ✅ 保持原有字段映射不变
|
||
|
||
#### ② updateByBo方法(修改时的字段更新)
|
||
|
||
**修复前**:只有部分字段更新,缺少13个基础字段
|
||
|
||
**修复后**:完整的字段更新逻辑
|
||
|
||
```java
|
||
// ==================== 基本信息 ====================
|
||
if (update.getApplicantId() != null) updateWrapper.set(...);
|
||
if (update.getApplicantName() != null) updateWrapper.set(...);
|
||
if (update.getGender() != null) updateWrapper.set(RsOverseasApplication::getGender, update.getGender()); // ✅ 新增
|
||
if (update.getBirthDate() != null) updateWrapper.set(RsOverseasApplication::getBirthDate, update.getBirthDate()); // ✅ 新增
|
||
if (update.getPhoto() != null) updateWrapper.set(RsOverseasApplication::getPhoto, update.getPhoto()); // ✅ 新增
|
||
if (update.getIdNumber() != null) updateWrapper.set(RsOverseasApplication::getIdNumber, update.getIdNumber()); // ✅ 新增
|
||
if (update.getPoliticalStatus() != null) updateWrapper.set(RsOverseasApplication::getPoliticalStatus, update.getPoliticalStatus()); // ✅ 政治面貌(关键)
|
||
if (update.getRegisteredAddress() != null) updateWrapper.set(RsOverseasApplication::getRegisteredAddress, update.getRegisteredAddress()); // ✅ 新增
|
||
|
||
// ==================== 工作信息 ====================
|
||
if (update.getDepartment() != null) updateWrapper.set(...);
|
||
if (update.getPosition() != null) updateWrapper.set(RsOverseasApplication::getPosition, update.getPosition()); // 职务
|
||
if (update.getProfessionalTitle() != null) updateWrapper.set(RsOverseasApplication::getProfessionalTitle, update.getProfessionalTitle()); // 职称
|
||
if (update.getAdministrativeLevel() != null) updateWrapper.set(RsOverseasApplication::getAdministrativeLevel, update.getAdministrativeLevel()); // ✅ 新增
|
||
if (update.getPersonnelCategory() != null) updateWrapper.set(RsOverseasApplication::getPersonnelCategory, update.getPersonnelCategory()); // ✅ 新增
|
||
|
||
// ==================== 单位和联系信息 ====================
|
||
if (update.getRegistrationUnit() != null) updateWrapper.set(...); // ✅ 新增
|
||
if (update.getUnitLeaderSignature() != null) updateWrapper.set(...); // ✅ 新增
|
||
if (update.getUnitContact() != null) updateWrapper.set(...); // ✅ 新增
|
||
if (update.getOfficePhone() != null) updateWrapper.set(...); // ✅ 新增
|
||
if (update.getMobilePhone() != null) updateWrapper.set(...); // ✅ 新增
|
||
if (update.getContactPhone() != null) updateWrapper.set(...);
|
||
|
||
// ... 其他分类 ...
|
||
|
||
// ==================== 出境事由和备注 ====================
|
||
if (update.getExitReason() != null) updateWrapper.set(RsOverseasApplication::getExitReason, update.getExitReason()); // 出境事由(关键)
|
||
```
|
||
|
||
**修复要点**:
|
||
- ✅ 补全13个基础字段更新逻辑
|
||
- ✅ 保持只更新非null字段的原则
|
||
- ✅ 按业务逻辑分组组织代码
|
||
- ✅ 添加清晰的注释标识
|
||
|
||
### 2. 前端列表字段绑定修复 ✅
|
||
|
||
#### 文件:`web/src/views/rs/overseas/index.vue`
|
||
|
||
**修复前**:
|
||
```vue
|
||
<el-table-column label="职称" align="center" prop="position" width="120" />
|
||
<!-- ❌ label是"职称",但绑定的是position字段(职务) -->
|
||
|
||
<el-table-column label="职位" align="center" prop="administrativeLevelText" width="120" />
|
||
<!-- ❌ 缺少"职务"列 -->
|
||
|
||
<el-table-column label="出境事由" align="center" prop="purposeText" width="110" />
|
||
<!-- ❌ label是"出境事由",但绑定的是purposeText字段(出国目的) -->
|
||
```
|
||
|
||
**修复后**:
|
||
```vue
|
||
<el-table-column label="职务" align="center" prop="position" width="120" />
|
||
<!-- ✅ 正确:职务列绑定position字段 -->
|
||
|
||
<el-table-column label="职称" align="center" prop="professionalTitle" width="120" />
|
||
<!-- ✅ 正确:职称列绑定professionalTitle字段 -->
|
||
|
||
<el-table-column label="政治面貌" align="center" prop="politicalStatusText" width="100" />
|
||
<!-- ✅ 正确:政治面貌已有正确绑定 -->
|
||
|
||
<el-table-column label="出境事由" align="center" prop="exitReason" width="110" />
|
||
<!-- ✅ 正确:出境事由列绑定exitReason字段 -->
|
||
```
|
||
|
||
**修复要点**:
|
||
- ✅ 职务列:`prop="position"`
|
||
- ✅ 职称列:`prop="professionalTitle"`
|
||
- ✅ 出境事由列:`prop="exitReason"`
|
||
- ✅ 政治面貌列:保持`prop="politicalStatusText"`不变
|
||
|
||
## 数据流程对比
|
||
|
||
### ❌ 修复前的数据流程(问题状态)
|
||
|
||
```
|
||
前端提交:
|
||
{
|
||
politicalStatus: "1", // 中共党员
|
||
position: "处长",
|
||
exitReason: "旅游"
|
||
}
|
||
↓
|
||
Controller接收: Bo对象
|
||
{
|
||
politicalStatus: "1" ✅
|
||
position: "处长" ✅
|
||
exitReason: "旅游" ✅
|
||
}
|
||
↓
|
||
Service层: buildEntityFromBo(bo)
|
||
{
|
||
// entity.setPoliticalStatus(bo.getPoliticalStatus()); ❌ 缺失!
|
||
entity.setPosition(bo.getPosition()); ✅ 有映射
|
||
entity.setExitReason(bo.getExitReason()); ✅ 有映射
|
||
}
|
||
↓
|
||
Entity对象:
|
||
{
|
||
politicalStatus: null ❌ 未映射
|
||
position: "处长" ✅
|
||
exitReason: "旅游" ✅
|
||
}
|
||
↓
|
||
数据库:
|
||
political_status = NULL ❌
|
||
position = "处长" ✅
|
||
exit_reason = "旅游" ✅
|
||
↓
|
||
前端列表查询:
|
||
{
|
||
politicalStatusText: null ❌
|
||
position: "处长"
|
||
exitReason: "旅游"
|
||
}
|
||
↓
|
||
前端列表显示:
|
||
<el-table-column label="政治面貌" prop="politicalStatusText" /> ❌ 显示空
|
||
<el-table-column label="职称" prop="position" /> ❌ 显示"处长"(应该显示职称)
|
||
<el-table-column label="出境事由" prop="purposeText" /> ❌ 显示出国目的(不是出境事由)
|
||
```
|
||
|
||
### ✅ 修复后的数据流程(正确状态)
|
||
|
||
```
|
||
前端提交:
|
||
{
|
||
politicalStatus: "1", // 中共党员
|
||
position: "处长",
|
||
professionalTitle: "副教授",
|
||
exitReason: "旅游"
|
||
}
|
||
↓
|
||
Controller接收: Bo对象
|
||
{
|
||
politicalStatus: "1" ✅
|
||
position: "处长" ✅
|
||
professionalTitle: "副教授" ✅
|
||
exitReason: "旅游" ✅
|
||
}
|
||
↓
|
||
Service层: buildEntityFromBo(bo)
|
||
{
|
||
entity.setPoliticalStatus(bo.getPoliticalStatus()); ✅ 已添加映射
|
||
entity.setPosition(bo.getPosition()); ✅ 有映射
|
||
entity.setProfessionalTitle(bo.getProfessionalTitle()); ✅ 有映射
|
||
entity.setExitReason(bo.getExitReason()); ✅ 有映射
|
||
}
|
||
↓
|
||
Entity对象:
|
||
{
|
||
politicalStatus: "1" ✅ 映射成功
|
||
position: "处长" ✅
|
||
professionalTitle: "副教授" ✅
|
||
exitReason: "旅游" ✅
|
||
}
|
||
↓
|
||
数据库:
|
||
political_status = "1" ✅
|
||
position = "处长" ✅
|
||
professional_title = "副教授" ✅
|
||
exit_reason = "旅游" ✅
|
||
↓
|
||
前端列表查询:
|
||
{
|
||
politicalStatusText: "中共党员" ✅
|
||
position: "处长" ✅
|
||
professionalTitle: "副教授" ✅
|
||
exitReason: "旅游" ✅
|
||
}
|
||
↓
|
||
前端列表显示:
|
||
<el-table-column label="政治面貌" prop="politicalStatusText" /> ✅ 显示"中共党员"
|
||
<el-table-column label="职务" prop="position" /> ✅ 显示"处长"
|
||
<el-table-column label="职称" prop="professionalTitle" /> ✅ 显示"副教授"
|
||
<el-table-column label="出境事由" prop="exitReason" /> ✅ 显示"旅游"
|
||
```
|
||
|
||
## 修复文件总览
|
||
|
||
| 文件 | 修复内容 | 行数 | 状态 |
|
||
|------|---------|------|------|
|
||
| **RsOverseasApplicationServiceImpl.java** | buildEntityFromBo方法补全13个基础字段映射 | 548-609 | ✅ 完成 |
|
||
| **RsOverseasApplicationServiceImpl.java** | updateByBo方法补全13个基础字段更新逻辑 | 220-274 | ✅ 完成 |
|
||
| **web/src/views/rs/overseas/index.vue** | 列表页面列定义字段绑定修正 | 68-74 | ✅ 完成 |
|
||
|
||
## 修复字段清单
|
||
|
||
### 本次修复的关键字段
|
||
|
||
| 序号 | 字段名 | Java属性 | 数据库字段 | 修复内容 | 优先级 |
|
||
|------|--------|---------|-----------|---------|--------|
|
||
| 1 | 政治面貌 | politicalStatus | political_status | Service层映射 | 🔴 高 |
|
||
| 2 | 职务 | position | position | 前端列绑定 | 🔴 高 |
|
||
| 3 | 出境事由 | exitReason | exit_reason | 前端列绑定 | 🔴 高 |
|
||
|
||
### 一并补全的基础字段
|
||
|
||
| 序号 | 字段名 | Java属性 | 数据库字段 | 修复内容 | 优先级 |
|
||
|------|--------|---------|-----------|---------|--------|
|
||
| 4 | 性别 | gender | gender | Service层映射 | 🟡 中 |
|
||
| 5 | 出生日期 | birthDate | birth_date | Service层映射 | 🟡 中 |
|
||
| 6 | 照片 | photo | photo | Service层映射 | 🟡 中 |
|
||
| 7 | 公民身份号码 | idNumber | id_number | Service层映射 | 🟡 中 |
|
||
| 8 | 户籍所在地 | registeredAddress | registered_address | Service层映射 | 🟡 中 |
|
||
| 9 | 行政职级 | administrativeLevel | administrative_level | Service层映射 | 🟡 中 |
|
||
| 10 | 人员类别代码 | personnelCategory | personnel_category | Service层映射 | 🟡 中 |
|
||
| 11 | 登记备案责任单位 | registrationUnit | registration_unit | Service层映射 | 🟢 低 |
|
||
| 12 | 单位负责人签名 | unitLeaderSignature | unit_leader_signature | Service层映射 | 🟢 低 |
|
||
| 13 | 单位联系人 | unitContact | unit_contact | Service层映射 | 🟢 低 |
|
||
| 14 | 办公电话 | officePhone | office_phone | Service层映射 | 🟢 低 |
|
||
| 15 | 移动电话 | mobilePhone | mobile_phone | Service层映射 | 🟢 低 |
|
||
|
||
## 测试验证
|
||
|
||
### ⚠️ 必须重启后端服务
|
||
|
||
```bash
|
||
cd /Users/weizzzz/Documents/Cursor/0828CURSOR/all-project/backend
|
||
mvn clean install
|
||
# 然后重启后端服务
|
||
```
|
||
|
||
### 测试步骤
|
||
|
||
#### 1. 新增申请测试
|
||
|
||
填写完整表单:
|
||
- ✅ 姓名:张三
|
||
- ✅ 性别:男
|
||
- ✅ 出生年月:1990-01-01
|
||
- ✅ **政治面貌:中共党员** ⬅️ 关键测试字段
|
||
- ✅ 现工作部门:计算机学院
|
||
- ✅ **职务:处长** ⬅️ 关键测试字段
|
||
- ✅ **职称:副教授** ⬅️ 测试字段
|
||
- ✅ 前往国家:美国
|
||
- ✅ **出境事由:旅游** ⬅️ 关键测试字段
|
||
- ✅ 出发日期:2025-11-01
|
||
- ✅ 返回日期:2025-11-10
|
||
|
||
#### 2. 数据库验证SQL
|
||
|
||
```sql
|
||
SELECT
|
||
application_id,
|
||
applicant_name,
|
||
gender,
|
||
birth_date,
|
||
political_status, -- ⬅️ 应该显示"1"或"中共党员"
|
||
department,
|
||
position, -- ⬅️ 应该显示"处长"
|
||
professional_title, -- ⬅️ 应该显示"副教授"
|
||
exit_reason, -- ⬅️ 应该显示"旅游"
|
||
destination_country,
|
||
start_date,
|
||
end_date,
|
||
duration,
|
||
status,
|
||
create_time
|
||
FROM rs_overseas_application
|
||
ORDER BY create_time DESC
|
||
LIMIT 1;
|
||
```
|
||
|
||
**预期结果**:
|
||
```
|
||
political_status = "1" ✅ 不应为NULL
|
||
position = "处长" ✅ 不应为NULL
|
||
professional_title = "副教授" ✅ 不应为NULL
|
||
exit_reason = "旅游" ✅ 不应为NULL
|
||
```
|
||
|
||
#### 3. 前端列表显示验证
|
||
|
||
刷新列表页面,查看最新记录:
|
||
|
||
| 姓名 | 现工作部门 | 职务 | 职称 | 政治面貌 | 前往国家 | 出境事由 |
|
||
|------|-----------|------|------|---------|---------|---------|
|
||
| 张三 | 计算机学院 | **处长** | **副教授** | **中共党员** | 美国 | **旅游** |
|
||
|
||
**验证要点**:
|
||
- ✅ "职务"列显示"处长"(不是职称)
|
||
- ✅ "职称"列显示"副教授"(不是职务)
|
||
- ✅ "政治面貌"列显示"中共党员"(不是空)
|
||
- ✅ "出境事由"列显示"旅游"(不是出国目的)
|
||
|
||
#### 4. 修改申请测试
|
||
|
||
1. 编辑已有申请
|
||
2. 修改政治面貌从"中共党员"改为"群众"
|
||
3. 修改职务从"处长"改为"科长"
|
||
4. 修改出境事由从"旅游"改为"探亲"
|
||
5. 保存修改
|
||
6. 查询数据库验证字段是否正确更新
|
||
7. 查看列表验证显示是否正确
|
||
|
||
## 修复影响范围
|
||
|
||
### 直接影响
|
||
|
||
1. **政治面貌字段** ✅
|
||
- 新增申请:政治面貌可以正确保存
|
||
- 修改申请:政治面貌可以正确更新
|
||
- 列表显示:政治面貌可以正确显示
|
||
- 党籍保留判断:可以根据政治面貌判断是否为党员
|
||
|
||
2. **职务字段** ✅
|
||
- 列表显示:职务列显示正确的职务数据
|
||
- 职称列显示:职称列显示正确的职称数据
|
||
- 数据保存:职务数据已经可以正确保存(之前就有映射)
|
||
|
||
3. **出境事由字段** ✅
|
||
- 列表显示:出境事由列显示正确的出境事由数据
|
||
- 数据保存:出境事由数据已经可以正确保存(之前就有映射)
|
||
|
||
### 间接影响
|
||
|
||
1. **基础信息完整性** ✅
|
||
- 13个基础字段现在都可以正确保存和更新
|
||
- 出国登记信息更加完整
|
||
- 支持完整的出国登记表生成
|
||
|
||
2. **党籍保留功能** ✅
|
||
- 可以正确判断是否为中共党员
|
||
- 党籍保留附件上传逻辑可以正常工作
|
||
- 党籍保留记录可以正确创建
|
||
|
||
3. **审批流程** ✅
|
||
- 审批人员可以看到完整的申请信息
|
||
- 包括政治面貌、职务、出境事由等关键信息
|
||
|
||
4. **报表统计** ✅
|
||
- 可以按政治面貌统计出国人员
|
||
- 可以按职务级别统计
|
||
- 可以按出境事由统计
|
||
|
||
## 技术要点总结
|
||
|
||
### 1. Service层字段映射机制
|
||
|
||
**问题**:即使Entity、Bo、Vo类都有字段定义,如果Service层的转换方法中缺少字段映射,数据仍然无法保存。
|
||
|
||
**原因**:项目使用了MapStruct的`@AutoMapper`注解,但在手动编写的`buildEntityFromBo`方法中,MapStruct的自动映射不生效,必须手动调用setter方法。
|
||
|
||
**解决方案**:在`buildEntityFromBo`方法中显式调用所有字段的setter方法。
|
||
|
||
### 2. 前端列定义字段绑定
|
||
|
||
**问题**:`<el-table-column>`的`label`属性和`prop`属性必须一致,否则会出现标题和内容不匹配的问题。
|
||
|
||
**示例错误**:
|
||
```vue
|
||
<el-table-column label="职称" prop="position" />
|
||
<!-- label是"职称",但prop绑定的是position(职务字段) -->
|
||
```
|
||
|
||
**正确写法**:
|
||
```vue
|
||
<el-table-column label="职务" prop="position" />
|
||
<el-table-column label="职称" prop="professionalTitle" />
|
||
```
|
||
|
||
### 3. 字段命名规范
|
||
|
||
| 业务概念 | Java属性 | 数据库字段 | 前端字段 | 说明 |
|
||
|---------|---------|-----------|---------|------|
|
||
| 职务 | position | position | position | 行政职务,如"处长" |
|
||
| 职称 | professionalTitle | professional_title | professionalTitle | 专业技术职称,如"副教授" |
|
||
| 职位/行政职级 | administrativeLevel | administrative_level | administrativeLevel | 行政级别,如"正处级" |
|
||
| 出国目的 | purpose | purpose | purpose | 出国目的类型,如"学术交流" |
|
||
| 出境事由 | exitReason | exit_reason | exitReason | 出境具体事由,如"旅游"、"探亲" |
|
||
|
||
### 4. 新增字段的完整修复清单
|
||
|
||
对于任何新增的数据库字段,需要在以下位置进行修改:
|
||
|
||
- [ ] ✅ Entity类 - 已存在
|
||
- [ ] ✅ Bo类 - 已存在
|
||
- [ ] ✅ Vo类 - 已存在
|
||
- [ ] ✅ Service层 buildEntityFromBo方法 - **本次修复的关键点**
|
||
- [ ] ✅ Service层 updateByBo方法 - **本次修复的关键点**
|
||
- [ ] ✅ 前端表单字段定义 - 已存在
|
||
- [ ] ✅ 前端表单验证规则 - 已存在
|
||
- [ ] ✅ 前端列表列定义 - **本次修复的关键点**
|
||
|
||
## 修复对比表
|
||
|
||
| 修复项 | 修复前 | 修复后 |
|
||
|-------|--------|--------|
|
||
| buildEntityFromBo基础字段映射 | ❌ 缺少13个字段 | ✅ 补全所有基础字段 |
|
||
| updateByBo基础字段更新 | ❌ 缺少13个字段 | ✅ 补全所有基础字段 |
|
||
| 前端职务列绑定 | ❌ label="职称" prop="position" | ✅ label="职务" prop="position" |
|
||
| 前端职称列绑定 | ❌ 缺少独立的职称列 | ✅ label="职称" prop="professionalTitle" |
|
||
| 前端出境事由列绑定 | ❌ prop="purposeText" | ✅ prop="exitReason" |
|
||
| 政治面貌保存 | ❌ 保存为NULL | ✅ 正确保存 |
|
||
| 政治面貌显示 | ❌ 列表显示空 | ✅ 列表正确显示 |
|
||
| 职务显示 | ❌ 在职称列显示 | ✅ 在职务列显示 |
|
||
| 出境事由显示 | ❌ 显示出国目的 | ✅ 显示出境事由 |
|
||
| 语法检查 | - | ✅ 通过 |
|
||
|
||
## 注意事项
|
||
|
||
### 1. 已有数据处理
|
||
|
||
对于修复前已经提交的申请记录,政治面貌等13个基础字段的值为NULL。
|
||
|
||
**处理方案**:
|
||
- ✅ **推荐方案**:让用户重新编辑并保存(Service层的updateByBo已修复,可以正确更新)
|
||
- ⚠️ **备选方案**:通过SQL脚本批量设置默认值(需要业务确认)
|
||
|
||
### 2. 前端表单字段已正确
|
||
|
||
前端表单中这些字段的定义和验证规则都是正确的:
|
||
- ✅ `politicalStatus` - 下拉选择
|
||
- ✅ `position` - 文本输入
|
||
- ✅ `professionalTitle` - 文本输入
|
||
- ✅ `exitReason` - 单选按钮
|
||
|
||
### 3. 数据库字段已存在
|
||
|
||
数据库表`rs_overseas_application`中所有相关字段都已经存在:
|
||
- ✅ `political_status` varchar(20)
|
||
- ✅ `position` varchar(100)
|
||
- ✅ `professional_title` varchar(100)
|
||
- ✅ `exit_reason` varchar(50)
|
||
|
||
## 相关文档
|
||
|
||
- [出国申请字段映射问题修复报告.md](./出国申请字段映射问题修复报告.md) - 之前的修复报告
|
||
- [RsOverseasApplicationServiceImpl.java](./backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/service/impl/RsOverseasApplicationServiceImpl.java) - Service层修复代码
|
||
- [index.vue](./web/src/views/rs/overseas/index.vue) - 前端列表页修复代码
|
||
|
||
## 下一步行动
|
||
|
||
### 1. ⚠️ 必须重启后端服务
|
||
```bash
|
||
cd /Users/weizzzz/Documents/Cursor/0828CURSOR/all-project/backend
|
||
mvn clean install
|
||
# 重启后端服务
|
||
```
|
||
|
||
### 2. 执行完整测试
|
||
- 新增申请测试(重点测试政治面貌、职务、出境事由)
|
||
- 数据库验证(查询这些字段是否正确保存)
|
||
- 列表显示验证(查看列表各列显示是否正确)
|
||
- 修改申请测试(验证字段更新功能)
|
||
|
||
### 3. 反馈结果
|
||
如果测试发现问题,请提供:
|
||
- 具体的错误信息
|
||
- 后端日志
|
||
- 前端控制台输出
|
||
- 数据库查询结果截图
|
||
- 列表页面截图
|
||
|
||
---
|
||
|
||
**修复完成时间**: 2025-10-08
|
||
**修复执行者**: Cursor AI Assistant
|
||
**代码审查状态**: ✅ 已通过语法检查
|
||
**测试状态**: ⏳ 待用户验证
|
||
**预期效果**:
|
||
- ✅ 政治面貌可以正确保存和显示
|
||
- ✅ 职务列和职称列显示正确的数据
|
||
- ✅ 出境事由列显示正确的数据
|
||
- ✅ 13个基础字段都可以正确保存和更新
|
||
|