| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- 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: '网关超时。'
- // }
- const CODE_MESSAGE: codeMessage = {
- 200: 'The server successfully returned the requested data.',
- 400: 'The request was invalid; the server did not create or modify any data.',
- 401: 'Unauthorized: invalid token, username, or password.',
- 403: 'Access is forbidden despite valid authentication.',
- 404: 'The requested resource does not exist; no action was taken by the server.',
- 406: 'The requested format is not available.',
- 410: 'The requested resource has been permanently deleted and will not be available again.',
- 422: 'A validation error occurred while creating an object.',
- 456: 'Refresh token expired.',
- 457: 'Access token expired.',
- 500: 'An internal server error occurred. Please check the server.',
- 502: 'Bad gateway.',
- 503: 'Service unavailable: the server is temporarily overloaded or under maintenance.',
- 504: 'Gateway timeout.'
- };
- class HttpAxios {
- instance: AxiosInstance
- timeout = 30000
- cancelTokenArr: Array<any> = []
- 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 && response.data.code !== 4001 && response.data.code !== 4002 && response.data.code !== 4003) {
- 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) => {
- // ✅ 第一步:如果是用户取消的请求,静默处理 or 特殊处理
- if (axios.isCancel(error)) {
- return Promise.reject(error) // 通常仍 reject,但上层可选择忽略
- }
- // ✅ 第二步:超时错误(ECONNABORTED)
- 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({})
|