import axios from 'axios'; import type { InternalAxiosRequestConfig, AxiosResponse, AxiosRequestHeaders, } from 'axios'; import router from '@/router'; import { Message, Modal } from '@arco-design/web-vue'; import { useUserStore } from '@/store'; import { useAuth } from '@/utils/auth'; import { refreshToken } from '@/api/user'; const { getToken, getRefreshToken, setToken, clearToken } = useAuth(); let isRefreshing = false; let subscribers: ((token: string) => void)[] = []; function subscribeTokenRefresh(cb: (token: string) => void) { subscribers.push(cb); } function onRefreshed(token: string) { subscribers.forEach(cb => cb(token)); subscribers = []; } const instance = axios.create({ baseURL: '/', }); // 新增一个独立的函数来处理 Token 刷新 async function handleTokenRefresh( refreshTokenValue: string, originalConfig: InternalAxiosRequestConfig ) { isRefreshing = true; try { const res = await refreshToken({ token: refreshTokenValue }); if (res && res.data && res.success) { const { token: newAccessToken, refreshToken: newRefreshToken } = res.data; setToken(newAccessToken, newRefreshToken); onRefreshed(newAccessToken); // 重试原始请求 originalConfig.headers.Authorization = `${newAccessToken}`; return instance(originalConfig); } else { isRefreshing = false; clearToken(); router.push({ name: 'login' }); throw new Error('Invalid token refresh response'); } } catch (error) { Message.error('登录状态已过期,请重新登录'); clearToken(); router.push({ name: 'login' }); throw error; // 重新抛出错误,让外部拦截器可以继续处理 } finally { isRefreshing = false; } } instance.interceptors.request.use( (config: InternalAxiosRequestConfig) => { // let each request carry token // this example using the JWT token // Authorization is a custom headers key // please modify it according to the actual situation const token = getToken(); if (token) { if (!config.headers) { config.headers = {} as AxiosRequestHeaders; } config.headers.Authorization = `${token}`; } return config; }, error => { // do something return Promise.reject(error); } ); // 响应拦截器修复版本 instance.interceptors.response.use( (response: AxiosResponse) => { return response; }, async error => { const { config, response } = error; const refreshTokenValue = getRefreshToken(); if (!response) { // 网络错误处理 Message.error('网络连接异常'); return Promise.reject(error); } if (response.status === 401) { if (!isRefreshing) { isRefreshing = true; config._retry = true; if (refreshTokenValue) { return handleTokenRefresh(refreshTokenValue, config); } } else { return new Promise(resolve => { subscribeTokenRefresh((token: string) => { config.headers.Authorization = `${token}`; resolve(axios(config)); }); }); } } else if (response.status === 403) { Message.error('没有权限执行此操作'); // 可选:跳转到权限不足页面或首页 // router.push({ name: 'forbidden' }); } else if (response.status === 404) { Message.error('请求的资源不存在'); } else if (response.status >= 500) { Message.error('服务器内部错误,请稍后再试'); } else { Message.error( error.response?.data?.message || `请求错误: ${response.status}` ); } return Promise.reject(error); } ); export default instance;