Files
Yi.Framework/Yi.Ai.Vue3/src/utils/request.ts

122 lines
3.3 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 type { HookFetchPlugin } from 'hook-fetch';
import FingerprintJS from '@fingerprintjs/fingerprintjs'; // 新增指纹库
import { ElMessage } from 'element-plus';
import hookFetch from 'hook-fetch';
import { sseTextDecoderPlugin } from 'hook-fetch/plugins';
import router from '@/routers';
import { useUserStore } from '@/stores';
// 初始化指纹(单例模式)
const fpPromise = FingerprintJS.load();
// 获取浏览器指纹(缓存结果)
async function getFingerprint(): Promise<string> {
const fp = await fpPromise;
const { visitorId } = await fp.get();
return visitorId;
}
// 标准响应格式
interface BaseResponse<T = any> {
code: number;
data: T;
msg: string;
}
declare module 'hook-fetch' {
interface HookFetchDefaults {
response: any;
}
}
export const request = hookFetch.create<BaseResponse>({
baseURL: import.meta.env.VITE_WEB_BASE_API,
headers: {
'Content-Type': 'application/json',
},
plugins: [
sseTextDecoderPlugin({ json: true, prefix: 'data:' }),
{
name: 'fingerprint-plugin', // 新增指纹插件
beforeRequest: async (config) => {
try {
const fingerprint = await getFingerprint();
config.headers = new Headers(config.headers);
config.headers.set('X-Fingerprint', fingerprint);
}
catch (error) {
console.error('Failed to generate fingerprint:', error);
}
return config;
},
},
{
name: 'adapt-array-response',
afterResponse: async (response) => {
if (typeof response.result?.code === 'number') {
return response;
}
return {
...response,
result: {
code: 200,
data: response.result,
msg: 'success',
},
};
},
},
],
});
// JWT插件保持原有逻辑
function jwtPlugin(): HookFetchPlugin<BaseResponse> {
const userStore = useUserStore();
return {
name: 'jwt',
beforeRequest: async (config) => {
config.headers = new Headers(config.headers);
if (userStore.refreshToken) {
config.headers.set('refresh_token', `Bearer ${userStore.refreshToken}`);
}
if (userStore.token) {
config.headers.set('authorization', `Bearer ${userStore.token}`);
}
return config;
},
afterResponse: async (response: any) => {
console.log('response.response.headers---', response.response.headers);
if (response.response.headers?.refresh_token) {
userStore.setToken(response.response.headers?.access_token, response.response.headers?.refresh_token);
}
if (response.result?.code === 200)
return response;
if (response.result?.code === 403) {
router.replace({ name: '403' });
ElMessage.error(response.result?.msg);
return Promise.reject(response);
}
if (response.result?.code === 401) {
userStore.logout();
userStore.openLoginDialog();
}
ElMessage.error(response.result?.msg);
return Promise.reject(response);
},
};
}
request.use(jwtPlugin());
// 导出方法(保持原有)
export const post = request.post;
export const get = request.get;
export const put = request.put;
export const del = request.delete;
export default request;