import { router } from '@/router'
import { ElMessage } from 'element-plus'
import axiosRetry from 'axios-retry'
// import { authUtils } from '@/utils/auth'
import axios, {
AxiosError,
AxiosInstance,
AxiosPromise,
AxiosRequestConfig,
AxiosResponse
} from 'axios'
export interface RequestInterceptors {
// 请求拦截
requestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig
requestInterceptorsCatch?: (err: any) => any
// 响应拦截
responseInterceptors?: (config: AxiosResponse) => AxiosResponse
responseInterceptorsCatch?: (err: any) => any
}
// 自定义传入的参数
export interface RequestConfig extends AxiosRequestConfig {
interceptors?: RequestInterceptors
}
export interface IDataWithError<T> {
data: T
code: number
msg: string
}
interface ICommonResType<T> {
obj: T
success: boolean
errorCode: string
errorMessage: string
business: null | string
date: null | string
requestId: null | string
version: null | string
}
interface IHeadersType {
[key: string]: any
}
interface IParamsType {
[key: string]: any
}
const BASE_URL = '/'
class HttpService {
private http!: AxiosInstance
constructor() {
this.http = axios.create({
baseURL: BASE_URL,
timeout: 60000
})
axiosRetry(this.http, {
retries: 3,
shouldResetTimeout: true,
// 重复请求延迟
retryDelay: (retryCount: number) => {
return retryCount * 1000
},
retryCondition: (error: AxiosError) => {
if (error.message.includes('timeout')) {
return true
}
return !error.response || error.response.status !== 401
}
})
this.addInterceptors(this.http)
}
get<T>(url: string, params?: IParamsType, config?: AxiosRequestConfig) {
config = {
...config,
method: 'GET',
data: params
}
return this.requestHandle<T>(url, config)
// return this.handleErrorWrapper<T>(this.http.get(url, config))
}
post<T>(url: string, params?: unknown, config?: AxiosRequestConfig) {
config = {
...config,
method: 'POST',
data: params
}
return this.requestHandle<T>(url, config)
// return this.handleErrorWrapper<T>(this.http.post(url, params, config))
}
postDownload<T>(url: string, params?: unknown, config?: AxiosRequestConfig) {
config = {
...config,
method: 'POST',
data: params,
responseType: 'arraybuffer'
}
return this.requestHandle<T>(url, config)
// return this.handleErrorWrapper<T>(this.http.post(url, param, { responseType: 'arraybuffer' }))
}
put<T>(url: string, params?: unknown, config?: AxiosRequestConfig) {
config = {
...config,
method: 'PUT',
data: params
}
return this.requestHandle<T>(url, config)
// return this.handleErrorWrapper<T>(this.http.put(url, param, config))
}
delete<T>(url: string, params: unknown, config?: AxiosRequestConfig) {
config = {
...config,
method: 'DELETE',
data: params
}
return this.requestHandle<T>(url, config)
// return this.handleErrorWrapper<T>(this.http.delete(url, { data: param, ...config }))
}
private addInterceptors(http: AxiosInstance) {
// 一、请求拦截器
http.interceptors.request.use((config: any) => {
// 1、添加token
// const token = authUtils.getToken()
// if (token) {
// config.headers['Authorization'] = 'Bearer ' + token
// }
// 2、验证请求状态码
config.validateStatus = (status: number) => {
switch (status) {
case 401:
const instance = ElMessage.error('用户信息过期,请重新登录')
setTimeout(() => {
instance.close()
router.push('/login')
}, 1000)
break
default:
console.warn(`status= ${status}`)
break
}
return status >= 200 && status < 400
}
return config
})
// 二、响应拦截器
http.interceptors.response.use(
(response: AxiosResponse) => {
return response
},
error => {
return Promise.reject(error)
}
)
}
creadeHeaders(headers: IHeadersType) {
return {
...headers
}
}
request<T>(url: string, config: any) {
const isMock = config.url?.includes('mockapi')
const baseURL = isMock ? '/' : this.http.defaults.baseURL
config = {
...config,
baseURL,
url,
headers: this.creadeHeaders(config.headers)
}
return new Promise<ICommonResType<T>>((resolve, reject) => {
this.http
.request<IParamsType, AxiosResponse<ICommonResType<T>>>(config)
.then(res => {
resolve(res.data)
})
.catch(error => {
reject(error)
})
})
}
private requestHandle<T>(url: string, config: AxiosRequestConfig) {
return this.handleErrorWrapper<T>(
new Promise((resolve, reject) => {
this.request<T>(url, config)
.then(res => {
if (res.success) {
resolve(res.obj as any)
} else {
reject({
code: res.errorCode,
message: res.errorMessage
})
}
})
.catch(error => {
reject(error)
})
})
)
}
private async handleErrorWrapper<T>(promise: AxiosPromise): Promise<IDataWithError<T>> {
return promise
.then(response => {
return response.data
})
.catch((error: AxiosError) => {
// const obj = JSON.parse(JSON.stringify(error.response?.data))
return { error, res: {} as T }
})
}
}
export const http = new HttpService()
//const baseURL = 'http://localhost:3000'
//export const uploadFile = (url: string, formData: any, //onUploadProgress = () => {}) => {
// return axios({
// method: 'post',
// url,
// baseURL,
// headers: {
// 'Content-Type': 'multipart/form-data'
// },
// data: formData,
// onUploadProgress
// })
//}
// 使用:const { error, res } = await api.querylist.getList(params)