import axios, { type AxiosInstance } from 'axios' const API_BASE = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000' const api: AxiosInstance = axios.create({ baseURL: `${API_BASE}/api/v1`, timeout: 15000, headers: { 'Content-Type': 'application/json' }, }) // 请求拦截器:附加 Token api.interceptors.request.use((config) => { const token = localStorage.getItem('access_token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) // 防止并发刷新 let refreshPromise: Promise | null = null // 响应拦截器:处理 401 自动刷新 api.interceptors.response.use( (response) => response, async (error) => { const originalRequest = error.config if (error.response?.status === 401 && !originalRequest._retry) { originalRequest._retry = true const refreshToken = localStorage.getItem('refresh_token') if (!refreshToken) { // 没有 refresh token,直接跳转登录 localStorage.removeItem('access_token') localStorage.removeItem('refresh_token') window.location.href = '/login' return Promise.reject(error) } try { // 如果已经有正在进行的刷新请求,复用它 if (!refreshPromise) { refreshPromise = axios.post(`${API_BASE}/api/v1/auth/refresh`, { refresh_token: refreshToken, }) } const { data } = await refreshPromise refreshPromise = null // 更新 token localStorage.setItem('access_token', data.access_token) localStorage.setItem('refresh_token', data.refresh_token) // 重试原请求 originalRequest.headers.Authorization = `Bearer ${data.access_token}` return api(originalRequest) } catch (refreshError) { refreshPromise = null // 刷新失败,清除 token 并跳转登录 localStorage.removeItem('access_token') localStorage.removeItem('refresh_token') window.location.href = '/login' return Promise.reject(refreshError) } } return Promise.reject(error) }, ) export default api