2026-01-19 18:52:18 +08:00
|
|
|
|
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<String|null>}
|
|
|
|
|
|
*/
|
|
|
|
|
|
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 = {};
|
2026-01-20 16:30:03 +08:00
|
|
|
|
if(!options.data.corpId) {
|
|
|
|
|
|
options.data.corpId = env.MP_CORP_ID;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-19 18:52:18 +08:00
|
|
|
|
|
|
|
|
|
|
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}`;
|
|
|
|
|
|
}
|