import getConfig from "./config.js";
|
const { baseURL } = getConfig();
|
// @/utils/request.js
|
let isRedirectingToLogin = false;
|
|
// 全局 SSO 处理标记(挂载到 uni 上,便于跨模块共享)
|
uni.__isSSOHandling = false;
|
|
const showToast = (message) => {
|
if (uni.$u?.toast) {
|
uni.$u.toast(message);
|
} else {
|
uni.showToast({ title: message, icon: "none" });
|
}
|
};
|
console.log(baseURL,'baseURL');
|
|
const config = {
|
baseURL: baseURL,
|
timeout: 60000,
|
header: {
|
"Content-Type": "application/json",
|
"X-Business-System": "medical-system",
|
},
|
loginPage: "/pages/login/Login",
|
tokenExpiredCode: 401,
|
noPermissionCode: 403,
|
whiteList: ["/login", "/getToken", "/GiLink/getCode"],
|
};
|
|
const isInWhiteList = (url) => {
|
const relativeUrl = url.replace(config.baseURL, "").split("?")[0];
|
return config.whiteList.some((path) => {
|
if (path.endsWith("/")) return relativeUrl.startsWith(path);
|
return relativeUrl === path;
|
});
|
};
|
|
const navigateToLogin = () => {
|
// SSO 处理中,不重复跳转
|
if (isRedirectingToLogin || uni.__isSSOHandling) {
|
console.log("正在跳转登录页或SSO处理中,跳过");
|
return;
|
}
|
|
isRedirectingToLogin = true;
|
|
const pages = getCurrentPages();
|
const currentPage = pages[pages.length - 1];
|
const isLoginPage =
|
currentPage &&
|
currentPage.route &&
|
currentPage.route.includes("login/Login");
|
|
if (isLoginPage) {
|
console.log("当前已在登录页,不跳转");
|
isRedirectingToLogin = false;
|
return;
|
}
|
|
console.log("跳转到登录页");
|
setTimeout(() => {
|
uni.redirectTo({
|
url:
|
config.loginPage +
|
"?redirect=" +
|
encodeURIComponent(getCurrentPagePath()),
|
success: () => {
|
console.log("跳转登录页成功");
|
isRedirectingToLogin = false;
|
},
|
fail: () => {
|
console.log("跳转登录页失败");
|
isRedirectingToLogin = false;
|
},
|
});
|
}, 100);
|
};
|
|
const getCurrentPagePath = () => {
|
const pages = getCurrentPages();
|
return pages[pages.length - 1]?.route || "";
|
};
|
|
const checkTokenExpired = (statusCode) => {
|
if (statusCode === config.tokenExpiredCode) {
|
showToast("登录已过期,请重新登录");
|
navigateToLogin();
|
return true;
|
}
|
return false;
|
};
|
|
const requestInterceptor = (options) => {
|
const token = uni.getStorageSync("token");
|
|
if (isInWhiteList(options.url)) {
|
console.log("白名单接口,跳过token校验:", options.url);
|
return options;
|
}
|
|
if (!token) {
|
const pages = getCurrentPages();
|
const currentPage = pages[pages.length - 1];
|
const isLoginPage =
|
currentPage &&
|
currentPage.route &&
|
(currentPage.route.includes("login/Login") ||
|
currentPage.route.includes("login/DingTalkLogin"));
|
|
if (isLoginPage) {
|
console.log("当前是登录页,允许无token请求");
|
return options;
|
}
|
|
console.log("未登录且不在登录页,跳转到登录页");
|
navigateToLogin();
|
throw new Error("未登录");
|
}
|
|
options.header = {
|
...options.header,
|
Authorization: `Bearer ${token}`,
|
};
|
return options;
|
};
|
|
const responseInterceptor = (response) => {
|
const { statusCode, data } = response;
|
if (checkTokenExpired(statusCode)) return Promise.reject(data);
|
if (statusCode === config.noPermissionCode) {
|
showToast("无权限访问");
|
return Promise.reject(data);
|
}
|
if (statusCode !== 200) {
|
showToast(`请求失败: ${statusCode}`);
|
return Promise.reject(data);
|
}
|
if (data?.code !== 200) {
|
showToast(data?.msg || "操作失败");
|
return Promise.reject(data);
|
}
|
return data;
|
};
|
|
const request = async (options) => {
|
try {
|
options = {
|
...config,
|
...options,
|
url: config.baseURL + options.url,
|
header: { ...config.header, ...options.header },
|
};
|
options = await requestInterceptor(options);
|
return new Promise((resolve, reject) => {
|
uni.request({
|
...options,
|
success: (res) => resolve(responseInterceptor(res)),
|
fail: (err) => {
|
showToast("网络错误,请重试");
|
reject(err);
|
},
|
});
|
});
|
} catch (err) {
|
return Promise.reject(err);
|
}
|
};
|
|
const http = {
|
get(url, data = {}, options = {}) {
|
return request({ url, data, method: "GET", ...options });
|
},
|
post(url, data = {}, options = {}) {
|
return request({ url, data, method: "POST", ...options });
|
},
|
put(url, data = {}, options = {}) {
|
return request({ url, data, method: "PUT", ...options });
|
},
|
delete(url, data = {}, options = {}) {
|
return request({ url, data, method: "DELETE", ...options });
|
},
|
upload(url, filePath, name = "file", formData = {}) {
|
return request({
|
url,
|
method: "POST",
|
filePath,
|
name,
|
formData,
|
header: { "Content-Type": "multipart/form-data" },
|
});
|
},
|
};
|
|
uni.$uapi = http;
|
export default http;
|