fix(ui): 其余视图错误提示收敛为「拦截器统一弹」,消除同族双弹

承接 R64(Admin.vue)已定口径,本轮覆盖其余全部视图。

根因:src/api/request.js 响应拦截器已覆盖全部失败路径,且每种失败只弹一次
⇒ 调用方 catch 内再 ElMessage.error 即必然双弹。helper.error 不改 HTTP 状态,
故删除调用方提示不会丢后端文案。

删除 11 处重复提示(跨 5 文件):
- Login.vue        管理员登录 catch(adminLogin 未传 silent ⇒ 拦截器必弹)
- Activate.vue     handleStep1 / handleActivate / resendSms
- ForgotPassword.vue  handleStep1 / handleReset / resendSms
- Competition.vue  submitUploadFiles / deleteUploadedWork / onMounted 外层 catch
- Dashboard.vue    enterContest(warning 形态,同族)

刻意保留(已有显式理由,不得误删):
- silent 路径调用方唯一提示:Login 选手登录、Competition 大题加载/保存/交卷/自动交卷
- 客户端校验(未发请求)、原生 fetch(MockExam 样例模板)、独立 axios 实例(Materials)、
  el-upload on-success(Admin)

另:
- src/api/request.js 增补「错误提示口径」权威块(全站单一源 + 四类例外),
  五个视图各加一行口径指针注释,防回退。
- 无行为变更:仅移除重复提示,finally/return/refreshCaptcha/router.push 全部保留。
This commit is contained in:
2026-09-30 12:57:55 +08:00
parent ff7137aab6
commit 0fca4bd996
6 changed files with 57 additions and 24 deletions

View File

@@ -148,6 +148,21 @@ export function initProactiveTokenRefresh() {
}
}
// ==================== 错误提示口径(R64/R65 收敛 · 全站唯一权威) ====================
// 🔴 本拦截器已覆盖**全部**失败路径,且每种失败**只弹一次**:
// 业务码 ≠0/≠200 → `res.message`;403/404/500 → 固定文案;其它 HTTP 码 →
// `data.message`;超时(ECONNABORTED);无 response 的网络层错误。
// ⇒ **调用方 catch 内不要再 `ElMessage.error(...)`**,否则用户同时看到两条 = 同族双弹。
// ⇒ 已按此口径收敛:Admin.vue、Login.vue、Activate.vue、ForgotPassword.vue、
// Competition.vue、Dashboard.vue。
// 例外(**必须**由调用方负责提示,出现时须显式注明原因):
// ① 请求带 `silent: true` ⇒ 拦截器不说话,调用方是唯一提示方
// (登录 / 交卷 / 逐题保存 / 大题加载与保存 / 两个 Excel 导入 / resetTestData);
// ② 客户端校验失败(**根本没发请求**);
// ③ 非 axios 路径:`utils/download.js`(独立实例、不挂本拦截器)、原生 `fetch`、
// el-upload 的 on-success 手工判响应;
// ④ 401 由 `forceLogout()` 提示,**不受 `silent` 影响**(token 真失效必须让用户看到)。
// ==================== 响应拦截器 ====================
request.interceptors.response.use(