“编译修改”
This commit is contained in:
1 parent
69e4b08946
commit
e79bf5a26c
224 files changed
+66161
-6
No files matched your search
@@ -0,0 +1,500 @@
|
||||
# 出国行程变更 - 申请行程情况字段调整
|
||||
|
||||
## 📋 修改时间
|
||||
2025-10-13
|
||||
|
||||
## 🎯 需求说明
|
||||
|
||||
调整"二、申请行程情况"和"三、实际行程情况"部分的字段显示:
|
||||
|
||||
### 原字段布局
|
||||
- 申请出行时间
|
||||
- 地点
|
||||
- 在外停留时间
|
||||
|
||||
### 新字段布局
|
||||
- **前往国家** - 对应数据库字段 `original_destination`
|
||||
- **出境事由** - 对应数据库字段 `original_exit_reason`
|
||||
- **行程安排** - 对应数据库字段 `original_itinerary`
|
||||
|
||||
## ✅ 确认事项
|
||||
|
||||
### 数据库表结构
|
||||
数据库表 `rs_overseas_itinerary_change` 已有所需字段,**无需修改**:
|
||||
|
||||
```sql
|
||||
-- 原记录信息(从出国记录表冗余存储)
|
||||
`original_destination` varchar(100) DEFAULT NULL COMMENT '原目的地国家',
|
||||
`original_destination_city` varchar(100) DEFAULT NULL COMMENT '原目的地城市',
|
||||
`original_exit_reason` varchar(100) DEFAULT NULL COMMENT '原出境事由',
|
||||
`original_start_date` date DEFAULT NULL COMMENT '原出发日期',
|
||||
`original_end_date` date DEFAULT NULL COMMENT '原返回日期',
|
||||
`original_duration` int(11) DEFAULT NULL COMMENT '原出国天数',
|
||||
`original_itinerary` text COMMENT '原行程安排',
|
||||
|
||||
-- 变更信息
|
||||
`new_destination` varchar(100) DEFAULT NULL COMMENT '新目的地国家',
|
||||
`new_destination_city` varchar(100) DEFAULT NULL COMMENT '新目的地城市',
|
||||
`new_exit_reason` varchar(100) DEFAULT NULL COMMENT '新出境事由',
|
||||
`new_start_date` date DEFAULT NULL COMMENT '新出发日期',
|
||||
`new_end_date` date DEFAULT NULL COMMENT '新返回日期',
|
||||
`new_duration` int(11) DEFAULT NULL COMMENT '新出国天数',
|
||||
`new_itinerary` text COMMENT '新行程安排',
|
||||
```
|
||||
|
||||
### 后端代码
|
||||
后端实体类、VO类、Bo类已有相应字段,**无需修改**。
|
||||
|
||||
### 前端API类型
|
||||
前端API接口类型定义已有相应字段,**无需修改**:
|
||||
|
||||
```typescript
|
||||
export interface ItineraryChangeVO {
|
||||
// ... 其他字段
|
||||
originalDestination: string;
|
||||
originalExitReason: string;
|
||||
originalItinerary: string;
|
||||
newDestination?: string;
|
||||
newExitReason?: string;
|
||||
newItinerary?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 修改内容
|
||||
|
||||
### 一、前端表单UI修改
|
||||
|
||||
**文件**: `web/src/views/rs/overseas/itinerary-change.vue`
|
||||
|
||||
#### 1. 二、申请行程情况(只读显示)
|
||||
|
||||
**修改前**:
|
||||
```vue
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="申请出行时间">
|
||||
<el-input :value="formatDate(form.originalStartDate)" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="地点">
|
||||
<el-input v-model="form.originalDestination" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="在外停留时间">
|
||||
<el-input :value="`${formatDate(form.originalStartDate)} 至 ${formatDate(form.originalEndDate)} (${form.originalDuration || 0}天)`" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
```
|
||||
|
||||
**修改后**:
|
||||
```vue
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="前往国家">
|
||||
<el-input v-model="form.originalDestination" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="出境事由">
|
||||
<el-input v-model="form.originalExitReason" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="申请出行时间">
|
||||
<el-input :value="`${formatDate(form.originalStartDate)} 至 ${formatDate(form.originalEndDate)}`" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="在外停留天数">
|
||||
<el-input :value="`${form.originalDuration || 0}天`" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="行程安排">
|
||||
<el-input
|
||||
v-model="form.originalItinerary"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
disabled
|
||||
placeholder="原行程安排"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
```
|
||||
|
||||
#### 2. 三、实际行程情况(用户填写)
|
||||
|
||||
**修改前**:
|
||||
```vue
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际出行时间" prop="newStartDate">
|
||||
<el-date-picker v-model="form.newStartDate" ... />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="地点" prop="newDestination">
|
||||
<el-input v-model="form.newDestination" ... />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="在外停留时间">
|
||||
<!-- 日期范围选择器 -->
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
```
|
||||
|
||||
**修改后**:
|
||||
```vue
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="前往国家" prop="newDestination">
|
||||
<el-input v-model="form.newDestination" placeholder="请输入实际前往国家" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="出境事由" prop="newExitReason">
|
||||
<el-input v-model="form.newExitReason" placeholder="请输入实际出境事由" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="实际出行时间" prop="newStartDate">
|
||||
<el-date-picker
|
||||
v-model="newDateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="在外停留天数">
|
||||
<el-input :value="`${form.newDuration || 0}天`" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="行程安排" prop="newItinerary">
|
||||
<el-input
|
||||
v-model="form.newItinerary"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入实际行程安排"
|
||||
maxlength="1000"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
```
|
||||
|
||||
### 二、数据自动填充逻辑修改
|
||||
|
||||
**文件**: `web/src/views/rs/overseas/itinerary-change.vue`
|
||||
|
||||
**修改前**:
|
||||
```typescript
|
||||
// 填充申请行程情况
|
||||
state.form.originalDestination = selectedApplication.destination;
|
||||
state.form.originalDestinationCity = selectedApplication.destinationCity;
|
||||
state.form.originalExitReason = selectedApplication.exitReason || selectedApplication.purposeDetail;
|
||||
state.form.originalStartDate = selectedApplication.startDate;
|
||||
state.form.originalEndDate = selectedApplication.endDate;
|
||||
state.form.originalDuration = selectedApplication.duration;
|
||||
state.form.originalItinerary = selectedApplication.itinerary;
|
||||
```
|
||||
|
||||
**修改后**:
|
||||
```typescript
|
||||
// 填充申请行程情况
|
||||
// 前往国家:优先使用destinationCountry,其次使用destination
|
||||
state.form.originalDestination = selectedApplication.destinationCountry || selectedApplication.destination;
|
||||
state.form.originalDestinationCity = selectedApplication.destinationCity;
|
||||
// 出境事由:优先使用exitReason,其次使用purpose
|
||||
state.form.originalExitReason = selectedApplication.exitReason || selectedApplication.purpose;
|
||||
// 行程安排
|
||||
state.form.originalItinerary = selectedApplication.itinerary;
|
||||
state.form.originalStartDate = selectedApplication.startDate;
|
||||
state.form.originalEndDate = selectedApplication.endDate;
|
||||
state.form.originalDuration = selectedApplication.duration;
|
||||
|
||||
// 默认将原信息复制到新信息
|
||||
state.form.newDestination = selectedApplication.destinationCountry || selectedApplication.destination;
|
||||
state.form.newDestinationCity = selectedApplication.destinationCity;
|
||||
state.form.newExitReason = selectedApplication.exitReason || selectedApplication.purpose;
|
||||
state.form.newItinerary = selectedApplication.itinerary;
|
||||
state.form.newStartDate = selectedApplication.startDate;
|
||||
state.form.newEndDate = selectedApplication.endDate;
|
||||
state.form.newDuration = selectedApplication.duration;
|
||||
```
|
||||
|
||||
### 三、日期范围计算属性(新增)
|
||||
|
||||
**文件**: `web/src/views/rs/overseas/itinerary-change.vue`
|
||||
|
||||
**新增计算属性**(用于日期范围选择器的双向绑定):
|
||||
```typescript
|
||||
// 新出行时间日期范围(用于日期选择器的双向绑定)
|
||||
const newDateRange = computed({
|
||||
get() {
|
||||
if (state.form.newStartDate && state.form.newEndDate) {
|
||||
return [state.form.newStartDate, state.form.newEndDate];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
set(value: any) {
|
||||
if (value && value.length === 2) {
|
||||
state.form.newStartDate = value[0];
|
||||
state.form.newEndDate = value[1];
|
||||
} else {
|
||||
state.form.newStartDate = '';
|
||||
state.form.newEndDate = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- 日期选择器需要绑定一个数组 `[startDate, endDate]`
|
||||
- 计算属性的 `get` 方法将两个独立的日期字段组合成数组
|
||||
- 计算属性的 `set` 方法将数组拆分成两个独立的日期字段
|
||||
- 现有的 `watch` 监听 `newStartDate` 和 `newEndDate` 自动计算天数
|
||||
|
||||
### 四、变更类型自动识别逻辑增强
|
||||
|
||||
**文件**: `web/src/views/rs/overseas/itinerary-change.vue`
|
||||
|
||||
**修改前**:
|
||||
```typescript
|
||||
// 自动识别变更类型
|
||||
const changeTypeList: string[] = [];
|
||||
if (state.form.newDestination !== state.form.originalDestination) {
|
||||
changeTypeList.push('目的地变更');
|
||||
}
|
||||
if (state.form.newStartDate !== state.form.originalStartDate ||
|
||||
state.form.newEndDate !== state.form.originalEndDate) {
|
||||
changeTypeList.push('时间变更');
|
||||
}
|
||||
if (state.form.newItinerary && state.form.newItinerary !== state.form.originalItinerary) {
|
||||
changeTypeList.push('行程变更');
|
||||
}
|
||||
```
|
||||
|
||||
**修改后**:
|
||||
```typescript
|
||||
// 自动识别变更类型
|
||||
const changeTypeList: string[] = [];
|
||||
if (state.form.newDestination !== state.form.originalDestination) {
|
||||
changeTypeList.push('目的地变更');
|
||||
}
|
||||
if (state.form.newExitReason !== state.form.originalExitReason) {
|
||||
changeTypeList.push('出境事由变更'); // 新增
|
||||
}
|
||||
if (state.form.newStartDate !== state.form.originalStartDate ||
|
||||
state.form.newEndDate !== state.form.originalEndDate) {
|
||||
changeTypeList.push('时间变更');
|
||||
}
|
||||
if (state.form.newItinerary && state.form.newItinerary !== state.form.originalItinerary) {
|
||||
changeTypeList.push('行程变更');
|
||||
}
|
||||
```
|
||||
|
||||
### 四、表单验证规则调整
|
||||
|
||||
**文件**: `web/src/views/rs/overseas/itinerary-change.vue`
|
||||
|
||||
**修改前**:
|
||||
```typescript
|
||||
rules: {
|
||||
applicationId: [{ required: true, message: '请选择原出国申请', trigger: 'change' }],
|
||||
newDestination: [{ required: true, message: '请输入实际目的地', trigger: 'blur' }],
|
||||
newStartDate: [{ required: true, message: '请选择实际出行日期', trigger: 'change' }],
|
||||
changeReason: [{ required: true, message: '请输入变更原因', trigger: 'blur' }]
|
||||
}
|
||||
```
|
||||
|
||||
**修改后**:
|
||||
```typescript
|
||||
rules: {
|
||||
applicationId: [{ required: true, message: '请选择原出国申请', trigger: 'change' }],
|
||||
newDestination: [{ required: true, message: '请输入实际前往国家', trigger: 'blur' }],
|
||||
newExitReason: [{ required: true, message: '请输入实际出境事由', trigger: 'blur' }], // 新增
|
||||
newItinerary: [{ required: true, message: '请输入实际行程安排', trigger: 'blur' }], // 新增
|
||||
changeReason: [{ required: true, message: '请输入变更原因', trigger: 'blur' }]
|
||||
}
|
||||
```
|
||||
|
||||
## 📦 涉及文件清单
|
||||
|
||||
### 前端代码(1个文件)
|
||||
1. `web/src/views/rs/overseas/itinerary-change.vue` - 表单页面
|
||||
|
||||
### 数据库和后端
|
||||
- **无需修改** - 字段已存在
|
||||
|
||||
## 🎨 新字段展示效果
|
||||
|
||||
### 二、申请行程情况(只读)
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 二、申请行程情况 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 前往国家: [只读] 出境事由: [只读] │
|
||||
│ 申请出行时间: [只读] 在外停留天数: [只读] │
|
||||
│ 行程安排: [只读-多行文本框] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 三、实际行程情况(可编辑)
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 三、实际行程情况 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ 前往国家: [输入框] 出境事由: [输入框] │
|
||||
│ 实际出行时间: [日期范围选择器] 在外停留天数: [自动计算] │
|
||||
│ 行程安排: [多行文本框,1000字限制] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🔄 数据流程
|
||||
|
||||
```
|
||||
1. 用户选择原出国申请
|
||||
↓
|
||||
2. 调用 getOverseasApplication(applicationId) 获取申请详情
|
||||
↓
|
||||
3. handleApplicationChange 函数自动填充
|
||||
- 前往国家:destinationCountry 或 destination
|
||||
- 出境事由:exitReason 或 purpose
|
||||
- 行程安排:itinerary
|
||||
↓
|
||||
4. 用户填写实际情况
|
||||
- 前往国家(必填)
|
||||
- 出境事由(必填)
|
||||
- 行程安排(必填,最多1000字)
|
||||
↓
|
||||
5. 系统自动识别变更类型
|
||||
- 目的地变更
|
||||
- 出境事由变更 ← 新增
|
||||
- 时间变更
|
||||
- 行程变更
|
||||
↓
|
||||
6. 提交保存
|
||||
```
|
||||
|
||||
## 📊 字段映射关系
|
||||
|
||||
### 出国申请表 → 行程变更表(原信息)
|
||||
|
||||
| 出国申请表字段 | 行程变更表字段 | 显示标签 | 说明 |
|
||||
|---------------|---------------|---------|------|
|
||||
| destinationCountry / destination | original_destination | 前往国家 | 优先使用destinationCountry |
|
||||
| exitReason / purpose | original_exit_reason | 出境事由 | 优先使用exitReason |
|
||||
| itinerary | original_itinerary | 行程安排 | 多行文本 |
|
||||
|
||||
### 用户填写 → 行程变更表(新信息)
|
||||
|
||||
| 用户输入 | 行程变更表字段 | 显示标签 | 验证规则 |
|
||||
|---------|---------------|---------|---------|
|
||||
| 前往国家 | new_destination | 前往国家 | 必填 |
|
||||
| 出境事由 | new_exit_reason | 出境事由 | 必填 |
|
||||
| 行程安排 | new_itinerary | 行程安排 | 必填,最多1000字 |
|
||||
|
||||
## 🆚 修改对比
|
||||
|
||||
### 修改前后对比表
|
||||
|
||||
| 项目 | 修改前 | 修改后 |
|
||||
|-----|-------|-------|
|
||||
| **二、申请行程情况** | | |
|
||||
| 第一行 | 申请出行时间、地点 | 前往国家、出境事由 |
|
||||
| 第二行 | 在外停留时间 | 申请出行时间、在外停留天数 |
|
||||
| 第三行 | - | 行程安排(多行) |
|
||||
| **三、实际行程情况** | | |
|
||||
| 第一行 | 实际出行时间、地点 | 前往国家、出境事由 |
|
||||
| 第二行 | 在外停留时间 | 实际出行时间(日期选择器)、在外停留天数(自动计算) |
|
||||
| 第三行 | - | 行程安排(多行) |
|
||||
| **验证规则** | | |
|
||||
| 必填字段 | 原申请、新目的地、新出行时间、变更原因 | 原申请、新国家、新事由、新行程、变更原因 |
|
||||
| **变更类型识别** | | |
|
||||
| 识别项目 | 目的地、时间、行程 | 目的地、出境事由(新增)、时间、行程 |
|
||||
|
||||
## ✅ 优化亮点
|
||||
|
||||
1. **字段展示完整** - 保留了出行时间和停留天数,同时增加了前往国家、出境事由、行程安排
|
||||
2. **布局更合理** - 行程安排使用全宽多行文本框,便于显示完整内容
|
||||
3. **验证更完善** - 三个核心字段均为必填,确保信息完整性
|
||||
4. **变更识别增强** - 增加了"出境事由变更"的自动识别
|
||||
5. **字段映射灵活** - 兼容新旧两种API字段命名(destinationCountry/destination、exitReason/purpose)
|
||||
6. **用户体验优化** - 多行文本框带字数限制和计数器
|
||||
|
||||
## 🧪 测试要点
|
||||
|
||||
### 1. 数据自动填充测试
|
||||
- [ ] 选择原出国申请后,"前往国家"正确填充(二、三部分)
|
||||
- [ ] 选择原出国申请后,"出境事由"正确填充(二、三部分)
|
||||
- [ ] 选择原出国申请后,"申请出行时间"正确填充(二部分,只读)
|
||||
- [ ] 选择原出国申请后,"实际出行时间"正确填充(三部分,可编辑)
|
||||
- [ ] 选择原出国申请后,"在外停留天数"正确填充(二、三部分)
|
||||
- [ ] 选择原出国申请后,"行程安排"正确填充(二、三部分)
|
||||
- [ ] 字段以只读方式显示
|
||||
|
||||
### 2. 用户输入测试
|
||||
- [ ] "前往国家"输入框正常工作
|
||||
- [ ] "出境事由"输入框正常工作
|
||||
- [ ] "实际出行时间"日期范围选择器正常工作
|
||||
- [ ] 修改日期后,"在外停留天数"自动更新
|
||||
- [ ] 选择跨度天数计算正确(含起止日)
|
||||
- [ ] "行程安排"多行文本框正常工作
|
||||
- [ ] 字数限制(1000字)正常工作
|
||||
- [ ] 字数计数器正常显示
|
||||
|
||||
### 3. 表单验证测试
|
||||
- [ ] 未填写"前往国家"时显示错误提示
|
||||
- [ ] 未填写"出境事由"时显示错误提示
|
||||
- [ ] 未填写"行程安排"时显示错误提示
|
||||
|
||||
### 4. 变更类型识别测试
|
||||
- [ ] 修改"前往国家"后,识别为"目的地变更"
|
||||
- [ ] 修改"出境事由"后,识别为"出境事由变更"
|
||||
- [ ] 修改"行程安排"后,识别为"行程变更"
|
||||
- [ ] 同时修改多项时,正确组合变更类型
|
||||
|
||||
### 5. 数据保存测试
|
||||
- [ ] 提交后,新信息正确保存到数据库
|
||||
- [ ] 查看详情时,字段正确显示
|
||||
- [ ] 编辑已有变更时,字段正确回显
|
||||
|
||||
## 📝 完成状态
|
||||
|
||||
✅ 前端表单UI修改完成
|
||||
✅ 数据自动填充逻辑更新完成
|
||||
✅ 变更类型识别逻辑增强完成
|
||||
✅ 表单验证规则调整完成
|
||||
✅ 无编译错误和警告
|
||||
|
||||
---
|
||||
|
||||
**修改完成时间**:2025-10-13
|
||||
**涉及文件数量**:1个
|
||||
**测试状态**:待测试
|
||||
|
||||
Reference in new issue
Block a user