152 lines
4.4 KiB
TypeScript
152 lines
4.4 KiB
TypeScript
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 }
|