import { Message, Modal } from '@arco-design/web-vue'; import type { AxiosResponse, InternalAxiosRequestConfig } from 'axios'; import axios from 'axios'; import { useUserStore } from '@/store'; import { getToken } from '@/utils/auth'; export interface HttpResponse { status: number; msg: string; code: number; data: T; } let initialized = false; let sessionExpiredDialogVisible = false; function networkErrorMessage(error: unknown) { if (!axios.isAxiosError(error)) return '网络请求失败,请稍后重试'; if (!error.response) return '无法连接服务器,请检查网络后重试'; if (error.response.status === 403) return '当前账号无权执行此操作'; return error.response.data?.msg || `请求失败(${error.response.status})`; } export function setupHttp() { if (initialized) { return; } initialized = true; const baseURL = import.meta.env.VITE_API_BASE_URL?.trim(); if (baseURL) { axios.defaults.baseURL = baseURL; } axios.interceptors.request.use( (config: InternalAxiosRequestConfig) => { const token = getToken(); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, (error) => Promise.reject(error), ); axios.interceptors.response.use( (response: AxiosResponse) => { const res = response.data; if (res.code !== 20000) { Message.error({ content: res.msg || '请求失败', duration: 5 * 1000, }); if ( [50008, 50012, 50014].includes(res.code) && response.config.url !== '/api/user/info' ) { if (!sessionExpiredDialogVisible) { sessionExpiredDialogVisible = true; Modal.error({ title: '登录已失效', content: '当前登录状态已失效。重新登录后将返回当前页面。', okText: '重新登录', async onOk() { const userStore = useUserStore(); sessionStorage.setItem('auth-redirect', `${window.location.pathname}${window.location.search}`); await userStore.logout(); window.location.assign('/login'); }, onCancel() { sessionExpiredDialogVisible = false; }, }); } } return Promise.reject(new Error(res.msg || '请求失败')); } return res as unknown as AxiosResponse; }, (error) => { const content = networkErrorMessage(error); Message.error({ content, duration: 5 * 1000, }); return Promise.reject(new Error(content)); }, ); }