import axios, { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; import { ElMessage, ElMessageBox } from 'element-plus'; import { Session } from '/@/utils/storage'; import qs from 'qs'; // 标记是否正在处理 token 过期,避免重复弹窗 let isHandlingTokenExpired = false; // 配置新建第一个 axios 实例(原来的主服务) const service: AxiosInstance = axios.create({ baseURL: import.meta.env.VITE_API_URL, timeout: 50000, headers: { 'Content-Type': 'application/json' }, paramsSerializer: { serialize(params) { return qs.stringify(params, { allowDots: true, arrayFormat: 'brackets' }); }, }, }); // 配置新建第二个 axios 实例(新功能服务) const newService: AxiosInstance = axios.create({ // baseURL: 'http://192.168.3.95:8000/', // baseURL: 'http://192.168.3.49:8000/', baseURL: 'http://192.168.3.11:8000/', // baseURL: 'http://192.168.3.200:8000/', timeout: 50000, headers: { 'Content-Type': 'application/json' }, paramsSerializer: { serialize(params) { return qs.stringify(params, { allowDots: true, arrayFormat: 'brackets' }); }, }, }); // token 过期处理函数 const handleTokenExpired = () => { if (isHandlingTokenExpired) return; isHandlingTokenExpired = true; ElMessageBox.alert('登录状态已过期,请重新登录', '提示', { confirmButtonText: '确定', showClose: false, closeOnClickModal: false, closeOnPressEscape: false, beforeClose: (action, instance, done) => { if (action === 'confirm') { done(); performLogout(); } }, }) .then(() => { performLogout(); }) .catch(() => { performLogout(); }); }; // 执行退出登录操作 const performLogout = () => { Session.clear(); localStorage.clear(); isHandlingTokenExpired = false; // 跳转到登录页,确保完全刷新 setTimeout(() => { window.location.href = '/'; }, 500); }; // 请求拦截器 const requestInterceptor = (config: InternalAxiosRequestConfig) => { // 检查 token 是否有效 const token = Session.get('token'); if (token) { // 可以在这里添加 token 有效性检查(如果需要) config.headers!['Authorization'] = `Bearer ${token}`; } return config; }; const requestErrorHandler = (error: any) => { return Promise.reject(error); }; // 响应拦截器 const responseInterceptor = (response: AxiosResponse) => { // 文件流响应直接返回 if ( response.config.responseType === 'blob' || response.headers['content-type']?.includes('application/zip') || response.headers['content-type']?.includes('application/octet-stream') ) { return response; } const res = response.data; const httpStatus = response.status; const code = res?.code; const message = res?.message; // 检查 token 相关错误 if ( httpStatus === 401 || code === 401 || message?.includes('token') || message === 'token is invalid' || message === 'token 解析失败' || message?.includes('decrypt error') ) { handleTokenExpired(); return Promise.reject(new Error('登录状态已过期')); } // 业务逻辑错误处理 if (code !== undefined && code !== 0 && code !== 200) { const errorMsg = message || `请求失败(${code})`; ElMessage.error(errorMsg); return Promise.reject(new Error(errorMsg)); } return res; }; // 响应错误拦截器 const responseErrorHandler = (error: any) => { console.error('API请求错误:', error); if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) { ElMessage.error('请求超时,请检查网络连接'); return Promise.reject(new Error('请求超时')); } if (!error.response) { if (error.message === 'Network Error') { // ElMessage.error('网络连接错误,请检查网络设置'); } else { // ElMessage.error('网络异常,请检查连接'); } return Promise.reject(error); } const httpStatus = error.response.status; const message = error.response.data?.message || error.response.statusText; // 处理 HTTP 错误状态 switch (httpStatus) { case 401: handleTokenExpired(); break; case 403: // ElMessage.error('没有权限访问该资源'); break; case 404: // ElMessage.error('请求的资源不存在'); break; case 500: // ElMessage.error('服务器内部错误'); break; case 502: // ElMessage.error('网关错误'); break; case 503: // ElMessage.error('服务不可用'); break; default: if (httpStatus >= 400) { ElMessage.error(message || `请求失败(${httpStatus})`); } } return Promise.reject(error); }; // 为实例添加拦截器 service.interceptors.request.use(requestInterceptor, requestErrorHandler); service.interceptors.response.use(responseInterceptor, responseErrorHandler); newService.interceptors.request.use(requestInterceptor, requestErrorHandler); newService.interceptors.response.use(responseInterceptor, responseErrorHandler); // 导出 export default service; export { newService };