import Request from "luch-request" import { isEmpty } from "radash" import isDevEnv from "./isDevEnv" import { router, constant } from "@@/index" import { userApi } from "../api" // 常量定义 const TOKEN_KEY = constant.storageConstant.TOKEN const USER_INFO_KEY = constant.storageConstant.USERINFO // Loading 状态管理 const LoadingInstance = { target: null, count: 0, } // 关闭加载提示 function closeLoading() { if (LoadingInstance.count > 0) LoadingInstance.count-- if (LoadingInstance.count === 0) uni.hideLoading() } // 显示加载提示 function showLoading(message: string) { LoadingInstance.count++ if (LoadingInstance.count === 1) { uni.showLoading({ title: message, mask: true, fail: () => uni.hideLoading(), }) } } // 读取token并处理Authorization请求头 const getAuthHeader = (tokenStorage: any) => { if (isDevEnv()) { return tokenStorage?.access_token ? `Bearer ${tokenStorage.access_token}` : null } return tokenStorage?.accessToken?.tokenValue ? `Bearer ${tokenStorage.accessToken.tokenValue}` : null } // 浙政钉登录 登录成功返回true,否则返回false async function handleZzdLogin(): Promise { try { uni.showLoading({ title: "加载中...", mask: true }) const params = new URL(window.location.href).searchParams const token = params.get("uabaseToken") if (!token) return false const res = await userApi.auth(token) if (res?.code == 0) { uni.setStorageSync(TOKEN_KEY, res.data) const { data: userData } = await userApi.userInfo() uni.setStorageSync(USER_INFO_KEY, userData) return true } else { uni.removeStorageSync(TOKEN_KEY) uni.removeStorageSync(USER_INFO_KEY) if (res.msg == "token已失效") { uni.showToast({ title: "用户凭证已失效,请退出并重新进入智慧后勤应用", icon: "none", duration: 6000 }) } else { uni.showToast({ title: res.msg || "登录失败", icon: "none" }) } return false } } catch (error) { uni.showToast({ title: "登录错误", icon: "none" }) return false } finally { uni.hideLoading() } } // 诗画登录 登录成功返回true,否则返回false async function handleShLogin(): Promise { try { uni.showLoading({ title: "登录中...", mask: true }) const userInfo = await (window as any).CP2.getUserInfo() if (userInfo.code == 0) { uni.showToast({ title: "获取诗画用户信息失败", icon: "none" }) return false } const { accountId, sessionId } = userInfo.data const response = await userApi.authsh({ accountId, sessionId }) if (response.code == 0) { uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken }) const { data: userData } = await userApi.userInfo() uni.setStorageSync(USER_INFO_KEY, userData) uni.showToast({ title: "登录成功", icon: "none" }) return true } else { uni.showToast({ title: "获取用户信息失败", icon: "none" }) uni.removeStorageSync(TOKEN_KEY) uni.removeStorageSync(USER_INFO_KEY) return false } } catch (error) { uni.showToast({ title: "登录错误", icon: "none" }) return false } finally { uni.hideLoading() } } // 根据应用环境自动登录 返回登录结果 async function autoLogin(): Promise { const appInfo = await (window as any).CP2.getAppInfo() // 浙政钉环境 if (appInfo.code == 0) { return await handleZzdLogin() } // 诗画环境 else { return await handleShLogin() } } // token过期刷新检查 async function checkAndRefreshToken(tokenStorage: any) { const { accessToken } = tokenStorage if (!accessToken) return const expiresDate = new Date(accessToken.expiresAt).getTime() // console.log("过期时间", expiresDate) // console.log("现在时间", new Date().getTime()) // console.log("现在时间大于过期时间吗", new Date().getTime() >= expiresDate) // token已过期,尝试刷新 if (new Date().getTime() >= expiresDate) { await autoLogin() } } // 处理错误响应 function handleErrorResponse(response: any) { if (!response.config?.custom?.showError) return switch (response.data.code) { case 401: // 处理未授权情况 setTimeout(() => { uni.removeStorageSync(TOKEN_KEY) uni.removeStorageSync(USER_INFO_KEY) }, 500) break case 424: // 处理token过期 autoLogin() break default: uni.showToast({ title: response.data.msg || "服务器开小差啦,请稍后再试~", icon: "none", mask: true, }) } } // 处理成功提示 function handleSuccessMessage(response: any) { const { data, config } = response if (data.code === 0 && data.message && config?.custom?.showSuccess) { uni.showToast({ title: config.custom.successMsg || data.message, icon: "none", }) } } // 创建请求实例 const http = new Request({ baseURL: import.meta.env.VITE_API_URL, timeout: 8000, method: "GET", header: { Accept: "*/*", "Content-Type": "application/json;charset=UTF-8", }, withCredentials: true, custom: { showSuccess: false, // 成功提醒 默认使用后端返回值 successMsg: "", // 成功消息 showError: true, // 显示失败消息 默认显示 errorMsg: "", // 失败提醒 默认使用后端返回信息 showLoading: true, // 显示请求时loading模态框 默认显示 loadingMsg: "加载中", // loading提醒文字 auth: false, // 需要授权才能请求 默认放开 }, }) // 请求拦截器 http.interceptors.request.use(async (config) => { const tokenStorage = uni.getStorageSync(TOKEN_KEY) const config_header: any = config?.header || {} // 设置租户请求头 config_header["TENANT-ID"] = "1" if (import.meta.env.VITE_IS_TOC === "true") { config_header["CLIENT-TOC"] = "Y" } // 处理 loading if (config.custom?.showLoading) { showLoading(config.custom.loadingMsg) } // 不需要设置认证头的接口 const skipAuthUrls = ["/thirdparty/thirdPartyOAth2", "/sys/auth/refresh-token", "/auth/oauth2/token"] // 判断是否需要设置认证头 const needAuth = !skipAuthUrls.some((url) => config.url?.startsWith(url)) if (needAuth) { if (!isEmpty(tokenStorage)) { // token过期刷新检查 await checkAndRefreshToken(tokenStorage) const authHeader = getAuthHeader(tokenStorage) if (authHeader) { config_header.Authorization = authHeader } } else { // token不存在,则发起登录 await autoLogin() // 登录后重新获取token const newTokenStorage = uni.getStorageSync(TOKEN_KEY) const authHeader = getAuthHeader(newTokenStorage) if (authHeader) { config_header.Authorization = authHeader } } } return config }, Promise.reject) // 响应拦截器 http.interceptors.response.use( async (response) => { // 关闭loading if (response.config?.custom?.showLoading) { closeLoading() } // OAuth2 token请求特殊处理 if (response.config.url === "/auth/oauth2/token") { return Promise.resolve({ code: 0, data: response.data, msg: null, }) } // 错误处理和错误提示 if (response.data.code !== 0) { handleErrorResponse(response) return Promise.resolve(response.data) } // 成功提示 handleSuccessMessage(response) return Promise.resolve(response.data) }, async (error) => { // 处理 loading if (error.config?.custom?.showLoading) { closeLoading() } // 处理 424 错误(token过期) if (error.statusCode === 424) { if (isDevEnv()) { // 开发环境直接清除token并跳转登录 uni.removeStorageSync(TOKEN_KEY) uni.removeStorageSync(USER_INFO_KEY) uni.showToast({ title: "登录已过期,请重新登录", icon: "none" }) router.jump("/pages/test/login") return false } else { await autoLogin() } } // 显示错误信息 if (error?.data?.msg) { uni.showToast({ title: error.data.msg, icon: "none", mask: true, }) } return Promise.resolve(error.data) }, ) // 请求函数 const request = (config: any) => { return http.middleware(config) } export default request