# 出国行程变更申请功能优化说明 ## 📋 修改时间 2025-10-13 ## 🎯 修改目标 根据业务需求,优化出国行程变更申请流程: 1. ✅ 修改选项卡名称:"全部变更" → "变更申请","我的变更" → "变更记录" 2. ✅ 删除"变更记录"选项卡中的"新增变更申请"按钮 3. ✅ 修改新增变更申请逻辑:从选择"出国记录"改为选择"已审批通过的出国申请" 4. ✅ 流程优化:通过出国申请菜单下已审批通过的申请创建变更申请 ## 📝 详细修改内容 ### 一、前端修改 #### 1. 页面UI优化 (`web/src/views/rs/overseas/itinerary-change.vue`) **选项卡名称修改**: - `` → `` - `` → `` **移除"变更记录"选项卡中的新增按钮**: ```vue 新增变更申请 ``` **修改新增变更申请弹窗**: ```vue ``` #### 2. 业务逻辑调整 **数据结构变更**: ```typescript // 修改前 availableRecordList: [] as OverseasRecordVO[] // 修改后 availableApplicationList: [] as OverseasApplicationVO[] ``` **API调用变更**: ```typescript // 修改前 import { getAvailableOverseasRecords, getOverseasRecordForChange } // 修改后 import { getApprovedOverseasApplications, getOverseasApplication } ``` **方法更新**: - `getAvailableRecordList()` → `getApprovedApplicationList()` - `handleRecordChange(recordId)` → `handleApplicationChange(applicationId)` - 验证规则:`recordId` → `applicationId` #### 3. API接口更新 (`web/src/api/rs/overseas.ts`) **新增API方法**: ```typescript // 获取已审批通过的出国申请列表(用于行程变更申请选择) export function getApprovedOverseasApplications() { return request({ url: '/rs/overseas/application/status/1', method: 'get' }); } ``` **类型定义修改**: ```typescript export interface ItineraryChangeForm { changeId?: number | string; recordId: number; // ❌ 删除/废弃 applicationId: number; // ✅ 新增必填 // ... 其他字段保持不变 } ``` ### 二、后端修改 #### 1. BO类修改 (`RsOverseasItineraryChangeBo.java`) **字段验证调整**: ```java // 修改前 @NotNull(message = "关联备案记录ID不能为空", groups = { AddGroup.class, EditGroup.class }) private Long recordId; private Long applicationId; // 修改后 /** * 关联备案记录ID(外键,关联rs_overseas_entry_exit_record.record_id) * 注:该字段已废弃,现在使用applicationId */ private Long recordId; /** * 关联出国申请ID(外键,关联rs_overseas_application.application_id) */ @NotNull(message = "关联出国申请ID不能为空", groups = { AddGroup.class, EditGroup.class }) private Long applicationId; ``` #### 2. Service实现修改 (`RsOverseasItineraryChangeServiceImpl.java`) **依赖注入调整**: ```java // 新增 private final IRsOverseasApplicationService applicationService; // 删除(不再使用) // private final IRsOverseasRecordService recordService; ``` **新增逻辑修改**: ```java // 修改前:基于recordId查询出国记录 RsOverseasRecordVo record = recordService.queryById(bo.getRecordId()); if (record == null) { throw new ServiceException("出国记录不存在"); } // 修改后:基于applicationId查询出国申请 RsOverseasApplicationVo application = applicationService.queryById(bo.getApplicationId()); if (application == null) { throw new ServiceException("出国申请不存在"); } // 新增:检查申请状态 if (!"1".equals(application.getStatus())) { throw new ServiceException("只能为已通过审批的出国申请提交变更申请"); } ``` **数据来源变更**: ```java // 修改前:从出国记录复制原始信息 entity.setOriginalDestination(record.getDestination()); entity.setOriginalStartDate(record.getActualStartDate()); entity.setOriginalEndDate(record.getActualEndDate()); entity.setOriginalDuration(record.getActualDuration()); // 修改后:从出国申请复制原始信息 entity.setOriginalDestination(application.getDestination()); entity.setOriginalStartDate(application.getStartDate()); entity.setOriginalEndDate(application.getEndDate()); entity.setOriginalDuration(application.getDuration()); ``` **查重逻辑修改**: ```java // 修改前:检查recordId wrapper.eq(RsOverseasItineraryChange::getRecordId, bo.getRecordId()) // 修改后:检查applicationId wrapper.eq(RsOverseasItineraryChange::getApplicationId, bo.getApplicationId()) ``` ## 🔄 业务流程对比 ### 修改前流程 1. 用户在"出国申请"菜单中提交出国申请 2. 申请通过审批后,在"出国记录"选项卡中生成记录 3. 用户在"行程变更"菜单中,选择"出国记录"创建变更申请 4. 变更申请提交到审批流程 ### 修改后流程 1. 用户在"出国申请"菜单中提交出国申请 2. 申请通过审批后(状态=1) 3. 用户在"行程变更申请"选项卡中,**直接选择已审批通过的出国申请**创建变更申请 4. 变更申请提交到审批流程 5. 用户在"变更记录"选项卡中查看自己的变更历史 ## ✨ 优化亮点 1. **简化流程**:不再依赖"出国记录",直接从已审批申请创建变更 2. **状态验证**:后端强制检查申请状态为"已通过"(status=1)才能创建变更 3. **UI优化**: - 选择框支持筛选(`filterable`) - 清晰的选项卡命名(变更申请/变更记录) - "变更记录"仅查看,不允许新增 4. **数据一致性**:直接从原始申请复制数据,避免中间环节 5. **权限控制**:保持原有权限体系不变 ## 🧪 测试建议 ### 前端测试 1. ✅ 验证选项卡名称显示正确 2. ✅ 验证"变更记录"选项卡无新增按钮 3. ✅ 验证新增弹窗显示已审批通过的申请列表 4. ✅ 验证选择申请后自动填充原始信息 5. ✅ 验证筛选功能正常工作 ### 后端测试 1. ✅ 验证必填字段从recordId改为applicationId 2. ✅ 验证只能选择status=1的申请 3. ✅ 验证相同申请不能重复提交待审核的变更 4. ✅ 验证数据来源为出国申请而非出国记录 5. ✅ 验证编译通过无警告错误 ## 📦 涉及文件清单 ### 前端 - `web/src/views/rs/overseas/itinerary-change.vue` - 主页面组件 - `web/src/api/rs/overseas.ts` - API接口定义 ### 后端 - `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/domain/bo/RsOverseasItineraryChangeBo.java` - BO类 - `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/service/impl/RsOverseasItineraryChangeServiceImpl.java` - Service实现 ## ⚠️ 注意事项 1. **数据库兼容性**:`record_id`字段保留但不再必填,`application_id`字段成为必填 2. **向后兼容**:已有的变更记录仍然可以正常查看和处理 3. **权限不变**:所有权限配置保持原样,无需重新配置 4. **API不变**:后端API路径和返回格式保持不变 ## 🎉 完成状态 ✅ 所有修改已完成并通过编译验证 ✅ 前端TypeScript类型检查通过 ✅ 后端Java编译成功 ✅ 业务逻辑符合需求 ✅ 代码质量良好(无警告)