import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios' import router from '@/router' import { ElMessage, ElMessageBox } from 'element-plus' import { useUserStore } from '@/stores/modules/user' import emitter from '@/utils/bus' interface codeMessage { [key: number]: string } const CODE_MESSAGE: codeMessage = { 200: '服务器成功返回请求的数据。', 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', 401: '用户没有权限(令牌、用户名、密码错误)。', 403: '用户得到授权,但是访问是被禁止的。', 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', 406: '请求的格式不可得。', 410: '请求的资源被永久删除,且不会再得到的。', 422: '当创建一个对象时,发生一个验证错误。', 456: 'refreshToken过期', 457: 'accessToken过期', 500: '服务器发生错误,请检查服务器。', 502: '网关错误。', 503: '服务不可用,服务器暂时过载或维护。', 504: '网关超时。' } class HttpAxios { instance: AxiosInstance timeout = 30000 cancelTokenArr: Array = [] constructor(config: AxiosRequestConfig) { this.instance = axios.create(config) // 设置请求拦截 this.instance.interceptors.request.use(this._requestInterceptors, (error: any) => { return Promise.reject(error) }) this.instance.interceptors.response.use(this._responseInterceptors, this._checkResponseError) } _requestInterceptors = (config: AxiosRequestConfig) => { // const _config = { timeout: this.timeout } // return { ...config, ..._config } return config } /** * 返回拦截 * @param response * @returns */ _responseInterceptors = (response: AxiosResponse) => { if (response.status === 200) { if (response.data.code === 401 || response.data.code === 403) { sessionStorage.clear() router.push('/login') const userStore = useUserStore() userStore.logout() ElMessage.warning({ message: 'Please log in to use this feature.', grouping: true }) emitter.emit('login-out'); } else if (response.data.code !== 200 && response.data.code !== 400) { ElMessageBox.alert( response.data?.data?.msg || 'The request failed. Please try again later', 'Prompt', { confirmButtonText: 'OK', confirmButtonClass: 'el-button--dark' } ) } return response.data } return Promise.reject(response) } _checkResponseError = (error: any) => { if (error.code === 'ECONNABORTED') { ElMessage.error({ message: 'Request timed out, please try again later!!', grouping: true }) return Promise.reject(error) } const status = error.response?.status const statusText = error.response?.statusText const message = error.message ElMessage.error({ message: CODE_MESSAGE[status] || statusText || message, grouping: true }) return Promise.reject(error) } sendRequest = (url: string, params: any, method = 'post', config?: AxiosRequestConfig) => { if (!this.instance) return // TODO show loading if needed // showFullScreenLoading() const _method = method.toLowerCase() if (_method === 'get') { return this.instance.get(url, { params, ...config }) } if (_method === 'post') { return this.instance.post(url, params, { headers: { 'Content-Type': 'multipart/form-data' }, ...config }) } if (_method === 'put') { return this.instance.put(url, params, config) } if (_method === 'delete') { return this.instance.delete(url, { data: params, ...config }) } return this.instance.post(url, params, config) } get(url: string, params?: object, config?: AxiosRequestConfig) { return this.sendRequest(url, params, 'get', config) } post(url: string, params?: object, config?: AxiosRequestConfig) { return this.sendRequest(url, params, 'post', config) } formdata(url: string, params?: object, config?: AxiosRequestConfig) { return this.sendRequest(url, params, 'formdata', config) } put(url: string, params?: object, config?: AxiosRequestConfig) { return this.sendRequest(url, params, 'put', config) } delete(url: string, params?: any, config?: AxiosRequestConfig) { return this.sendRequest(url, params, 'delete', config) } async clearRequests() { if (this.cancelTokenArr.length === 0) return this.cancelTokenArr.forEach((token) => { token.cancel() }) this.cancelTokenArr = [] } } export default new HttpAxios({})