diff --git a/src/api/index.ts b/src/api/index.ts index f2ddca9c..ff76b5e4 100755 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -3,6 +3,18 @@ import axios from 'axios' // import qs from 'qs' import { toast } from 'vue-sonner' +// 请求重试配置 +const MAX_RETRY_COUNT = 3 // 最大重试次数 +const RETRY_DELAY = 1000 // 重试延迟时间(毫秒) + +// 扩展 AxiosRequestConfig 类型 +declare module 'axios' { + export interface AxiosRequestConfig { + retry?: boolean + retryCount?: number + } +} + const api = axios.create({ baseURL: (import.meta.env.DEV && import.meta.env.VITE_OPEN_PROXY) ? '/proxy/' : import.meta.env.VITE_APP_API_BASEURL, timeout: 1000 * 60, @@ -29,6 +41,28 @@ api.interceptors.request.use( }, ) +// 处理错误信息的函数 +function handleError(error: any) { + if (error.status === 401) { + useUserStore().requestLogout() + throw error + } + let message = error.message + if (message === 'Network Error') { + message = '后端网络故障' + } + else if (message.includes('timeout')) { + message = '接口请求超时' + } + else if (message.includes('Request failed with status code')) { + message = `接口${message.substr(message.length - 3)}异常` + } + toast.error('Error', { + description: message, + }) + return Promise.reject(error) +} + api.interceptors.response.use( (response) => { /** @@ -50,25 +84,31 @@ api.interceptors.response.use( } return Promise.resolve(response.data) }, - (error) => { - if (error.status === 401) { - useUserStore().requestLogout() - throw error + async (error) => { + // 获取请求配置 + const config = error.config + + // 如果配置不存在或未启用重试,则直接处理错误 + if (!config || !config.retry) { + return handleError(error) } - let message = error.message - if (message === 'Network Error') { - message = '后端网络故障' + + // 设置重试次数 + config.retryCount = config.retryCount || 0 + + // 判断是否超过重试次数 + if (config.retryCount >= MAX_RETRY_COUNT) { + return handleError(error) } - else if (message.includes('timeout')) { - message = '接口请求超时' - } - else if (message.includes('Request failed with status code')) { - message = `接口${message.substr(message.length - 3)}异常` - } - toast.error('Error', { - description: message, - }) - return Promise.reject(error) + + // 重试次数自增 + config.retryCount += 1 + + // 延迟重试 + await new Promise(resolve => setTimeout(resolve, RETRY_DELAY)) + + // 重新发起请求 + return api(config) }, )