TakeOutShop/utils/http.js

80 lines
2.3 KiB
JavaScript

// utils/http.js
import { ref } from 'vue';
import { url } from '@/server/config.js'
import { useCounterStore } from '@/store/counter';
const authStore = useCounterStore();
let isRefreshing = false;// 是否正在刷新 Token
let requestsQueue = [];// 等待队列
let retryCount = 0;// 当前重试次数
/**
* 刷新 Token
*/
const refreshToken = async () => {
//1. 获取微信 code
const { code } = await uni.login({ provider: 'weixin'});
const res = await uni.request({
url: `${url}/api/front/wechat/authorize/program/login?code=${code}`,
method: 'POST',
data: {}
});
const { token,uid,phone,nikeName } = res.data.data;
//成功:更新 Token 并重置重试计数
authStore.setToken(token,uid,phone,nikeName);
retryCount = 0;
return true;
};
/**
* 封装请求(防死循环关键逻辑)
*/
export const request = async (options) => {
//发起请求
const _request = () => {
return new Promise((resolve, reject) => {
//动态读取最新Token
const currentToken = authStore.token;
uni.request({
url:`${url}${options.url}` ,
method: options.method || 'GET',
data: options.data || {},
header: {
'Content-Type': options.contenttype ||'application/json',
'Authori-zation':`${currentToken}`
},
success: (res) => {
const { code } = res.data;
if(code === 200){
resolve(res.data);
}else if (code === 401) {
//1. 如果正在刷新,加入队列等待
if (isRefreshing) {
requestsQueue.push(() => resolve(_request()));
return;
}
//2. 触发刷新 Token
isRefreshing = true;
refreshToken().then((success) => {
if (success) {
//刷新成功:重试队列中的请求
requestsQueue.forEach(cb => cb());
}
}).finally(() => {
isRefreshing = false;
requestsQueue = []; // 清空队列(无论成功与否)
});
// 3.当前请求加入队列
requestsQueue.push(() => resolve(_request()));
} else {
console.log('报错啦',res);
reject(res.data)
}
},
fail: (err) => reject(err)
});
});
};
try {
return await _request();
} catch (err) {
throw err;
}
};