feat: api config

This commit is contained in:
xingyu4j
2025-11-11 13:41:14 +08:00
parent 26918cd56d
commit 6b0da7e397

View File

@@ -3,7 +3,7 @@
*/
import type { RequestClientOptions } from '@vben/request';
import { useAppConfig } from '@vben/hooks';
import { isTenantEnable, useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import {
authenticateResponseInterceptor,
@@ -12,6 +12,7 @@ import {
RequestClient,
} from '@vben/request';
import { useAccessStore } from '@vben/stores';
import { createApiEncrypt } from '@vben/utils';
import { message } from '#/adapter/tdesign';
import { useAuthStore } from '#/store';
@@ -19,6 +20,8 @@ import { useAuthStore } from '#/store';
import { refreshTokenApi } from './core';
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
const tenantEnable = isTenantEnable();
const apiEncrypt = createApiEncrypt(import.meta.env);
function createRequestClient(baseURL: string, options?: RequestClientOptions) {
const client = new RequestClient({
@@ -49,8 +52,16 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
*/
async function doRefreshToken() {
const accessStore = useAccessStore();
const resp = await refreshTokenApi();
const newToken = resp.data;
const refreshToken = accessStore.refreshToken as string;
if (!refreshToken) {
throw new Error('Refresh token is null!');
}
const resp = await refreshTokenApi(refreshToken);
const newToken = resp?.data?.data?.accessToken;
// add by 芋艿:这里一定要抛出 resp.data从而触发 authenticateResponseInterceptor 中,刷新令牌失败!!!
if (!newToken) {
throw resp.data;
}
accessStore.setAccessToken(newToken);
return newToken;
}
@@ -66,10 +77,54 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
config.headers.Authorization = formatToken(accessStore.accessToken);
config.headers['Accept-Language'] = preferences.app.locale;
// 添加租户编号
config.headers['tenant-id'] = tenantEnable
? accessStore.tenantId
: undefined;
// 只有登录时,才设置 visit-tenant-id 访问租户
config.headers['visit-tenant-id'] = tenantEnable
? accessStore.visitTenantId
: undefined;
// 是否 API 加密
if ((config.headers || {}).isEncrypt) {
try {
// 加密请求数据
if (config.data) {
config.data = apiEncrypt.encryptRequest(config.data);
// 设置加密标识头
config.headers[apiEncrypt.getEncryptHeader()] = 'true';
}
} catch (error) {
console.error('请求数据加密失败:', error);
throw error;
}
}
return config;
},
});
// API 解密响应拦截器
client.addResponseInterceptor({
fulfilled: (response) => {
// 检查是否需要解密响应数据
const encryptHeader = apiEncrypt.getEncryptHeader();
const isEncryptResponse =
response.headers[encryptHeader] === 'true' ||
response.headers[encryptHeader.toLowerCase()] === 'true';
if (isEncryptResponse && typeof response.data === 'string') {
try {
// 解密响应数据
response.data = apiEncrypt.decryptResponse(response.data);
} catch (error) {
console.error('响应数据解密失败:', error);
throw new Error(`响应数据解密失败: ${(error as Error).message}`);
}
}
return response;
},
});
// 处理返回的响应数据格式
client.addResponseInterceptor(
defaultResponseInterceptor({
@@ -96,7 +151,12 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? '';
const errorMessage =
responseData?.error ?? responseData?.message ?? responseData.msg ?? '';
// add by 芋艿:特殊:避免 401 “账号未登录”,重复提示。因为,此时会跳转到登录界面,只需提示一次!!!
if (error?.data?.code === 401) {
return;
}
// 如果没有错误信息,则会根据状态码进行提示
message.error(errorMessage || msg);
}),
@@ -110,3 +170,17 @@ export const requestClient = createRequestClient(apiURL, {
});
export const baseRequestClient = new RequestClient({ baseURL: apiURL });
baseRequestClient.addRequestInterceptor({
fulfilled: (config) => {
const accessStore = useAccessStore();
// 添加租户编号
config.headers['tenant-id'] = tenantEnable
? accessStore.tenantId
: undefined;
// 只有登录时,才设置 visit-tenant-id 访问租户
config.headers['visit-tenant-id'] = tenantEnable
? accessStore.visitTenantId
: undefined;
return config;
},
});