ykt-wxapp/utils/http.js
2026-01-20 19:04:24 +08:00

230 lines
5.2 KiB
JavaScript
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 { 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 = {};
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()
}
})
})
}