import { ref, Ref } from "vue"; import { ACCESS_TOKEN } from "@/constants/home.constants"; import { jumpToAgentDetailPage } from "@/utils/commonBusiness"; import { AgentComponentTypeEnum } from "@/types/enums/agent"; import { apiUserInfo } from "@/servers/account"; import { SUCCESS_CODE } from "@/constants/codes.constants"; import { getCurrentPageFullPath } from "@/utils/common"; /** * 智能体信息基础接口 */ interface AgentInfoBase { targetId: number; name: string; agentType?: "ChatBot" | "PageApp"; targetType?: AgentComponentTypeEnum; agentId?: number; icon?: string; description?: string; } /** * 登录拦截 composable * 用于在点击智能体时进行登录拦截,未登录时显示登录弹窗 * * @returns 返回登录弹窗 ref、处理点击的函数和登录成功回调 */ export const useAuthInterceptor = () => { // 登录弹窗ref const loginPopupRef = ref(null); // 待跳转的智能体信息 // const pendingAgentInfo = ref(null); /** * 检查是否登录 * * - 小程序、H5 开发环境:仅根据本地 ACCESS_TOKEN 是否存在判断 * - H5 正式环境:调用 apiUserInfo 接口判断是否处于登录状态 * * @returns 是否已登录 */ const hasToken = async (): Promise => { // #ifdef MP-WEIXIN const mpToken = uni.getStorageSync(ACCESS_TOKEN); return !!mpToken; // #endif // #ifdef H5 || WEB // 开发环境:只判断本地是否有 token if (process.env.NODE_ENV === "development") { const devToken = uni.getStorageSync(ACCESS_TOKEN); return !!devToken; } // 正式环境:通过接口校验登录状态 try { const res = await apiUserInfo(); const { code, data } = res || {}; if (code === SUCCESS_CODE && data) { return true; } } catch (error) { console.error("检查登录状态失败(apiUserInfo):", error); } return false; // #endif }; /** * 处理智能体点击事件 * @param info 智能体信息 */ const handleAgentClick = async (info: AgentInfoBase) => { // #ifdef H5 || WEB // H5 端统一走登录校验逻辑 const loggedIn = await hasToken(); if (!loggedIn) { // 微信小程序:获取当前页面的 url const currentUrl = getCurrentPageFullPath(); const redirectUrl = "/subpackages/pages/login/login?redirect=" + encodeURIComponent(currentUrl); uni.reLaunch({ url: redirectUrl }); // H5 未登录暂不弹登录弹窗,这里直接返回 return; } performJump(info); // #endif // #ifdef MP-WEIXIN // 检查是否登录 const loggedInMp = await hasToken(); if (!loggedInMp) { // 未登录,保存待跳转的智能体信息(包括 icon, name, description)到本地缓存 const tempAgentInfo = { name: info.name, icon: info.icon || "", description: info.description || "", }; uni.setStorageSync("temp_agent_info", JSON.stringify(tempAgentInfo)); // 跳转到临时会话页面 uni.navigateTo({ url: "/subpackages/pages/temporary-session/temporary-session", }); } else { // 已登录,直接跳转详情页 performJump(info); } // #endif }; /** * 执行跳转逻辑 * @param info 智能体信息 */ const performJump = (info: AgentInfoBase) => { // 优先使用 agentType,如果没有则根据 targetType 判断 let agentType: "ChatBot" | "PageApp" = "ChatBot"; if (info.agentType) { agentType = info.agentType; } else if (info.targetType === AgentComponentTypeEnum.Page) { agentType = "PageApp"; } // 使用 targetId 或 agentId(兼容不同数据结构) const agentId = info.targetId || info.agentId; if (agentId) { jumpToAgentDetailPage(agentId, null, agentType, info.name); } }; /** * 检查登录状态,如果未登录则显示登录弹窗 * @returns 是否已登录 */ const checkAuthAndShowPopup = async (): Promise => { // #ifdef H5 || WEB // H5:根据环境和接口结果判断是否已登录 const loggedInH5 = await hasToken(); return loggedInH5; // #endif // #ifdef MP-WEIXIN const loggedInMp = await hasToken(); if (loggedInMp) { return true; } if (loginPopupRef.value) { loginPopupRef.value.open(); } return false; // #endif }; return { loginPopupRef, handleAgentClick, checkAuthAndShowPopup, hasToken, }; };