import axios from 'axios' import type { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios' import { ElLoading, ElMessage } from 'element-plus/es' import { useStorage, useStorageType } from '@/utils' import { LOGIN_PATH, TOKEN } from '@/constants' import router from '@/router' interface InterceptorHooks { requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig requestInterceptorCatch?: (error: any) => any responseInterceptor?: (response: AxiosResponse) => AxiosResponse responseInterceptorCatch?: (error: any) => any } interface RequestConfig extends AxiosRequestConfig { hideLoading?: boolean interceptorHooks?: InterceptorHooks } interface RequestData { data: T returnCode: string success: boolean } class Request { public config: AxiosRequestConfig public interceptorHooks?: InterceptorHooks public hideLoading: boolean public loading?: any public instance: AxiosInstance constructor(options: RequestConfig) { this.config = options this.interceptorHooks = options.interceptorHooks this.hideLoading = options.hideLoading ?? false this.instance = axios.create(options) this.setupInterceptor() } public setupInterceptor(): void { this.instance.interceptors.request.use( this.interceptorHooks?.requestInterceptor, this.interceptorHooks?.requestInterceptorCatch ) this.instance.interceptors.response.use( this.interceptorHooks?.responseInterceptor, this.interceptorHooks?.responseInterceptorCatch ) this.instance.interceptors.request.use((config) => { if (!this.hideLoading) { this.loading = ElLoading.service({ lock: true, text: '加载中...', background: 'rgba(0, 0, 0, 0.7)' }) } return config }) this.instance.interceptors.response.use( (res) => { this.loading?.close() return res }, (err) => { this.loading?.close() return err } ) } public request(config: RequestConfig): Promise { if (config.hideLoading) { this.hideLoading = true } return new Promise((resolve, reject) => { // 防止出现多次请求与提示信息 const token = useStorage.getItem(TOKEN, useStorageType.Cookies) const currentPath = router.currentRoute.value.path if (!token && currentPath !== LOGIN_PATH) return // 实例请求数据 this.instance .request>(config) .then((res: any) => { // resolve(res.data) switch (res.status || res.code) { case 1 || 200: // 成功 if (res.msg) { ElMessage.success(res.msg) } resolve(res) break case 401: // 未授权 needLogin if (res.msg) { ElMessage.error(res.msg) } // 删除token 并跳转登录页 useStorage.removeItem(TOKEN, useStorageType.Cookies) router.replace(LOGIN_PATH).then((r) => r) break default: if (res.msg) { ElMessage.error(res.msg) } } }) .catch((err) => { reject(err) }) .finally(() => { this.hideLoading = false }) }) } public get(config: RequestConfig): Promise { return this.request({ ...config, method: 'GET' }) } public post(config: RequestConfig): Promise { return this.request({ ...config, method: 'POST' }) } public put(config: RequestConfig): Promise { return this.request({ ...config, method: 'PUT' }) } public delete(config: RequestConfig): Promise { return this.request({ ...config, method: 'DELETE' }) } public patch(config: RequestConfig): Promise { return this.request({ ...config, method: 'PATCH' }) } } export default Request