import { Modal, message } from 'antd'
import axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'
import AdminConfig from '@/common/config'
import { getToken } from './cookie'
interface ResponseData<T extends any> {
data: T
errorMsg: number
message: string
}
declare module 'axios' {
export interface AxiosRequestConfig {
currentRequestList: string[]
timeStep: number
currentCount: number
MaxReconnectionTimes: number
loading: boolean
submit: boolean
}
}
const service = axios.create({
// 接口地址前缀
baseURL: __PROD__ ? AdminConfig.apiUrl : '',
// 超时时间
timeout: 500,
// 当前同一时间内同时并行请求接口
currentRequestList: [],
// 重连间隔
timeStep: 500,
// 当前重连次数
currentCount: 1,
// 最大重连次数
MaxReconnectionTimes: 5,
// 重连机制开启时所有接口都不可在同一时间平行访问
loading: false,
// 重复提交控制
submit: false,
})
/**
* 清除当前请求的ajax
* @param url
*/
function clearRequestStatus(url: string): void {
service.defaults.loading = false
const index = service.defaults.currentRequestList.indexOf(url)
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
if (index > -1) {
service.defaults.currentRequestList.splice(index, 1)
}
}
/**
* @param url
* @param data
* @param submit
* @param loading
* @returns {Promise<postcss.Result> | Q.Promise<any>}
*/
// eslint-disable-next-line max-len
export function httpServer(url: string, data: any, submit = false, loading = false): any {
return service({
...service.defaults,
url,
data,
submit,
loading
})
}
// 请求拦截
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
const token = getToken()
if (token) {
// eslint-disable-next-line no-param-reassign
config.headers.token = token
}
const { submit, url } = config
if (submit) {
if (service.defaults.currentRequestList.includes(String(url))) {
return Promise.reject(message.info(`${url}正在请求,请勿重复提交`))
}
service.defaults.currentRequestList.push(String(url))
}
if (service.defaults.loading && !config.loading) {
return Promise.reject(message.info('当前网络不佳,正在为您拼命加载...'))
}
// 对config处理完后返回,下一步将向后端发送请求
return config
},
async (error: AxiosError) => Promise.reject(error),
)
axios.interceptors.response.use(
(response: AxiosResponse<ResponseData<any>>) => {
// 登录已过期或者未登录
if (response.data.errorMsg === AdminConfig.loginExpire) {
Modal.confirm({
title: '系统提示',
content: response.data.message,
okText: '重新登录',
onOk() {
// 登出与首页跳转
// store.dispatch(logout())
},
})
return Promise.reject(new Error(response.data.message))
}
// 请求成功
if (response.data.errorMsg === AdminConfig.successCode) {
return response.data as any
}
return Promise.reject(new Error(response.data.message))
},
// eslint-disable-next-line complexity
async (error: AxiosError) => {
const { config } = error
if (config.submit) {
clearRequestStatus(String(config.url))
}
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
if (error.message.search('timeout') > -1) {
const { MaxReconnectionTimes, currentCount, timeStep } = service.defaults
// 可自行在这里配置showTitle弹出框展示
message.info(`当前网络不佳...已尝试为您重连第${currentCount}次`)
if (MaxReconnectionTimes <= currentCount) {
return Promise.reject(error)
}
const Reconnection = new Promise((resolve) => {
setTimeout(() => {
service.defaults.currentCount += 1
resolve()
}, timeStep || 1000)
})
const {url, data } = config
return Reconnection.then(() => {
service.defaults.loading = true
httpServer(String(url), data, true, true)
})
}
return Promise.reject(error)
},
)
export default service
typescript对与axios的封装
最新推荐文章于 2024-03-17 23:38:24 发布