From 0fca4bd996b52cb7671a0c473eee455d2eb960db Mon Sep 17 00:00:00 2001 From: qubiaobiao <3294694717@qq.com> Date: Wed, 30 Sep 2026 12:57:55 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui):=20=E5=85=B6=E4=BD=99=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA=E6=94=B6=E6=95=9B=E4=B8=BA?= =?UTF-8?q?=E3=80=8C=E6=8B=A6=E6=88=AA=E5=99=A8=E7=BB=9F=E4=B8=80=E5=BC=B9?= =?UTF-8?q?=E3=80=8D=EF=BC=8C=E6=B6=88=E9=99=A4=E5=90=8C=E6=97=8F=E5=8F=8C?= =?UTF-8?q?=E5=BC=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 承接 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 全部保留。 --- src/api/request.js | 15 +++++++++++++++ src/views/Activate.vue | 16 ++++++++++------ src/views/Competition.vue | 16 ++++++++++------ src/views/Dashboard.vue | 8 ++++++-- src/views/ForgotPassword.vue | 16 ++++++++++------ src/views/Login.vue | 10 ++++++---- 6 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/api/request.js b/src/api/request.js index b6e4b52..d7237d2 100644 --- a/src/api/request.js +++ b/src/api/request.js @@ -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( diff --git a/src/views/Activate.vue b/src/views/Activate.vue index 283c9a0..0fff4b8 100644 --- a/src/views/Activate.vue +++ b/src/views/Activate.vue @@ -199,6 +199,10 @@