import { useAccessStore, useUserStore } from '@vben/stores'; import { message as Message } from 'ant-design-vue'; import { postApiAppAccountRefreshToken } from '#/api-client'; import { $t } from '#/locales'; import { antdLocale } from '#/locales/index'; import { useAuthStore } from '#/store'; import { client } from '../api-client/services.gen'; client.setConfig({ baseURL: import.meta.env.DEV ? '/proxy/' : import.meta.env.VITE_APP_API_ADDRESS, timeout: 1000 * 60, responseType: 'json', throwOnError: true, }); // 是否正在刷新token let isRefreshing = false; // 刷新token队列 let refreshTokenQueue: ((token: string) => void)[] = []; client.instance.interceptors.request.use((request) => { // 全局拦截请求发送前提交的参数 const userStore = useUserStore(); const accessStore = useAccessStore(); const token = accessStore.getAccessToken(); // 设置请求头 if (request.headers) { request.headers.__tenant = userStore.tenant?.tenantId; // todo vben5 没有提供统一获取当前语言的方式 request.headers['accept-language'] = antdLocale.value.locale; } // 如果token过期,则跳转到登录页面 if ( request.url !== undefined && request.url.includes('/api/app/account/login') ) { return request; } // 设置请求头 if (request.headers) { request.headers.Authorization = `Bearer ${token}`; } return request; }); client.instance.interceptors.response.use( (response) => { return Promise.resolve(response); }, async (error) => { let message = error.message; if (message === 'Network Error') { message = $t('common.mesage500'); } else if (message.includes('timeout')) { message = $t('common.timeOut'); } else switch (error.status) { case 400: { message = error.response.data.error?.validationErrors[0].message; break; } case 401: { message = $t('common.mesage401'); const { config } = error; const originalRequest = config; if (isRefreshing) { return new Promise((resolve) => { refreshTokenQueue.push((token) => { originalRequest.headers.Authorization = `Bearer ${token}`; resolve(client.request(originalRequest)); }); }); } else { isRefreshing = true; try { const newToken = await refreshTokenAsync(); // 处理队列中的请求 refreshTokenQueue.forEach((callback) => callback(newToken)); // 清空队列 refreshTokenQueue = []; return client.request(originalRequest); } catch (refreshError) { // 如果刷新 token 失败,处理错误(如强制登出或跳转登录页面) message = $t('common.mesage401'); refreshTokenQueue = []; const authStore = useAuthStore(); authStore.logout(); console.error(refreshError); } finally { isRefreshing = false; } } break; } case 403: { message = $t('common.mesage403'); break; } case 500: { message = error.response.data.error?.message; break; } default: { if (message.includes('Request failed with status code')) { message = $t('common.mesage500'); } } } Message.error(message); throw error; }, ); async function refreshTokenAsync(): Promise { try { const userStore = useUserStore(); const accessStore = useAccessStore(); const refreshToken = accessStore.getRefreshToken(); if (!refreshToken) return ''; const res = await postApiAppAccountRefreshToken({ body: { userId: userStore.userInfo?.id, refreshToken, }, }); if (res?.data?.success) { accessStore.setAccessToken(res.data.token as string); accessStore.setRefreshToken(res.data.refreshToken as string); return res.data.token as string; } else { throw new Error('get refreshToken error'); } } catch { throw new Error($t('common.mesage401')); } } export default client;