// 导入必要的模块和函数 import { useRouter } from "vue-router"; // 用于路由导航 import Request from "@/service/request/index.js"; // 自定义请求类 import { message } from '@/components/x-message/useMessage.js'; import {authStore} from "~/stores/auth/index.js"; // 消息提示组件 // 初始化路由 const router = useRouter(); let isRefreshing = false; // 标记是否正在刷新token let refreshSubscribers = []; // 存储刷新token的回调函数 const config = useRuntimeConfig(); // 获取运行时配置 // 创建请求实例 const request = new Request({ baseURL: config.public.NUXT_PUBLIC_API_BASE, // 基础URL timeout: 1000 * 60 * 5, // 超时时间设置为5分钟 showMsg: true, // 是否显示消息提示 interceptors: { // 请求拦截器 requestInterceptors: (config) => { // 根据是否是表单数据设置Content-Type const contentType = config.isFormData ? 'multipart/form-data' : config.contentType || 'application/json'; config.headers = { "Content-Type": contentType, "Authorization": localStorage.getItem('token') || '' // 从本地存储获取token }; return config; // 返回修改后的配置 }, // 响应拦截器 responseInterceptors: async (response) => { // 如果需要显示消息且状态为1,显示警告消息 if (response.config.showMsg && response.data.status === 1) { message.warning(response.data.msg); } // 如果响应码为401,尝试刷新token if (response.data.code === 401) { return getRefreshToken(response); } // 如果响应状态为200, 201, 204,直接返回响应 if ([200, 201, 204].includes(response.status)) { return response.config.responseType === "blob" ? response : response; } else { // 处理其他错误情况 const errorMsg = response.data.msg || 'An error occurred.'; message.error(errorMsg); return Promise.reject(new Error(errorMsg)); } }, }, }); // 刷新token的函数 async function getRefreshToken(response) { const {token,RefreshToken,userInfo}= authStore() if (!isRefreshing) { isRefreshing = true; // 标记正在刷新 const refreshToken = RefreshToken.value; // 获取刷新token if (refreshToken) { try { // 发送请求刷新token const res = await request.post("/user/refresh/token", { refreshToken }); if (res.code === 200) { // 更新本地存储的token和用户信息 token.value = res.data.Token; userInfo.value=res.data.AccountInfo RefreshToken.value = res.data.RefreshToken; response.config.headers["Authorization"] = res.data.Token; // 更新请求头的token return request.request(response.config); // 重新发送原始请求 } else { handleAuthError(res); // 处理认证错误 } } catch (error) { throw error; // 抛出错误 } finally { isRefreshing = false; // 重置刷新标记 refreshSubscribers.forEach(callback => callback()); // 执行所有等待的回调 refreshSubscribers = []; // 清空回调列表 } } else { handleAuthError(); // 没有刷新token时处理错误 } } else { // 如果正在刷新,返回一个Promise,等待刷新完成后重新发送请求 return new Promise(resolve => { refreshSubscribers.push(() => resolve(request.request(response.config))); }); } } // 处理认证错误的函数 function handleAuthError(res = {}) { router.push("/login"); // 跳转到登录页面 const errorMsg = res.message || res.msg || "No refresh token available."; // 错误消息 message.error(errorMsg); // 显示错误消息 throw new Error(errorMsg); // 抛出错误 } // 发送请求的函数 const fontRequest = (config) => { // 如果是GET请求,将data作为params if (["get", "GET"].includes(config.method)) { config.params = config.data; } return request.request(config); // 发送请求 }; export default fontRequest; // 导出请求函数