import type { AxiosInstance, AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse, InternalAxiosRequestConfig, } from 'axios' import qs from 'qs' import Keys from '../Keys' import axios, { AxiosError, isCancel } from 'axios' // import { // getRefreshToken, // getTenantId, // getToken, // removeToken, // setToken, // } from '@/utils/auth' import { authErrMap, ignoreMsgs, networkErrMap } from '../basic/utils' import type { Result } from '../basic/httpTypes' import type { APIConfigKeys } from './config' import { useRouter } from 'vue-router' import { useMessage } from '@/composables/useMessage' const router = useRouter() const message = useMessage() const basicHeader = { tenant() { // const tenant = getTenantId() // if (tenant) return tenant return '' }, token() { // const token = getToken() // if (token) return 'Bearer ' + token return '' }, } interface Config { baseURL?: string baseAPI: string } const instances: Record = {} let isRefreshToken = false // 是否正在刷新中 let requestList: any[] = [] // 请求队列 const createAxiosInstance = (module: APIConfigKeys, config: Config) => { if (!config || !config.baseAPI) { throw new Error(`Invalid configuration for module: ${module}`) } const { baseAPI } = config if (!instances[module]) { const instance = axios.create({ baseURL: `${baseAPI}`, timeout: 10000, headers: { 'Content-Type': 'application/json', }, }) instances[module] = instance } const service = instances[module] service.interceptors.request.use( (config: InternalAxiosRequestConfig): InternalAxiosRequestConfig => { // config.headers.Authorization = basicHeader.token() // config.headers['tenant-id'] = basicHeader.tenant() if (config.url?.includes('auth')) { config.headers['tenant-id'] = '1' } const params = config.params || {} const data = config.data || false if ( config.method?.toUpperCase() === 'POST' && (config.headers as AxiosRequestHeaders)['Content-Type'] === 'application/x-www-form-urlencoded' ) { config.data = qs.stringify(data) } if (config.method?.toUpperCase() === 'GET' && params) { config.params = {} const paramsStr = qs.stringify(params, { allowDots: true }) if (paramsStr) { config.url = config.url + '?' + paramsStr } } return config }, (error: AxiosError): Promise => { return Promise.reject(error) } ) service.interceptors.response.use( async (res: AxiosResponse) => { const config = res.config let { data } = res if (!res.data) { throw new Error('返回“[HTTP]请求没有返回值”') } if ( res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer' ) { // 注意:如果导出的响应为 json,说明可能失败了,不直接返回进行下载 if (res.data.type !== 'application/json') { return Promise.resolve({ code: res.status, data: res.data }) } data = await new Response(res.data).json() } const code = data.code || 200 const msg = data.msg || authErrMap[code] || authErrMap['default'] if (ignoreMsgs.indexOf(msg) !== -1) { // 如果是忽略的错误码,直接返回 msg 异常 return Promise.reject({ code: null, msg }) } else // if (code === 401) { // if (!isRefreshToken) { // isRefreshToken = true // if (!getRefreshToken()) logout() // try { // const refreshTokenRes = await refreshToken() // if (refreshTokenRes.data.code !== 0) { // logout() // return Promise.reject({ code, msg }) // } // setToken(refreshTokenRes.data.data.accessToken) // config.headers!.Authorization = 'Bearer ' + getToken() // requestList.forEach((cb: any) => { // cb() // }) // requestList = [] // // 重连接socket // // openSocket() // return service(config) // } catch (e) { // logout() // return Promise.reject({ code, msg }) // } finally { // requestList = [] // isRefreshToken = false // } // } else { // return new Promise(resolve => { // requestList.push(() => { // config.headers!.Authorization = 'Bearer ' + getToken() // resolve(service(config)) // }) // }) // } // } else if (code === 500) { return Promise.reject({ code, msg }) } else if (code !== 200) { // if (msg === '无效的刷新令牌') { // // hard coding:忽略这个提示,直接登出 // console.log(msg) // } else { // ElMessage.error(msg) // } return Promise.reject({ code, msg }) } return data }, (error: any): Promise => { if (isCancel(error)) { return Promise.reject({ name: 'CanceledError', message: 'canceled', code: 10001 }) } const message = '请求错误' if (error.code === 'ECONNABORTED') { return Promise.reject({ code: null, msg: '服务器响应超时' }) } if (!error.response) { return Promise.reject({ code: null, msg: message }) } const status = error.response?.status const unKnowError = `连接出错(${error.response.status})!` if (status === 401) { localStorage.removeItem(Keys.STORAGE_TOKEN) router.push('/login') } const msg = networkErrMap[status] ? networkErrMap[status] : unKnowError return Promise.reject({ code: status || null, msg: msg }) } ) if (!service) { throw new Error(`Failed to create Axios instance for module: ${module}`) } // const refreshToken = async () => { // // axios.defaults.headers.common['tenant-id'] = getTenantId() // return await axios.post( // `${VITE_BASE_API_SYSTEM}/auth/refresh-token?refreshToken=` + getRefreshToken() // ) // } async function request(config: AxiosRequestConfig): Promise> { try { const result = (await service(config)) as Result return result } catch (err: any) { const result: Result = { code: err?.code || -1, msg: err.msg || err.message, data: err.data || null, } return result } } return request } // let isShowLogout = false // async function logout() { // if (isShowLogout) return // isShowLogout = true // await message.forceConfirm('登录状态已失效,请重新登录', '系统提示', '重新登录') // removeToken() // isShowLogout = false // window.location.href = '/login' // } export default createAxiosInstance