import qs from "qs";
import cache from "./cache";
import { refreshTokenService, loginUserService } from "@/service/index";
import { CLIENT_SECRET, CLIENT_ID } from "@/constants/app";
import { to } from "@/utils/util";
let isTokenRefreshing = false;
let refreshTokenTimes = 0;
let wrongAuth = 0;
let firstTokenGetting = false;
let tokenFirstGetTimes = 0;
let subscribers: any[] = [];
function onAccessTokenFetched() {
subscribers.forEach((callback) => {
callback();
});
subscribers = [];
}
const doLogin = async () => {
const [res_code, err_code] = await to(wx.login());
if (err_code) {
console.log("wxlogin出错:", err_code);
}
if (res_code) {
const [res, err] = await loginUserService({
code: res_code.code,
client_id: CLIENT_ID,
});
if (res) {
cache.set(
"access_token",
res.data.data.access_token,
res.data.data.expires_in
);
cache.set("refresh_token", res.data.data.refresh_token);
return res;
}
if (err) {
wx.showToast({
title: "用户认证失败",
icon: "error",
});
}
}
};
const addSubscriber = (callback: any) => {
subscribers.push(callback);
};
const refreshToken = async () => {
if (refreshTokenTimes >= 3) {
console.error("登陆信息过期");
return;
}
console.log("token开始更新");
isTokenRefreshing = true;
refreshTokenTimes++;
const [res] = await refreshTokenService({
access_token: cache.get("refresh_token"),
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
});
isTokenRefreshing = false;
if (res && res.statusCode === 200) {
cache.set(
"access_token",
res.data.data.access_token,
res.data.data.expires_in
);
cache.set("refresh_token", res.data.data.refresh_token);
onAccessTokenFetched();
} else {
refreshToken();
}
};
const getToken = async () => {
if (tokenFirstGetTimes >= 3) {
console.error("登录失败");
return;
}
firstTokenGetting = true;
tokenFirstGetTimes += 1;
console.log("token开始首次获取");
const res = await doLogin();
if (res) {
onAccessTokenFetched();
} else {
getToken();
}
};
const checkHasToken = (url: string, method: any, data: any) => {
if (!firstTokenGetting) {
getToken();
}
const retryOriginalRequest = new Promise((resolve) => {
addSubscriber(() => {
resolve(requestBase(url, method, data));
});
});
return retryOriginalRequest;
};
const checkTokenRefreshStatus = (url: string, method: any, data: any) => {
if (isTokenRefreshing) {
refreshToken();
}
isTokenRefreshing = false;
const retryOriginalRequest = new Promise((resolve) => {
addSubscriber(() => {
resolve(requestBase(url, method, data));
});
});
return retryOriginalRequest;
};
const requestBase = (url: string, method: any, data: any) => {
if (wrongAuth >= 5) {
console.error("多个请求授权失败,重新登陆下?");
return;
}
return new Promise((resolve, reject) => {
wx.request({
url: data ? url : url + "?" + qs.stringify(data),
header: {
"content-type": "application/json;charset=UTF-8;",
authorization: `Bearer ${cache.get("access_token")}`,
},
method: method,
data: data,
success(res) {
if (res && res.statusCode !== 200) {
if (res.statusCode === 401) {
wrongAuth++;
try {
if (!cache.directGet("access_token")) {
resolve(checkHasToken(url, method, data));
}
else if (
res.data.detail === "身份认证信息未提供。" ||
res.data.detail ===
"Authentication credentials were not provided."
) {
resolve(checkTokenRefreshStatus(url, method, data));
}
} catch (e) {
throw e;
}
}
} else {
if (res && res.data.code === 20000) {
resolve(res);
console.log("全局打印请求成功:", res);
} else {
reject(res);
console.log("状态码非20000:", res);
}
}
},
fail(err) {
reject(err);
console.error("全局打印请求失败:", err);
},
});
});
};
export const post = (url: string, data: any) => {
return requestBase(url, "POST", data);
};
export const get = (url: string, data: any) => {
return requestBase(url, "GET", data);
};