From 29b92a3e61cf10f0d5cdd531707ea647ce9e6b23 Mon Sep 17 00:00:00 2001 From: weiwei Date: Wed, 2 Apr 2025 10:12:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 310 +++++++++++++------------ src/sheep/utils/request.ts | 462 ++++++++++++++----------------------- 2 files changed, 331 insertions(+), 441 deletions(-) diff --git a/src/App.vue b/src/App.vue index 75f3258..ab4bab0 100644 --- a/src/App.vue +++ b/src/App.vue @@ -67,181 +67,179 @@ const tabbar = [ ] export default { - onLaunch() { + async onLaunch() { + if (isDevEnv()) return + console.log("环境判断") // 诗画浦江获取用户信息进行环境判断 - ;(window as any).CP2.getAppInfo().then(async (res) => { - if (res.code !== 0) { - // 不是诗画环境 - const launchParam = new URL(window.location.href).searchParams.get("launchParam") - console.log("app launch 启动路径参数", launchParam) - switch (launchParam) { - case "canteen": - uni.switchTab({ url: "/pages/tabbar/canteen" }) - break - case "selfMerchant": - uni.switchTab({ url: "/pages/tabbar/selfMerchant" }) - break - default: - break + const res = await (window as any).CP2.getAppInfo() + if (res.code == 0) { + // 不是诗画环境 + const launchParam = new URL(window.location.href).searchParams.get("launchParam") + console.log("app launch 启动路径参数", launchParam) + switch (launchParam) { + case "canteen": + uni.switchTab({ url: "/pages/tabbar/canteen" }) + break + case "selfMerchant": + uni.switchTab({ url: "/pages/tabbar/selfMerchant" }) + break + default: + break + } + } else { + // 是诗画环境 + const userRole = uni.getStorageSync("userRole") + if (userRole && userRole == "user") uni.switchTab({ url: "/pages/tabbar/coopMerchant" }) + if (userRole && userRole == "merchant") uni.switchTab({ url: "/pages/tabbar/individualOrder" }) + + const res = await user.isMerchant() + if (res.code == 0) { + if (res.data) { + return uni.redirectTo({ url: "/pages/user/userRole" }) + } else { + uni.setStorageSync("userRole", "user") + uni.switchTab({ url: "/pages/tabbar/coopMerchant" }) } } else { - // 是诗画环境 - const userRole = uni.getStorageSync("userRole") - if (userRole && userRole == "user") uni.switchTab({ url: "/pages/tabbar/coopMerchant" }) - if (userRole && userRole == "merchant") uni.switchTab({ url: "/pages/tabbar/individualOrder" }) - - const res = await user.isMerchant() - if (res.code == 0) { - if (res.data) { - return uni.redirectTo({ url: "/pages/user/userRole" }) - } else { - uni.setStorageSync("userRole", "user") - uni.switchTab({ url: "/pages/tabbar/coopMerchant" }) - } - } else { - uni.showToast({ title: "角色身份判断失败", icon: "none" }) - } + uni.showToast({ title: "角色身份判断失败", icon: "none" }) } - }) + } }, onShow() {}, onHide() {}, methods: { - _initTabbar() { - // const launchPath = uni.getLaunchOptionsSync().path - // console.log("启动路径", launchPath) + async _initTabbar() { + if (isDevEnv()) { + tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath, auth }, index) => { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: true, + }) + }) + return + } const launchParam = new URL(window.location.href).searchParams.get("launchParam") console.log("tabbar launch 启动路径参数", launchParam) // 诗画浦江获取用户信息进行环境判断 - ;(window as any).CP2.getAppInfo().then((res) => { - if (res.code == 0) { - // 不是诗画环境 - if (isDevEnv()) { - tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath, auth }, index) => { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: true, - }) + const res = await (window as any).CP2.getAppInfo() + if (res.code == 0) { + // 不是诗画环境 + switch (launchParam) { + case "canteen": + tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath }, index) => { + if (authPath.includes("pages/tabbar/canteen")) { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: true, + }) + } else { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: false, + }) + } }) - } else { - switch (launchParam) { - case "canteen": - tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath }, index) => { - if (authPath.includes("pages/tabbar/canteen")) { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: true, - }) - } else { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: false, - }) - } + break + case "selfMerchant": + tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath }, index) => { + if (authPath.includes("pages/tabbar/selfMerchant")) { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: true, }) - break - case "selfMerchant": - tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath }, index) => { - if (authPath.includes("pages/tabbar/selfMerchant")) { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: true, - }) - } else { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: false, - }) - } + } else { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: false, }) - break - default: - uni.hideTabBar() - uni.showToast({ title: "启动参数不合法", icon: "none" }) - break - } - } - } else { - // 是诗画环境 - const userRole = uni.getStorageSync("userRole") - switch (userRole) { - case "user": - tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath, auth }, index) => { - if (auth.includes("user")) { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: true, - }) - } else { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: false, - }) - } - }) - break - case "merchant": - tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath, auth }, index) => { - if (auth.includes("merchant")) { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: true, - }) - } else { - uni.setTabBarItem({ - index, - pagePath, - text, - iconPath, - selectedIconPath, - visible: false, - }) - } - }) - break - default: - uni.hideTabBar() - uni.showToast({ title: "用户身份未确认", icon: "none" }) - break - } + } + }) + break + default: + uni.hideTabBar() + uni.showToast({ title: "启动参数不合法", icon: "none" }) + break } - }) + } else { + // 是诗画环境 + const userRole = uni.getStorageSync("userRole") + switch (userRole) { + case "user": + tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath, auth }, index) => { + if (auth.includes("user")) { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: true, + }) + } else { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: false, + }) + } + }) + break + case "merchant": + tabbar.forEach(({ pagePath, text, iconPath, selectedIconPath, authPath, auth }, index) => { + if (auth.includes("merchant")) { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: true, + }) + } else { + uni.setTabBarItem({ + index, + pagePath, + text, + iconPath, + selectedIconPath, + visible: false, + }) + } + }) + break + default: + uni.hideTabBar() + uni.showToast({ title: "用户身份未确认", icon: "none" }) + break + } + } }, }, } diff --git a/src/sheep/utils/request.ts b/src/sheep/utils/request.ts index ed26edf..7450939 100644 --- a/src/sheep/utils/request.ts +++ b/src/sheep/utils/request.ts @@ -4,22 +4,166 @@ 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: any; count: number } = { +// Loading 状态管理 +const LoadingInstance = { target: null, count: 0, } -// 关闭 loading +// 关闭加载提示 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) + 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" }) + 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() + + // 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, @@ -31,88 +175,16 @@ const http = new Request({ }, withCredentials: true, custom: { - showSuccess: false, - // 成功提醒 默认使用后端返回值 - successMsg: "", - // 显示失败消息 默认显示 - showError: true, - // 失败提醒 默认使用后端返回信息 - errorMsg: "", - // 显示请求时loading模态框 默认显示 - showLoading: true, - // loading提醒文字 - loadingMsg: "加载中", - // 需要授权才能请求 默认放开 - auth: false, + showSuccess: false, // 成功提醒 默认使用后端返回值 + successMsg: "", // 成功消息 + showError: true, // 显示失败消息 默认显示 + errorMsg: "", // 失败提醒 默认使用后端返回信息 + showLoading: true, // 显示请求时loading模态框 默认显示 + loadingMsg: "加载中", // loading提醒文字 + auth: false, // 需要授权才能请求 默认放开 }, }) -// 读取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 -} - -// token过期刷新检查 -const checkAndRefreshToken = async (tokenStorage: any) => { - const { accessToken } = tokenStorage - if (!accessToken) return - - const expiresDate = new Date(accessToken.expiresAt).getTime() - // console.log("现在的时间大于过期时间吗:", new Date().getTime() >= expiresDate) - - if (new Date().getTime() >= expiresDate) { - const appInfo = await (window as any).CP2.getAppInfo() - if (appInfo.code == 0) { - try { - uni.showLoading({ title: "加载中...", mask: true }) - const params = new URL(window.location.href).searchParams - const token = params.get("uabaseToken") - if (token) { - const res = await userApi.auth(token) - if (res?.code === 0) { - uni.setStorageSync(TOKEN_KEY, res.data) - } else { - uni.removeStorageSync(TOKEN_KEY) - uni.removeStorageSync(USER_INFO_KEY) - uni.showToast({ title: res.msg, icon: "none" }) - } - } - } catch (error) { - uni.showToast({ title: "错误", icon: "none" }) - } finally { - uni.hideLoading() - } - } else { - // 诗画 - try { - uni.showLoading({ title: "登录中...", mask: true }) - const userInfo = await (window as any).CP2.getUserInfo() - if (userInfo.code == 0) { - return uni.showToast({ title: "获取诗画用户信息失败", icon: "none" }) - } else { - const { accountId, sessionId } = userInfo.data - const response = await userApi.authsh({ accountId, sessionId }) - if (response.code == 0) { - uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken }) - uni.showToast({ title: "登录成功", icon: "none" }) - const { data: userData } = await userApi.userInfo() - uni.setStorageSync(USER_INFO_KEY, userData) - } else { - uni.showToast({ title: "获取用户信息失败", icon: "none" }) - } - } - } catch (error) { - uni.showToast({ title: "错误", icon: "none" }) - } finally { - uni.hideLoading() - } - } - } -} - // 请求拦截器 http.interceptors.request.use(async (config) => { const tokenStorage = uni.getStorageSync(TOKEN_KEY) @@ -126,25 +198,19 @@ http.interceptors.request.use(async (config) => { // 处理 loading if (config.custom?.showLoading) { - LoadingInstance.count++ - if (LoadingInstance.count === 1) { - uni.showLoading({ - title: config.custom.loadingMsg, - mask: true, - fail: () => uni.hideLoading(), - }) - } + showLoading(config.custom.loadingMsg) } - // 设置认证头 - if ( - !config.url?.startsWith("/thirdparty/thirdPartyOAth2") && - config.url !== "/sys/auth/refresh-token" && - config.url !== "/auth/oauth2/token" - ) { + // 不需要设置认证头的接口 + 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过期刷新检查 - checkAndRefreshToken(tokenStorage) + await checkAndRefreshToken(tokenStorage) const authHeader = getAuthHeader(tokenStorage) if (authHeader) { @@ -152,57 +218,13 @@ http.interceptors.request.use(async (config) => { } } else { // token不存在,则发起登录 - const appInfo = await (window as any).CP2.getAppInfo() - if (appInfo.code == 0) { - // 浙政钉 - const params = new URL(window.location.href).searchParams - const token = params.get("uabaseToken") - if (token) { - try { - uni.showLoading({ title: "加载中...", mask: true }) - 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) + await autoLogin() - const authHeader = getAuthHeader(tokenStorage) - if (authHeader) { - config_header.Authorization = authHeader - } - } else { - uni.showToast({ title: "获取浙政钉用户信息失败", icon: "none" }) - } - } catch (error) { - uni.showToast({ title: "错误", icon: "none" }) - } finally { - uni.hideLoading() - } - } - } else { - // 诗画 - try { - uni.showLoading({ title: "登录中...", mask: true }) - const userInfo = await (window as any).CP2.getUserInfo() - if (userInfo.code == 0) { - return uni.showToast({ title: "获取诗画用户信息失败", icon: "none" }) - } else { - const { accountId, sessionId } = userInfo.data - const response = await userApi.authsh({ accountId, sessionId }) - if (response.code == 0) { - uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken }) - uni.showToast({ title: "登录成功", icon: "none" }) - const { data: userData } = await userApi.userInfo() - uni.setStorageSync(USER_INFO_KEY, userData) - } else { - uni.showToast({ title: "获取用户信息失败", icon: "none" }) - } - } - } catch (error) { - uni.showToast({ title: "错误", icon: "none" }) - } finally { - uni.hideLoading() - } + // 登录后重新获取token + const newTokenStorage = uni.getStorageSync(TOKEN_KEY) + const authHeader = getAuthHeader(newTokenStorage) + if (authHeader) { + config_header.Authorization = authHeader } } } @@ -210,91 +232,6 @@ http.interceptors.request.use(async (config) => { return config }, Promise.reject) -// 处理错误响应 -const handleErrorResponse = async (response: any) => { - if (!response.config?.custom?.showError) return - - switch (response.data.code) { - case 401: - // 处理未授权情况 - setTimeout(() => { - uni.removeStorageSync(TOKEN_KEY) - uni.removeStorageSync(USER_INFO_KEY) - // console.log("未授权") - }, 500) - break - case 424: - const appInfo = await (window as any).CP2.getAppInfo() - if (appInfo.code == 0) { - try { - const params = new URL(window.location.href).searchParams - const token = params.get("uabaseToken") - if (token) { - userApi.auth(token).then((res) => { - if (res?.code === 0) { - uni.setStorageSync(TOKEN_KEY, res.data) - } else { - uni.removeStorageSync(TOKEN_KEY) - uni.removeStorageSync(USER_INFO_KEY) - // uni.showToast({ title: "登录已过期", icon: "none" }) - return Promise.resolve({ - code: 1, - data: "登录已过期", - msg: "登录已过期", - }) - } - }) - } - } catch (error) { - uni.hideLoading() - uni.showToast({ title: "错误", icon: "none" }) - } - } else { - // 诗画 - try { - uni.showLoading({ title: "登录中...", mask: true }) - const userInfo = await (window as any).CP2.getUserInfo() - if (userInfo.code == 0) { - return uni.showToast({ title: "获取诗画用户信息失败", icon: "none" }) - } else { - const { accountId, sessionId } = userInfo.data - const response = await userApi.authsh({ accountId, sessionId }) - if (response.code == 0) { - uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken }) - uni.showToast({ title: "登录成功", icon: "none" }) - const { data: userData } = await userApi.userInfo() - uni.setStorageSync(USER_INFO_KEY, userData) - } else { - uni.showToast({ title: "获取用户信息失败", icon: "none" }) - } - } - } catch (error) { - uni.showToast({ title: "错误", icon: "none" }) - } finally { - uni.hideLoading() - } - } - break - default: - uni.showToast({ - title: response.data.msg || "服务器开小差啦,请稍后再试~", - icon: "none", - mask: true, - }) - } -} - -// 处理成功提示 -const 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", - }) - } -} - // 响应拦截器 http.interceptors.response.use( async (response) => { @@ -324,6 +261,11 @@ http.interceptors.response.use( return Promise.resolve(response.data) }, async (error) => { + // 处理 loading + if (error.config?.custom?.showLoading) { + closeLoading() + } + // 处理 424 错误(token过期) if (error.statusCode === 424) { if (isDevEnv()) { @@ -334,58 +276,7 @@ http.interceptors.response.use( router.jump("/pages/test/login") return false } else { - const appInfo = await (window as any).CP2.getAppInfo() - if (appInfo.code == 0) { - try { - uni.showLoading({ title: "加载中...", mask: true }) - const params = new URL(window.location.href).searchParams - const token = params.get("uabaseToken") - if (token) { - userApi.auth(token).then((res) => { - if (res?.code === 0) { - uni.setStorageSync(TOKEN_KEY, res.data) - } else { - uni.removeStorageSync(TOKEN_KEY) - uni.removeStorageSync(USER_INFO_KEY) - // uni.showToast({ title: "登录已过期", icon: "none" }) - return Promise.resolve({ - code: 1, - data: "登录已过期", - msg: "登录已过期", - }) - } - }) - } - } catch (error) { - uni.showToast({ title: "错误", icon: "none" }) - } finally { - uni.hideLoading() - } - } else { - // 诗画 - try { - uni.showLoading({ title: "登录中...", mask: true }) - const userInfo = await (window as any).CP2.getUserInfo() - if (userInfo.code == 0) { - return uni.showToast({ title: "获取诗画用户信息失败", icon: "none" }) - } else { - const { accountId, sessionId } = userInfo.data - const response = await userApi.authsh({ accountId, sessionId }) - if (response.code == 0) { - uni.setStorageSync(TOKEN_KEY, { accessToken: response.data.accessToken }) - uni.showToast({ title: "登录成功", icon: "none" }) - const { data: userData } = await userApi.userInfo() - uni.setStorageSync(USER_INFO_KEY, userData) - } else { - uni.showToast({ title: "获取用户信息失败", icon: "none" }) - } - } - } catch (error) { - uni.showToast({ title: "错误", icon: "none" }) - } finally { - uni.hideLoading() - } - } + await autoLogin() } } @@ -401,6 +292,7 @@ http.interceptors.response.use( }, ) +// 请求函数 const request = (config: any) => { return http.middleware(config) }