import type { HookFetchPlugin } from 'hook-fetch'; import { ElMessage } from 'element-plus'; import hookFetch from 'hook-fetch'; import { sseTextDecoderPlugin } from 'hook-fetch/plugins'; import router from '@/routers'; import { useUserStore } from '@/stores'; // 标准响应格式 // 标准响应格式 interface BaseResponse { code: number; data: T; msg: string; } // 扩展请求函数类型声明 declare module 'hook-fetch' { interface HookFetchDefaults { // 允许响应是裸数据(自动会被插件包装) response: any; } } export const request = hookFetch.create({ baseURL: import.meta.env.VITE_WEB_BASE_API, headers: { 'Content-Type': 'application/json', }, plugins: [ sseTextDecoderPlugin({ json: true, prefix: 'data:' }), { name: 'adapt-array-response', afterResponse: async (response) => { // 已经是标准格式(包含 code 字段) if (typeof response.result?.code === 'number') { return response; } // 非标准格式 → 包装为标准格式 return { ...response, result: { code: 200, // 默认成功码 data: response.result, // 原始数据放入 data msg: 'success', // 默认消息 }, }; }, }, ], }); function jwtPlugin(): HookFetchPlugin { const userStore = useUserStore(); return { name: 'jwt', beforeRequest: async (config) => { config.headers = new Headers(config.headers); config.headers.set('authorization', `Bearer ${userStore.token}`); return config; }, afterResponse: async (response) => { // console.log(response); if (response.result?.code === 200) { return response; } // 处理403逻辑 if (response.result?.code === 403) { // 跳转到403页面(确保路由已配置) router.replace({ name: '403', }); ElMessage.error(response.result?.msg); return Promise.reject(response); } // 处理401逻辑 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;