import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
|
import Qs from 'qs'
|
import { useBedsideAuxiliaryScreenStore } from '@/store/bedsideAuxiliaryScreen'
|
import { ElMessage } from 'element-plus/es'
|
|
// ====== 配置 ======
|
const BASE_URL = import.meta.env.VITE_API_BASE_URL
|
const TIME_OUT = 60 * 1 * 1000
|
|
// 正在进行中的请求列表,避免重复请求
|
let reqList: string[] = []
|
|
/**
|
* 允许某个请求再次发送
|
*/
|
const allowRequest = (url?: string) => {
|
if (!url) return
|
const idx = reqList.indexOf(url)
|
if (idx > -1) reqList.splice(idx, 1)
|
}
|
|
/**
|
* 创建 axios 实例
|
*/
|
const instance = axios.create({
|
baseURL: BASE_URL,
|
timeout: TIME_OUT,
|
paramsSerializer: (params) => Qs.stringify(params, { arrayFormat: 'brackets' }),
|
})
|
|
// ====== 错误处理函数 ======
|
const errorHandle = (status: number, error: any): void => {
|
const msg = error?.msg || error?.message || ''
|
switch (status) {
|
case 401:
|
ElMessage.error(`Error Code: 401, Message: ${msg || '登录失效,请重新登录'}`);
|
break
|
case 403:
|
ElMessage.error(`Error Code: 403, Message: ${msg || '你没有访问权限'}`);
|
break
|
case 500:
|
ElMessage.error(`Error Code: 500, Message: ${msg || '后台错误,请联系管理员'}`);
|
break
|
case 502:
|
alert()
|
ElMessage.error(`Error Code: 502, Message: ${msg || '平台环境异常'}`);
|
break
|
default:
|
ElMessage.error(`Error Code: ${status}, Message: ${msg || '未知错误,请刷新重试'}`);
|
}
|
}
|
|
// ====== 请求拦截 ======
|
instance.interceptors.request.use(
|
(config: InternalAxiosRequestConfig) => {
|
const store = useBedsideAuxiliaryScreenStore()
|
|
// 加 token
|
if (store.userInfo?.token) {
|
config.headers.set('Authorization', `Bearer ${store.userInfo.token}`)
|
}
|
|
// 防止同一接口短时间内重复请求
|
if (config.url) {
|
if (reqList.includes(config.url)) {
|
// return Promise.reject(new axios.Cancel(`重复请求:${config.url}`))
|
} else {
|
reqList.push(config.url)
|
}
|
}
|
|
return config
|
},
|
(error) => Promise.reject(error),
|
)
|
|
// ====== 响应拦截 ======
|
instance.interceptors.response.use(
|
(res: AxiosResponse) => {
|
|
// setTimeout(() => allowRequest(res.config.url), 1000)
|
if (String(res.status).charAt(0) !== '2') {
|
return Promise.reject({
|
code: res.status,
|
message: res.data?.message || '请求异常,请刷新重试',
|
})
|
}
|
if (res.data?.code === 200) return res.data
|
const whiteList: string[] = []
|
const requestUrl: string = res?.config?.url || ''
|
const isInWhiteList = whiteList.some((item) => requestUrl.includes(item))
|
ElMessage.error(res.data.message);
|
if (isInWhiteList) return Promise.reject(res.data)
|
return Promise.reject(res.data)
|
},
|
|
|
(err: unknown) => {
|
|
const anyErr = err as any
|
const configUrl = anyErr?.config?.url
|
// 失败后 1s 允许再次请求
|
// setTimeout(() => allowRequest(configUrl), 1000)
|
|
// 先判断是否是取消请求
|
// if (axios.isCancel(err as any)) {
|
// console.warn('请求被取消:', (err as any)?.message)
|
// return Promise.reject(err)
|
// }
|
|
// 判断是否为 axios 的错误类型(有 response)
|
if (axios.isAxiosError(err)) {
|
const axErr = err // 现在 TypeScript 知道这是 AxiosError
|
if (axErr.response) {
|
// 使用你现有的错误处理函数
|
errorHandle(axErr.response.status, axErr.response.data)
|
|
if (axErr.response.status === 401) {
|
ElMessage.error('请登录');
|
}
|
return Promise.reject(axErr.response.data || axErr.response)
|
}
|
|
ElMessage.error('网络请求失败, 请刷新重试');
|
return Promise.reject(axErr)
|
}
|
|
//(未知错误)
|
ElMessage.error('网络请求失败, 请刷新重试');
|
return Promise.reject(err)
|
},
|
)
|
|
export default instance
|