Files
front-pc/utils/axios.ts

152 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import axios, { AxiosInstance, InternalAxiosRequestConfig, AxiosRequestConfig, AxiosResponse } from 'axios'
import qs from 'qs'
import useUserStore from '@/store/user'
import isPlainObject from 'lodash/isPlainObject'
import RefreshToken from './RefreshToken'
// 允许跨域
axios.defaults.headers.post['Access-Control-Allow-Origin-Type'] = '*'
const axiosInstance: AxiosInstance = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 1200000,
})
// 自动刷新 token 实现
export const refreshToken = RefreshToken.create({
axiosInstance,
refreshTokenApiUrl: '',
onRefreshTokenResponse: (res: any) => {
if (res.data && (res?.data?.code === 0 || res?.data?.statusCode === '00000') && res.data.data) {
return {
token: res?.data?.data?.access_token || '',
refreshToken: res?.data?.data?.refresh_token || '',
}
}
const userStore = useUserStore()
userStore.logout()
return false
},
onRefreshTokenResquest() {
const tokens = refreshToken.getToken()
return {
data: {
refreshToken: tokens.refreshToken,
},
config: {
headers: {
refreshToken: tokens.refreshToken,
},
data: {
refreshToken: tokens.refreshToken,
},
},
}
},
})
// axios实例拦截响应
axiosInstance.interceptors.response.use(
(response: AxiosResponse) => {
//因为后端的有些接口没有statusCode这个状态码先这样判断吧
if (response.data.statusCode === '00000' || response.data.code === 0) {
return response.data
} else {
ElMessage.error(response.data.msg)
return response.data
}
},
(error) => {
let message = '系统异常'
const { status, config } = error.response
if (status === 401) {
if (refreshToken.pending) {
return refreshToken.pushCallbacks(config)
} else {
// 刷新token
refreshToken.refresh().then((refreshSuccess) => {
// 刷新成功 回调错误队列
if (refreshSuccess) {
refreshToken.releaseQueue()
} else {
return Promise.reject(error)
}
})
// 推入第一个401请求
return refreshToken.pushCallbacks(config)
}
} else if (status === 404) {
message = '接口地址有误'
} else if (status === 400) {
message = '参数有误,请确认参数是否正确'
}
ElMessage.error(message)
return Promise.reject(error)
}
)
// axios实例拦截请求
axiosInstance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
config.headers['Accept-Language'] = 'zh-CN'
const tokens = refreshToken.getToken()
if (tokens !== null) {
config.headers['authorization'] = `Bearer ${tokens.token}`
config.headers['Refreshtoken'] = tokens.refreshToken
}
// 防止get请求缓存
if (config.method === 'get') {
config.params = {
...config.params,
...{ _t: new Date().getTime() },
}
}
if (isPlainObject(config.data)) {
// eslint-disable-next-line no-param-reassign
config.data = {
...config.data,
}
if (config.headers?.['content-type']) {
const contentType: string = config.headers['content-type'] + ''
if (/^application\/x-www-form-urlencoded/.test(contentType)) {
// form形式编码
config.data = qs.stringify(config.data)
}
}
}
return config
},
(error) => {
return Promise.reject(error)
}
)
const request = <T = any>(config: AxiosRequestConfig): Promise<T> => {
const conf = config
return new Promise((resolve, reject) => {
axiosInstance
.request<any, AxiosResponse<IResponse>>(conf)
.then((res: AxiosResponse<IResponse>) => {
const data: any = res
resolve(data as T)
})
.catch((error) => reject(error))
})
}
// 封装get
export function get<T = any>(config: AxiosRequestConfig): Promise<T> {
return request({ ...config, method: 'GET' })
}
// 封装delete
export function Delete<T = any>(config: AxiosRequestConfig): Promise<T> {
return request({ ...config, method: 'delete' })
}
// 封装put
export function put<T = any>(config: AxiosRequestConfig): Promise<T> {
return request({ ...config, method: 'put' })
}
// 封装post
export function post<T = any>(config: AxiosRequestConfig): Promise<T> {
return request({ ...config, method: 'POST' })
}
export default axiosInstance
export type { AxiosInstance, AxiosResponse }