import { loading, hideLoading } from "./widget"; const env = __VITE_ENV__; const baseUrl = env.MP_API_BASE_URL; const defaultOptions = { header: { "Content-Type": "application/json", }, method: "POST", timeout: 1000 * 60, // 请求超时设置为60秒 }; const tasks = []; // 是否正在刷新 token let isRefreshing = false; // 重试队列 let retryQueue = []; /** * 处理重试队列 * @param {String} token - 新的 token */ function processQueue(token) { retryQueue.forEach(({ resolve, reject, config }) => { if (token) { // 更新 token 并重试请求 if (!config.header) config.header = {}; config.header.Authorization = `Bearer ${token}`; uni.request({ ...config, success: (res) => resolve(res), fail: (err) => reject(err), }); } else { reject(new Error("Token 刷新失败")); } }); retryQueue = []; } /** * 刷新 token * @returns {Promise} */ async function refreshAccessToken() { const refreshToken = uni.getStorageSync("refreshToken"); if (!refreshToken) { return null; } if (isRefreshing) { // 等待刷新完成 await new Promise((resolve) => setTimeout(resolve, 100)); return uni.getStorageSync("accessToken"); } isRefreshing = true; try { const res = await uni.request({ url: `${baseUrl}/auth/refresh`, method: "POST", header: { "Content-Type": "application/json", }, data: { refreshToken, }, }); if (res && res.data && res.data.success && res.data.data) { const newToken = res.data.data.accessToken; uni.setStorageSync("accessToken", newToken); processQueue(newToken); return newToken; } else { // 刷新失败,清空队列 processQueue(null); // 清除登录状态 uni.removeStorageSync("accessToken"); uni.removeStorageSync("refreshToken"); uni.removeStorageSync("jwtUserInfo"); return null; } } catch (error) { console.error("Token 刷新异常:", error); processQueue(null); uni.removeStorageSync("accessToken"); uni.removeStorageSync("refreshToken"); uni.removeStorageSync("jwtUserInfo"); return null; } finally { isRefreshing = false; } } const request = async (options = {}, showLoading = true) => { // 合并用户传入的配置和默认配置 if (!options.data) options.data = {}; const config = { ...defaultOptions, ...options, url: baseUrl + options.url, }; // 添加 token 到请求头 // const accessToken = uni.getStorageSync("accessToken"); // if (accessToken) { // if (!config.header) config.header = {}; // config.header.Authorization = `Bearer ${accessToken}`; // } const key = `${JSON.stringify(config)}_${Date.now()}`; if (showLoading) { recordTask(key) } try { // 发起请求 const res = await uni.request(config); if (showLoading) { removeTask(key) } // 如果返回 401,尝试刷新 token // if (res.statusCode === 401) { // if (showLoading) { // removeTask(key) // } // // 尝试刷新 token // const newToken = await refreshAccessToken(); // if (newToken) { // // 刷新成功,重试原请求 // if (!config.header) config.header = {}; // config.header.Authorization = `Bearer ${newToken}`; // if (showLoading) { // recordTask(key) // } // const retryRes = await uni.request(config); // if (showLoading) { // removeTask(key) // } // const success = retryRes && retryRes.data && retryRes.data.success === true; // if (success) { // return retryRes.data; // } // return { // success: false, // message: retryRes.data && retryRes.data.message ? retryRes.data.message : "请求失败", // }; // } else { // return { // success: false, // message: "登录已过期,请重新登录", // }; // } // } const success = res && res.data && res.data.success === true; if (success) { return res.data; } return { success: false, message: res.data && res.data.message ? res.data.message : "请求失败", }; } catch (error) { console.log("error:", error); if (showLoading) { removeTask(key) } return Promise.reject(error); } }; function recordTask(task) { if (tasks.length === 0) { loading("请求中..."); } tasks.push(task); } function removeTask(task) { const index = tasks.findIndex((i) => i === task); if (index > -1) { tasks.splice(index, 1); } if (tasks.length === 0) { hideLoading(); } } export default request; export const uploadUrl = `${baseUrl}/upload`; export function getFullPath(path) { return `${baseUrl}/${path}`; } export function upload(path) { return new Promise((resolve) => { uni.uploadFile({ url: uploadUrl, // 替换为你的上传接口地址 filePath: path, name: 'file', fileType: 'image', success: (res) => { try { const url = JSON.parse(res.data).filePath; resolve(url ? getFullPath(url) : '') } catch (e) { resolve() } }, fail: res => { resolve() } }) }) }