Files
chart-view/src/api/axios.ts
2025-12-20 17:39:32 +08:00

108 lines
3.5 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, { AxiosResponse, AxiosRequestConfig, Axios, AxiosError, InternalAxiosRequestConfig } from 'axios'
import { RequestHttpHeaderEnum, ResultEnum, ModuleTypeEnum } from '@/enums/httpEnum'
import { PageEnum, ErrorPageNameMap } from '@/enums/pageEnum'
import { StorageEnum } from '@/enums/storageEnum'
import { axiosPre } from '@/settings/httpSetting'
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
import { redirectErrorPage, getLocalStorage, routerTurnByName, isPreview } from '@/utils'
import { fetchAllowList, ftsList } from './axios.config'
import includes from 'lodash/includes'
export interface MyResponseType<T> {
code: ResultEnum
data?: T
details?: T
message: string
timeseq?: number
}
export interface MyRequestInstance extends Axios {
<T = any>(config: AxiosRequestConfig): Promise<MyResponseType<T>>
}
const axiosInstance = axios.create({
// iframe 嵌入模式:直接请求后端地址,不使用代理
baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : import.meta.env.VITE_DEV_PATH}${axiosPre}`,
timeout: ResultEnum.TIMEOUT
}) as unknown as MyRequestInstance
axiosInstance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// fts 接口特殊处理:使用完整路径,不添加 /Visual/v1 前缀
if (config.url && includes(ftsList, config.url)) {
const baseUrl = import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : import.meta.env.VITE_DEV_PATH
config.baseURL = baseUrl
}
// 获取 token 并添加到所有请求
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
if (info) {
const userInfo = info[SystemStoreEnum.USER_INFO]
if (userInfo && userInfo[SystemStoreUserInfoEnum.USER_TOKEN]) {
config.headers['authorization'] = userInfo[SystemStoreUserInfoEnum.USER_TOKEN]
}
}
return config
},
(err: AxiosError) => {
Promise.reject(err)
}
)
// 响应拦截器
axiosInstance.interceptors.response.use(
(res: AxiosResponse) => {
// 统一处理后台返回 details 字段的情况,将其转换为 data 字段
const { code, details, message } = res.data as { code: number; details?: any; message?: string }
const responseData = details !== undefined
? { code, message, data: details }
: res.data
// 预览页面错误不进行处理
if (isPreview()) {
return Promise.resolve(responseData)
}
if (code === undefined || code === null) return Promise.resolve(responseData)
// 成功
if (code === ResultEnum.SUCCESS) {
return Promise.resolve(responseData)
}
// 登录过期
if (code === ResultEnum.TOKEN_OVERDUE) {
window['$message'].error(window['$t']('http.token_overdue_message'))
// iframe 嵌入模式下token 过期不重定向到登录页
console.error('[GoView] iframe 模式token 已过期,请更新 URL 中的 token 参数')
return Promise.resolve(responseData)
}
// 固定错误码重定向
if (ErrorPageNameMap.get(code)) {
redirectErrorPage(code)
return Promise.resolve(responseData)
}
// 提示错误
window['$message'].error(window['$t']((res.data as any).msg || message))
return Promise.resolve(responseData)
},
(err: AxiosError) => {
const status = err.response?.status
switch (status) {
case 401:
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
Promise.reject(err)
break
default:
Promise.reject(err)
break
}
}
)
export default axiosInstance