import axios from 'axios' import type { AxiosInstance, InternalAxiosRequestConfig, AxiosResponse } from 'axios' import { ElMessage } from 'element-plus' import { useAuthStore } from '@/stores/auth' import { getToken, getRefreshToken } from '@/utils/auth' import router from '@/router' // 创建axios实例 const request: AxiosInstance = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000', timeout: 30000, // 调整为 30 秒,避免长时间挂起 headers: { 'Content-Type': 'application/json' } }) // 请求拦截器 request.interceptors.request.use( (config: InternalAxiosRequestConfig) => { const token = getToken() if (token && config.headers) { config.headers.Authorization = `Bearer ${token}` } return config }, (error) => { return Promise.reject(error) } ) // 响应拦截器 request.interceptors.response.use( (response: AxiosResponse) => { const { code, message } = response.data ?? {} // 成功响应(兼容 code=0 和 code=200,以及无 code 的纯数据/Blob 返回) if (code === 0 || code === 200 || typeof code === 'undefined') { return response.data } // 业务错误 if (!response.config.headers?.['Skip-Error-Message']) { ElMessage.error(message || '请求失败') } return Promise.reject(new Error(message || '请求失败')) }, async (error) => { const { response } = error const skipErrorMessage = error.config?.headers?.['Skip-Error-Message'] if (response) { const { status, data } = response switch (status) { case 401: // 未授权,尝试刷新token const authStore = useAuthStore() const refreshToken = getRefreshToken() if (refreshToken && !error.config._retry) { error.config._retry = true try { const success = await authStore.refreshToken() if (success) { // 重新发送原请求 const token = getToken() if (token) { error.config.headers.Authorization = `Bearer ${token}` } return request(error.config) } } catch (refreshError) { console.error('刷新token失败:', refreshError) } } // 刷新失败或没有refresh token,跳转到登录页 await authStore.logout() router.push('/login') if (!skipErrorMessage) { ElMessage.error('登录已过期,请重新登录') } break case 403: if (!skipErrorMessage) ElMessage.error('权限不足') router.push('/unauthorized') break case 404: if (!skipErrorMessage) ElMessage.error('请求的资源不存在') break case 429: if (!skipErrorMessage) ElMessage.error('请求过于频繁,请稍后再试') break case 500: if (!skipErrorMessage) ElMessage.error('服务器内部错误') break default: if (!skipErrorMessage) ElMessage.error(data?.message || '请求失败') } } else { // 网络错误 if (!skipErrorMessage) { ElMessage.error('网络连接失败,请检查网络设置') } } return Promise.reject(error) } ) export default request