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 = (config: AxiosRequestConfig): Promise => { const conf = config return new Promise((resolve, reject) => { axiosInstance .request>(conf) .then((res: AxiosResponse) => { const data: any = res resolve(data as T) }) .catch((error) => reject(error)) }) } // 封装get export function get(config: AxiosRequestConfig): Promise { return request({ ...config, method: 'GET' }) } // 封装delete export function Delete(config: AxiosRequestConfig): Promise { return request({ ...config, method: 'delete' }) } // 封装put export function put(config: AxiosRequestConfig): Promise { return request({ ...config, method: 'put' }) } // 封装post export function post(config: AxiosRequestConfig): Promise { return request({ ...config, method: 'POST' }) } export default axiosInstance export type { AxiosInstance, AxiosResponse }