# 党籍保留审批通过失败问题排查指南 ## 问题描述 在"出国登记审批"菜单下的"登记审批"选项卡列表中,点击查看详情按钮弹窗界面中的"审批通过",填写审批意见后点击"确认通过",提示"审批通过失败"。 ## 已完成的排查工作 ### 1. 后端接口验证 ✅ - **接口路径**: `PUT /rs/party/retention/approve/{retentionId}` - **接口实现**: `RsPartyMembershipRetentionController.approve()` - **日志显示**: 请求成功执行,耗时231毫秒 ```log 2025-10-10 10:49:41 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[PUT /rs/party/retention/approve/5],参数类型[param],参数:[{"approved":["true"],"approvalOpinion":["同意"]}] 2025-10-10 10:49:41 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[PUT /rs/party/retention/approve/5],耗时:[231]毫秒 ``` ### 2. 数据库验证 ✅ - **表名**: `rs_party_membership_retention` - **更新字段**: - `status`: "1"(待审核)→ "2"(已通过) - `final_approval`: NULL → "同意" - `update_time`: 2025-10-10 10:49:41 - **结论**: 数据库更新成功 ### 3. 后端响应格式 ✅ - **Controller返回**: `toAjax(Boolean)` - **响应格式**: `{ code: 200, msg: "操作成功", data: null }` - **结论**: 后端返回正常的成功响应 ### 4. 前端响应拦截器 ✅ - **文件**: `web/src/utils/request.ts` - **成功判断条件** (第138-151行): ```typescript if ( code === HttpStatus.SUCCESS || // 200 code === 0 || code === 'SUCCESS' || resData.success === true || ... ) { return Promise.resolve(resData); } ``` - **HttpStatus.SUCCESS值**: 200(与后端一致) ## 问题定位 ### 可能原因1: PUT请求特殊处理 前端响应拦截器在第148行有个特殊判断: ```typescript (res.status === 200 && res.config?.method === 'get') ``` **仅对GET请求做了200状态的兼容处理,PUT/POST请求没有**! ### 可能原因2: 响应code丢失或格式错误 虽然后端返回 `code: 200`,但前端接收到的可能: - code被加密/解密过程改变 - code类型不匹配(字符串 vs 数字) - 响应被其他中间件拦截 ## 解决方案 ### 方案1: 添加详细日志(已实施)✅ 已在前端审批方法中添加 `console.log` 和 `console.error`: ```typescript // 审批通过 const submitApprove = async () => { approveDialog.loading = true; try { console.log('审批请求参数:', approveForm.value); const response = await approvePartyRetention(approveForm.value); console.log('审批响应数据:', response); ElMessage.success('审批通过成功'); // ... } catch (error) { console.error('审批通过失败详情:', error); const errorMsg = (error as any)?.message || (error as any)?.msg || '审批通过失败'; ElMessage.error(errorMsg); } } ``` **操作步骤**: 1. 刷新前端页面(Ctrl+F5 强制刷新) 2. 打开浏览器开发者工具(F12) 3. 切换到"Console"(控制台)标签 4. 再次测试审批功能 5. 查看控制台输出的详细信息: - 审批请求参数 - 审批响应数据 - 审批失败详情 ### 方案2: 修复响应拦截器(备选) 如果日志显示code确实是200,但仍进入错误处理,可以修改响应拦截器: ```typescript // web/src/utils/request.ts 第138行 if ( code === HttpStatus.SUCCESS || code === 0 || code === 'SUCCESS' || resData.success === true || (res.status === 200 && (resData.rows !== undefined || resData.total !== undefined || (resData.data && (resData.data.rows !== undefined || resData.data.total !== undefined || resData.data.list !== undefined)) || resData.list !== undefined)) || (res.status === 200 && res.config?.method === 'get') || // 新增:对PUT/POST等修改操作,如果HTTP状态码为200且有合法的msg字段,也视为成功 (res.status === 200 && resData.msg && !resData.rows && !resData.total) ) { return Promise.resolve(resData); } ``` ### 方案3: 后端返回更明确的成功标识(备选) 修改后端Controller: ```java @PutMapping("/approve/{retentionId}") public R approve(@NotNull(message = "主键不能为空") @PathVariable Long retentionId, @RequestParam String approvalOpinion, @RequestParam Boolean approved) { Boolean result = retentionService.approve(retentionId, approvalOpinion, approved); return result ? R.ok("审批成功") : R.fail("审批失败"); } ``` ## 下一步操作 ### 立即执行(推荐) 1. **刷新前端页面** ```bash # 在浏览器中按 Ctrl+F5 或 Cmd+Shift+R ``` 2. **打开浏览器控制台** - 按F12打开开发者工具 - 点击"Console"标签 3. **再次测试审批功能** - 进入"人事管理" → "出国登记审批" - 点击"登记审批"选项卡 - 点击某条记录的"查看详情"按钮 - 点击"审批通过" - 填写审批意见 - 点击"确认通过" 4. **查看控制台输出** - 找到 `审批请求参数:` - 找到 `审批响应数据:` 或 `审批通过失败详情:` - 将完整信息截图或复制出来 5. **根据日志分析** - 如果看到"审批响应数据",说明后端返回成功,问题在前端响应处理 - 如果看到"审批通过失败详情",查看error对象的具体内容 - 特别关注 `code`、`msg`、`message` 等字段的值 ### 备用方案 如果无法访问浏览器控制台,可以查看后端日志: ```bash cd /Users/weizzzz/Documents/Cursor/0828CURSOR/all-project/backend tail -f ruoyi-admin/logs/sys-info.log | grep -E "approve|审批" ``` ## 相关文件清单 ### 前端文件 - **审批页面**: `web/src/views/rs/party-membership-retention/approval.vue` - **API定义**: `web/src/api/rs/party-membership-retention.ts` - **请求拦截器**: `web/src/utils/request.ts` ### 后端文件 - **Controller**: `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/controller/RsPartyMembershipRetentionController.java` - **Service实现**: `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/service/impl/RsPartyMembershipRetentionServiceImpl.java` ### 数据库 - **表名**: `rs_party_membership_retention` - **关键字段**: `status`, `final_approval`, `update_time` ## 测试数据 ### 已测试记录 - **retention_id=5**: 审批时间 2025-10-10 10:49:41,状态已更新为"2"(已通过) - **retention_id=6**: 已重置为待审批状态,可用于测试 ### 状态值说明 - **0**: 草稿 - **1**: 待审核 - **2**: 已通过 - **3**: 已拒绝 - **4**: 已撤回 --- **修改时间**: 2025-10-10 **修改人**: AI Assistant **状态**: 待用户验证