import axios, { AxiosInstance, AxiosResponse } from 'axios' import { store } from '../store' import { clearCredentials, setCredentials } from '../store/slices/authSlice' let isRefreshing = false let pendingQueue: Array<(token: string) => void> = [] const instance: AxiosInstance = axios.create({ baseURL: '/api', timeout: 10000 }) instance.interceptors.request.use(config => { const token = store.getState().auth.accessToken if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) instance.interceptors.response.use( (response: AxiosResponse) => { const data = response.data if (data.code !== undefined && data.code !== 200) { return Promise.reject(new Error(data.message || '请求失败')) } return data.data }, async error => { const originalRequest = error.config if (error.response?.status === 401 && !originalRequest._retry) { originalRequest._retry = true const refreshToken = store.getState().auth.refreshToken if (!refreshToken) { store.dispatch(clearCredentials()) window.location.href = '/login' return Promise.reject(error) } if (isRefreshing) { return new Promise(resolve => { pendingQueue.push((token: string) => { originalRequest.headers.Authorization = `Bearer ${token}` resolve(instance(originalRequest)) }) }) } isRefreshing = true try { const res = await axios.post('/api/auth/refresh', { refreshToken }) const newToken = res.data.data.accessToken store.dispatch(setCredentials({ accessToken: newToken, refreshToken, userInfo: store.getState().auth.userInfo! })) pendingQueue.forEach(cb => cb(newToken)) pendingQueue = [] originalRequest.headers.Authorization = `Bearer ${newToken}` return instance(originalRequest) } catch { store.dispatch(clearCredentials()) window.location.href = '/login' return Promise.reject(error) } finally { isRefreshing = false } } return Promise.reject(error) } ) export default instance