import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'; import { ElMessage as Message, ElMessageBox as MessageBox, ElLoading as Loading } from 'element-plus'; import tokenInfo from '@/stores/modules/token'; import useUserInfo from "@/stores/modules/user"; // 加载动画的并发管理 const activeRequests = new Set(); let loadingObj = null; /** * 关闭加载动画 * 当所有请求完成时,关闭加载动画 */ function loadingClose(requestId: string) { activeRequests.delete(requestId); if (activeRequests.size === 0 && loadingObj) { loadingObj.close(); loadingObj = null } } /** * 创建一个axios实例,用于发送HTTP请求 * 配置了请求拦截器和响应拦截器,支持加载动画和错误提示 */ const service = axios.create({ timeout: 5000, // 设置请求超时时间 baseURL: '__API__', }); console.log('__API__'); // 请求拦截器 service.interceptors.request.use( (config: AxiosRequestConfig) => { // 在发送请求之前做些什么,例如添加 token const tokenInfoStore = tokenInfo(); const token = tokenInfoStore.getToken; // 使用 getToken() 获取 token if (token) { config.headers['Authorization'] = `Bearer ${token}`; } // 如果配置中启用了加载动画,则显示加载动画 if (config.loading) { const requestId = `${Date.now()}-${Math.random()}`; activeRequests.add(requestId); if (activeRequests.size === 1) { loadingObj = Loading.service({ lock: true, text: '请稍候', background: 'rgba(0, 0, 0, 0)', }); } config.requestId = requestId; // 将 requestId 挂载到 config 上 } return config; }, (error: AxiosError) => { // 对请求错误做些什么 return Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( (response: AxiosResponse) => { // 对响应数据做点什么 const res = response.data; const useUserInfoStore = useUserInfo(); // 如果配置中启用了加载动画,则关闭加载动画 if (response.config?.loading && response.config.requestId) { loadingClose(response.config.requestId as string); } // 如果自定义状态码不为0,则判断为错误 if (res.code !== 0) { switch (res.code) { case 401: Message({ message: '登录状态已失效,请重新登录', type: 'error', duration: 3 * 1000, }); useUserInfoStore.updateLoginShow(true) break; default: if (response.config.showErrorMessage) { if (res.message?.length > 30 || res.code === 400011) { let message = '
' + res.message + '
' || 'Error'; MessageBox.alert(message, '提示', { dangerouslyUseHTMLString: true, }); } else { Message({ message: res.message || 'Error', type: 'error', duration: 5 * 1000, }); } } break; } return Promise.reject(res || 'Error'); } else { return res; } }, (error: AxiosError) => { // 对响应错误做点什么 let errMessage = ''; // 如果配置中启用了加载动画,则关闭加载动画 if (error.config?.loading && error.config.requestId) { loadingClose(error.config.requestId as string); } const useUserInfoStore = useUserInfo(); try { if (error.response) { switch (error.response.status) { case 400: errMessage = '请求错误(400)'; break; case 401: errMessage = '登录状态已失效,请重新登录'; useUserInfoStore.updateLoginShow(true) break; case 403: errMessage = '拒绝访问(403)'; break; case 404: errMessage = '请求出错(404)'; break; case 408: errMessage = '请求超时(408)'; break; case 500: errMessage = '服务器错误(500)'; break; case 501: errMessage = '服务未实现(501)'; break; case 502: errMessage = '网络错误(502)'; break; case 503: errMessage = '服务不可用(503)'; break; case 504: errMessage = '网络超时(504)'; break; case 505: errMessage = 'HTTP版本不受支持(505)'; break; default: errMessage = '连接出错!'; } } else { errMessage = '未知错误'; } } catch (e) { console.log(e); } // 如果配置中启用了错误提示,则显示错误信息 if (error.config?.showErrorMessage) { if (error.message && error.message.includes('timeout')) { Message({ message: '请求超时!', type: 'error', duration: 5 * 1000, }); } else if (errMessage) { Message({ message: errMessage, type: 'error', duration: 5 * 1000, }); } } // 对响应错误做处理 return Promise.reject(error); } ); /** * 发起 GET 请求 * * @template T 泛型,表示返回数据的类型 * @param {string} url 请求的 URL * @param {any} [params] 请求参数 * @returns {Promise} 返回一个 Promise,解析为响应数据 */ export function GET(url: string, data?: any,config): Promise { return service.get(url, { params: data, loading: config?.loading ?? false, showErrorMessage: config?.showErrorMessage ?? true, }); } /** * 发起 POST 请求 * * @template T 泛型,表示返回数据的类型 * @param {string} url 请求的 URL * @param {any} [data] 请求体 * @param {any} [config] 请求配置 * @returns {Promise} 返回一个 Promise,解析为响应数据 */ export function POST(url: string, data?: any, config?: AxiosRequestConfig): Promise { return service.post(url, data, { ...config, loading: config?.loading ?? true, showErrorMessage: config?.showErrorMessage ?? true, }); } // 导出配置好的 axios 实例 export default service;