import axios from 'axios' import tokenManager from '@gold/utils/token-manager' // Token白名单 const WHITE_LIST = [ '/auth/login', '/auth/send-sms-code', '/auth/sms-login', '/auth/validate-sms-code', '/auth/register', '/auth/reset-password', '/auth/refresh-token', ] function isInWhiteList(url) { return !!(url && WHITE_LIST.some(path => url.includes(path))) } // Token刷新状态管理 let isRefreshing = false let refreshSubscribers = [] function subscribeTokenRefresh(callback) { isRefreshing ? refreshSubscribers.push(callback) : callback() } function onRefreshed() { refreshSubscribers.forEach(callback => callback()) refreshSubscribers = [] } /** * 创建Axios实例 * @param {Object} options - 配置选项 * @param {string} options.baseURL - 基础URL * @param {number} options.timeout - 超时时间 * @param {Function} options.on401 - 401错误处理函数 * @param {Function} options.on403 - 403错误处理函数 * @param {Function} options.refreshTokenFn - Token刷新函数 * @returns {AxiosInstance} Axios实例 */ export default function createClientAxios(options = {}) { const { baseURL = '/', timeout = 180000, on401 = null, on403 = null, refreshTokenFn = null, } = options const client = axios.create({ baseURL, timeout, }) // 请求拦截器 client.interceptors.request.use((config) => { const needToken = config.headers?.isToken !== false && !isInWhiteList(config.url || '') if (!needToken) { return config } const currentToken = tokenManager.getAccessToken() if (!currentToken) { return config } const isTokenExpired = tokenManager.isExpired(30 * 1000) if (!isTokenExpired) { const authHeader = tokenManager.getAuthHeader() if (authHeader) { config.headers.Authorization = authHeader } return config } if (!isRefreshing) { isRefreshing = true if (!refreshTokenFn || typeof refreshTokenFn !== 'function') { isRefreshing = false onRefreshed() return config } refreshTokenFn().finally(() => { isRefreshing = false onRefreshed() }) } return new Promise((resolve, reject) => { subscribeTokenRefresh(() => { const token = tokenManager.getAccessToken() if (!token) { return reject({ message: 'Token已过期,需要重新登录', code: 401, }) } config.headers.Authorization = tokenManager.getAuthHeader() resolve(config) }) }) }) // 响应拦截器 client.interceptors.response.use( (response) => { const data = response.data if (data && typeof data.code === 'number') { if (data.code === 0 || data.code === 200) { return data } const error = new Error(data?.message || data?.msg || '请求失败') error.code = data?.code error.data = data if (data.code === 403 && typeof on403 === 'function') { on403(error) } if (data.code === 401 && typeof on401 === 'function') { refreshTokenFn && refreshTokenFn() } return Promise.reject(error) } return data }, (error) => { const status = error.response?.status const code = error.code if ((status === 401 || code === 401) && typeof on401 === 'function') { on401(error) } else if ((status === 403 || code === 403) && typeof on403 === 'function') { on403(error) } return Promise.reject(error) } ) return client }