369 lines
12 KiB
Markdown
369 lines
12 KiB
Markdown
# 出国申请附件显示修复说明
|
||
|
||
## 问题描述
|
||
|
||
用户通过"出国申请"菜单新增申请时,上传了以下两个附件:
|
||
1. **出国境登记表盖章文件**
|
||
2. **党籍保留附件**
|
||
|
||
但在点击"查看详情"按钮时,弹窗中**未显示这两个附件**。
|
||
|
||
---
|
||
|
||
## 问题原因分析
|
||
|
||
### 根本原因
|
||
|
||
**后端VO类缺少党籍保留附件相关字段**
|
||
|
||
#### 数据库表字段(完整)
|
||
`rs_overseas_application` 表中包含以下字段:
|
||
- `stamped_registration_file_path` - 登记备案表盖章文件路径
|
||
- `stamped_registration_file_name` - 登记备案表盖章文件名
|
||
- `stamped_file_upload_time` - 盖章文件上传时间
|
||
- `stamped_file_upload_status` - 盖章文件上传状态
|
||
- `stamped_file_oss_id` - 盖章文件OSS ID
|
||
- `party_retention_file_path` - 党籍保留附件文件路径
|
||
- `party_retention_file_name` - 党籍保留附件文件名
|
||
- `party_retention_upload_time` - 党籍保留附件上传时间
|
||
- `party_retention_upload_status` - 党籍保留附件上传状态
|
||
- `party_retention_file_oss_id` - 党籍保留附件OSS ID
|
||
|
||
#### 后端实体类(RsOverseasApplication.java)- ✅ 完整
|
||
|
||
```java
|
||
private String partyRetentionFilePath;
|
||
private String partyRetentionFileName;
|
||
private Date partyRetentionUploadTime;
|
||
private String partyRetentionUploadStatus;
|
||
private Long partyRetentionFileOssId;
|
||
```
|
||
|
||
#### 后端VO类(RsOverseasApplicationVo.java)- ❌ 缺失
|
||
|
||
**修复前**:只有 `partyRetentionFileOssId`,缺少以下字段:
|
||
- `partyRetentionFilePath`
|
||
- `partyRetentionFileName`
|
||
- `partyRetentionUploadTime`
|
||
- `partyRetentionUploadStatus`
|
||
|
||
**导致问题**:
|
||
- 前端调用查看详情API时,后端返回的VO数据中没有党籍保留附件的文件名、上传时间等信息
|
||
- 前端无法判断是否有党籍保留附件上传(`partyRetentionUploadStatus` 为空)
|
||
- 前端详情弹窗的条件渲染失效:`v-if="partyRetentionUploadStatus === '1'"` 始终为false
|
||
|
||
---
|
||
|
||
## 修复方案
|
||
|
||
### 1️⃣ 后端修复:补充VO字段
|
||
|
||
**文件**:`backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/domain/vo/RsOverseasApplicationVo.java`
|
||
|
||
**修改位置**:第332-356行
|
||
|
||
**修改内容**:在 `stampedFileOssId` 之后补充党籍保留附件的完整字段
|
||
|
||
```java
|
||
/**
|
||
* 党籍保留附件文件路径
|
||
*/
|
||
private String partyRetentionFilePath;
|
||
|
||
/**
|
||
* 党籍保留附件文件名
|
||
*/
|
||
private String partyRetentionFileName;
|
||
|
||
/**
|
||
* 党籍保留附件上传时间
|
||
*/
|
||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||
private Date partyRetentionUploadTime;
|
||
|
||
/**
|
||
* 党籍保留附件上传状态:0-未上传,1-已上传
|
||
*/
|
||
private String partyRetentionUploadStatus;
|
||
|
||
/**
|
||
* 党籍保留附件OSS ID(用于安全下载)
|
||
*/
|
||
private Long partyRetentionFileOssId;
|
||
```
|
||
|
||
### 2️⃣ 前端修复:补充TypeScript接口字段
|
||
|
||
**文件**:`web/src/api/rs/overseas.ts`
|
||
|
||
**修改位置**:第55-64行(OverseasApplicationVO接口)
|
||
|
||
**修改内容**:补充党籍保留附件和OSS ID字段
|
||
|
||
```typescript
|
||
export interface OverseasApplicationVO {
|
||
// ... 其他字段 ...
|
||
stampedFileOssId?: number; // 盖章文件OSS ID
|
||
partyRetentionFilePath?: string; // 党籍保留附件文件路径
|
||
partyRetentionFileName?: string; // 党籍保留附件文件名
|
||
partyRetentionUploadTime?: string; // 党籍保留附件上传时间
|
||
partyRetentionUploadStatus?: string; // 党籍保留附件上传状态
|
||
partyRetentionFileOssId?: number; // 党籍保留附件OSS ID
|
||
// ... 其他字段 ...
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 前端详情弹窗显示逻辑
|
||
|
||
**文件**:`web/src/views/rs/overseas/index.vue`
|
||
|
||
### 出国境登记表盖章文件显示(第997-1022行)
|
||
|
||
```vue
|
||
<div v-if="(state.viewData as OverseasApplicationVO).stampedFileUploadStatus === '1'"
|
||
style="margin-bottom: 15px; padding: 12px; border: 1px solid #e4e7ed; border-radius: 4px; background: #f9fafb;">
|
||
<div style="font-size: 14px; color: #606266; margin-bottom: 8px;">
|
||
<el-icon><Document /></el-icon>
|
||
<span style="margin-left: 5px; font-weight: 500;">出国境登记表盖章文件</span>
|
||
</div>
|
||
<div style="display: flex; align-items: center; justify-content: space-between;">
|
||
<div style="flex: 1;">
|
||
<el-tag type="success" size="small">
|
||
<el-icon><Document /></el-icon>
|
||
{{ (state.viewData as OverseasApplicationVO).stampedRegistrationFileName }}
|
||
</el-tag>
|
||
<span style="margin-left: 10px; font-size: 12px; color: #909399;">
|
||
上传时间: {{ (state.viewData as OverseasApplicationVO).stampedFileUploadTime }}
|
||
</span>
|
||
</div>
|
||
<el-button link type="primary" size="small" @click="handleDownloadStampedFile">
|
||
<el-icon><Download /></el-icon> 下载
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
**条件渲染**:
|
||
- `v-if="stampedFileUploadStatus === '1'"` - 只有上传状态为"1"(已上传)时才显示
|
||
- 显示文件名:`stampedRegistrationFileName`
|
||
- 显示上传时间:`stampedFileUploadTime`
|
||
|
||
### 党籍保留附件显示(第1024-1050行)
|
||
|
||
```vue
|
||
<div v-if="(state.viewData as OverseasApplicationVO).partyRetentionUploadStatus === '1'"
|
||
style="margin-bottom: 15px; padding: 12px; border: 1px solid #e4e7ed; border-radius: 4px; background: #fff5f5;">
|
||
<div style="font-size: 14px; color: #ff4757; margin-bottom: 8px;">
|
||
<el-icon><Warning /></el-icon>
|
||
<span style="margin-left: 5px; font-weight: 500;">党籍保留附件</span>
|
||
</div>
|
||
<div style="display: flex; align-items: center; justify-content: space-between;">
|
||
<div style="flex: 1;">
|
||
<el-tag type="danger" size="small">
|
||
<el-icon><Document /></el-icon>
|
||
{{ (state.viewData as OverseasApplicationVO).partyRetentionFileName }}
|
||
</el-tag>
|
||
<span style="margin-left: 10px; font-size: 12px; color: #909399;">
|
||
上传时间: {{ (state.viewData as OverseasApplicationVO).partyRetentionUploadTime }}
|
||
</span>
|
||
</div>
|
||
<el-button link type="primary" size="small" @click="handleDownloadPartyRetentionFile">
|
||
<el-icon><Download /></el-icon> 下载
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
**条件渲染**:
|
||
- `v-if="partyRetentionUploadStatus === '1'"` - 只有上传状态为"1"(已上传)时才显示
|
||
- 显示文件名:`partyRetentionFileName`(✅ **修复后可用**)
|
||
- 显示上传时间:`partyRetentionUploadTime`(✅ **修复后可用**)
|
||
|
||
---
|
||
|
||
## 修复效果
|
||
|
||
### 修复前 ❌
|
||
- **问题1**:党籍保留附件区域不显示(条件渲染失败)
|
||
- **原因**:`partyRetentionUploadStatus` 字段为空/undefined
|
||
|
||
### 修复后 ✅
|
||
- **出国境登记表盖章文件**:
|
||
- 显示文件名、上传时间
|
||
- 提供下载按钮
|
||
- **党籍保留附件**:
|
||
- 显示文件名、上传时间(✅ **字段补全后可用**)
|
||
- 提供下载按钮
|
||
|
||
---
|
||
|
||
## 部署步骤
|
||
|
||
### 1️⃣ 后端部署
|
||
|
||
#### Step 1: 编译代码(已完成)
|
||
```bash
|
||
cd /Users/weizzzz/Documents/Cursor/0828CURSOR/all-project/backend
|
||
mvn clean compile -DskipTests -pl ruoyi-modules/ruoyi-rs -am
|
||
```
|
||
|
||
**编译结果**:✅ BUILD SUCCESS
|
||
|
||
#### Step 2: 重启后端服务
|
||
|
||
**方法1:IDEA重启**
|
||
1. 停止当前运行的 RuoYi-Admin 服务
|
||
2. 重新运行 RuoYi-Admin 启动类
|
||
|
||
**方法2:命令行重启**
|
||
```bash
|
||
# 停止现有进程
|
||
ps aux | grep ruoyi-admin
|
||
kill -9 <pid>
|
||
|
||
# 启动服务
|
||
cd ruoyi-admin
|
||
mvn spring-boot:run
|
||
```
|
||
|
||
### 2️⃣ 前端部署
|
||
|
||
#### 前端无需重新编译
|
||
- TypeScript 接口更新后,前端代码无需重新编译
|
||
- 浏览器刷新即可生效
|
||
|
||
#### 浏览器刷新
|
||
**硬刷新(清除缓存)**:
|
||
- **Windows**: `Ctrl + Shift + R`
|
||
- **Mac**: `Cmd + Shift + R`
|
||
|
||
---
|
||
|
||
## 验证步骤
|
||
|
||
### 1️⃣ 准备测试数据
|
||
|
||
#### 新增出国申请(包含附件)
|
||
1. 点击"出国申请"菜单
|
||
2. 点击"新增申请"按钮
|
||
3. 填写表单信息
|
||
4. 上传"出国境登记表盖章文件"
|
||
5. 上传"党籍保留附件"(如果是党员)
|
||
6. 点击"提交"按钮
|
||
|
||
### 2️⃣ 验证详情弹窗显示
|
||
|
||
#### 查看详情
|
||
1. 在出国申请列表中找到刚才新增的申请
|
||
2. 点击"查看详情"按钮
|
||
3. **验证点**:
|
||
- ✅ 出国境登记表盖章文件区域显示
|
||
- ✅ 显示文件名(如:`出国登记表-盖章.pdf`)
|
||
- ✅ 显示上传时间(如:`2025-10-11 10:30:15`)
|
||
- ✅ 党籍保留附件区域显示(如果是党员且已上传)
|
||
- ✅ 显示文件名(如:`党籍保留材料.pdf`)
|
||
- ✅ 显示上传时间(如:`2025-10-11 10:31:20`)
|
||
|
||
### 3️⃣ 验证下载功能
|
||
|
||
#### 下载附件
|
||
1. 点击"出国境登记表盖章文件"的"下载"按钮
|
||
- ✅ 文件开始下载
|
||
- ✅ 文件名正确
|
||
2. 点击"党籍保留附件"的"下载"按钮
|
||
- ✅ 文件开始下载
|
||
- ✅ 文件名正确
|
||
|
||
---
|
||
|
||
## 技术要点
|
||
|
||
### AutoMapper 自动映射
|
||
|
||
**注解**:`@AutoMapper(target = RsOverseasApplication.class)`
|
||
|
||
**作用**:
|
||
- 自动将 `RsOverseasApplication` 实体类的字段映射到 `RsOverseasApplicationVo`
|
||
- 字段名相同的会自动映射
|
||
- **要求**:VO类必须包含对应的字段,否则不会映射
|
||
|
||
**为什么需要手动补充字段**:
|
||
- 虽然有 `@AutoMapper` 注解
|
||
- 但VO类中必须**显式声明**所有需要返回的字段
|
||
- 缺失的字段不会自动添加,需要手动补充
|
||
|
||
### JSON序列化
|
||
|
||
**时间字段格式化**:
|
||
```java
|
||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||
private Date partyRetentionUploadTime;
|
||
```
|
||
|
||
**作用**:
|
||
- 将 `Date` 类型转换为指定格式的字符串
|
||
- 前端接收到的数据:`"2025-10-11 10:31:20"` 而不是时间戳
|
||
|
||
---
|
||
|
||
## 参考
|
||
|
||
### 对比:培训申请附件显示实现
|
||
|
||
**文件**:`web/src/views/rs/training/index.vue`
|
||
|
||
**相似功能**:
|
||
- 培训申请详情弹窗中也显示附件列表
|
||
- 实现方式:通过 `attachmentIds` 字段查询附件列表
|
||
- 显示逻辑:使用 `el-table` 展示附件列表
|
||
|
||
**出国申请的差异**:
|
||
- 出国申请有两类特殊附件(盖章文件、党籍附件)
|
||
- 直接将附件信息存储在主表中(而不是关联附件表)
|
||
- 使用条件渲染显示(`v-if`)而不是表格列表
|
||
|
||
---
|
||
|
||
## 总结
|
||
|
||
### 修复内容
|
||
1. ✅ **后端VO补充字段**:添加党籍保留附件的4个字段
|
||
2. ✅ **前端TS接口补充字段**:添加党籍保留附件和OSS ID字段
|
||
3. ✅ **后端编译成功**:无错误
|
||
|
||
### 待验证
|
||
1. ⏳ **重启后端服务**:应用VO字段更改
|
||
2. ⏳ **前端刷新验证**:硬刷新浏览器
|
||
3. ⏳ **功能验证**:查看详情弹窗显示附件
|
||
4. ⏳ **下载验证**:附件下载功能正常
|
||
|
||
### 修复时间
|
||
**修复日期**:2025-10-11
|
||
**修复内容**:出国申请查看详情弹窗附件不显示问题
|
||
|
||
---
|
||
|
||
## 附录:字段对照表
|
||
|
||
| 字段用途 | 数据库字段 | 实体类字段 | VO类字段 | 前端TS接口 |
|
||
|---------|-----------|-----------|----------|-----------|
|
||
| 盖章文件路径 | `stamped_registration_file_path` | `stampedRegistrationFilePath` | `stampedRegistrationFilePath` | `stampedRegistrationFilePath` |
|
||
| 盖章文件名 | `stamped_registration_file_name` | `stampedRegistrationFileName` | `stampedRegistrationFileName` | `stampedRegistrationFileName` |
|
||
| 盖章上传时间 | `stamped_file_upload_time` | `stampedFileUploadTime` | `stampedFileUploadTime` | `stampedFileUploadTime` |
|
||
| 盖章上传状态 | `stamped_file_upload_status` | `stampedFileUploadStatus` | `stampedFileUploadStatus` | `stampedFileUploadStatus` |
|
||
| 盖章文件OSS ID | `stamped_file_oss_id` | `stampedFileOssId` | `stampedFileOssId` | `stampedFileOssId` |
|
||
| 党籍附件路径 | `party_retention_file_path` | `partyRetentionFilePath` | ✅ `partyRetentionFilePath` | ✅ `partyRetentionFilePath` |
|
||
| 党籍附件文件名 | `party_retention_file_name` | `partyRetentionFileName` | ✅ `partyRetentionFileName` | ✅ `partyRetentionFileName` |
|
||
| 党籍上传时间 | `party_retention_upload_time` | `partyRetentionUploadTime` | ✅ `partyRetentionUploadTime` | ✅ `partyRetentionUploadTime` |
|
||
| 党籍上传状态 | `party_retention_upload_status` | `partyRetentionUploadStatus` | ✅ `partyRetentionUploadStatus` | ✅ `partyRetentionUploadStatus` |
|
||
| 党籍文件OSS ID | `party_retention_file_oss_id` | `partyRetentionFileOssId` | `partyRetentionFileOssId` | ✅ `partyRetentionFileOssId` |
|
||
|
||
✅ = 本次修复补充的字段
|
||
|
||
---
|
||
|
||
**修复完成!请重启后端服务并刷新前端验证功能。**
|
||
|