From be496ab375e59dd6bb8b46e9b136b65e9708758a Mon Sep 17 00:00:00 2001 From: owenchen Date: Thu, 24 Sep 2026 08:56:30 +0800 Subject: [PATCH] ow --- WebVue/src/utils/request.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/WebVue/src/utils/request.ts b/WebVue/src/utils/request.ts index 05aedde..6f7d2a8 100644 --- a/WebVue/src/utils/request.ts +++ b/WebVue/src/utils/request.ts @@ -49,9 +49,7 @@ service.interceptors.request.use( } return config; }, - (error) => { - Promise.reject(error); - } + (error) => Promise.reject(error), ); /** @@ -119,10 +117,10 @@ service.interceptors.response.use( return Promise.reject(error); } + // ① 只把「刷新令牌」放进 try。 + // 刷新失败(RefreshToken 过期/被作废/网络异常)才需要清登录态。 try { await refreshTokenOnce(); - //令牌成功刷新后,再次调用之前请求(请求拦截器会带上新令牌) - return await service.request(originalConfig); } catch (refreshError) { // 刷新失败必须 reject:原来 return Promise.resolve() 会让业务拿到 undefined // 当成功处理;这里清登录态跳登录页,并把错误抛给调用方。 @@ -131,9 +129,16 @@ service.interceptors.response.use( goLogin(!!(e && (e.status || e.response))); return Promise.reject(refreshError ?? error); } + + // ② 重试请求放在 try 之外。 + // 它自身的失败(500/403/网络抖动等)只应让这一次业务请求失败, + // 不能当成「刷新失败」处理,否则会把已成功续期的用户莫名踢下线。 + // 这里直接 return,让错误冒泡到外层 request() 的 catch 里, + // 复用已有的业务异常通知逻辑(ValidatedException / ServiceErrorException 等)。 + return await service.request(originalConfig); } return Promise.reject(error); - } + }, ); /** @@ -144,7 +149,7 @@ service.interceptors.response.use( */ export const request = async ( config: AxiosRequestConfig, - options: RequestOptions = {} + options: RequestOptions = {}, ): Promise => { try { const { isGetDataDirectly = true } = options; @@ -152,25 +157,21 @@ export const request = async ( const res = await service.request(config); if (res) { - if ( res.data && (res.data.SourceCode == "CloudBuilder.Core.ValidatedException" || res.data.SourceCode == "CloudBuilder.Core.ServiceErrorException") ) { - let msg = res.data.Message; if (res.data.SourceCode == "CloudBuilder.Core.ValidatedException") { warnNotificationWithIcon(msg); } if (res.data.SourceCode == "CloudBuilder.Core.ServiceErrorException") { - errorNotificationWithIcon(msg); } return Promise.reject(res); } - // res 是 AxiosResponse,取 data 才是业务数据;这里断言成 T 消除类型报错(原代码就有) return (isGetDataDirectly ? res.data : res) as T; } else { @@ -285,7 +286,7 @@ export const download = async (d: { link.href = downloadUrl; link.setAttribute( "download", - d.filename + dayjs().format("YYYYMMDDHHmmss") + ".xlsx" + d.filename + dayjs().format("YYYYMMDDHHmmss") + ".xlsx", ); document.body.appendChild(link); link.click(); @@ -299,7 +300,6 @@ export const download = async (d: { }); }; - const errorNotificationWithIcon = (message: string) => { notification.error({ message: t("request.notification.errorMessage"),