import { getCurrentInstance, type App } from 'vue' import { useUserLoginStore } from '@/store/login' import { Pages } from './pages' import { LoginPopupViewer } from './loginPopupServices' import Loading from './Loading' /** 实时判断用户是否已登录(避免 computed 缓存) */ function isUserLoggedIn(): boolean { return useUserLoginStore().isLoggedIn } // 路由相关配置 // 这里可以根据实际情况调整 // 例如:需要登录验证的页面等 // 以及登录页面、会员中心页面等 // 需要登录验证的页面 const authPages = [ Pages.USER_INFO_EDIT, Pages.VIP_CENTER, //Pages.PRODUCT_LIST, //Pages.PRODUCT_DETAILS, Pages.USER_ACCOUNT_SECURITY, Pages.USER_EDIT_NICKNAME, Pages.USER_ORDER_LIST, Pages.USER_ORDER_DETAILS, Pages.USER_MOBILE, Pages.DISTRIBUTION_CENTER, Pages.DISTRIBUTION_CENTER_DETAILS, Pages.USER_MOBILE_CHANGE, Pages.USER_PERSONAL_INFO, Pages.USER_REMARK, Pages.PRODUCT_ORDER_CONFIRM, Pages.PRODUCT_PAY_MODE, Pages.COUPON_CENTER, Pages.COUPON_LIST, Pages.CUSTOMER_SERVICE, Pages.SHIPPING_ADDRESS_ADDED_OR_EDIT, Pages.SHIPPING_ADDRESS_LIST, Pages.USER_PASSWORD_CONFIG, Pages.WITHDRAWAL, Pages.WITHDRAWAL_RECORD_LIST, ] /** 判断是否需要登录 */ function getBasePath(url: string): string { const index = url.indexOf('?') return index !== -1 ? url.substring(0, index) : url } function isAuthRequired(url: string): boolean { const cleanUrl = getBasePath(url) console.log(`URL数据源:${authPages}`) console.log(`URL原始值: ${url}`) console.log(`URL过滤值: ${cleanUrl}`) return authPages.some((item) => item === cleanUrl) } /** 缓存跳转路径 */ function cacheRedirect(url: string) { uni.setStorageSync('pending_redirect', url) } /** 读取并清除缓存跳转路径 */ function consumeRedirect(): string | null { const url = uni.getStorageSync('pending_redirect') uni.removeStorageSync('pending_redirect') return url || null } /** 路由核心跳转方法 */ async function internalNavigate( type: 'navigateTo' | 'redirectTo' | 'switchTab' | 'reLaunch', url: string, options: Record = {}, ) { const originUrl: string = url.startsWith('/') ? url : `/${url}` const isAuthPage = isAuthRequired(originUrl) console.log(`[Router][${type}] 跳转到:`, originUrl, '需要登录:', isAuthPage) console.log(`[Router][${type}] 是否登录:`, isUserLoggedIn) // 如果需要登录但未登录,则弹出登录框 if (isAuthPage && !isUserLoggedIn()) { cacheRedirect(originUrl) const loginResult = await LoginPopupViewer.open() console.log(`[Router][${type}] 登录弹窗结果:`, loginResult) // 如果登录失败(或用户取消),中断跳转 if (!loginResult) { console.log(`[Router][${type}] 已终止跳转,原因:用户未登录或取消登录`) Loading.showError({ msg: '已取消登录' }) return } } // 登录状态已满足,可以安全跳转 try { switch (type) { case 'navigateTo': return await uniNavigateTo(originUrl, options) case 'redirectTo': return await uniRedirectTo(originUrl, options) case 'switchTab': return await uniSwitchTab(originUrl) case 'reLaunch': return await uniReLaunch(originUrl) } } catch (error) { console.error(`[Router][${type}] 跳转失败:`, error) } } /** ✅ Promise 封装 uni API **/ function uniNavigateTo(url: string, options: any) { return new Promise((resolve, reject) => { uni.navigateTo({ url, ...options, success: resolve, fail: reject, }) }) } function uniRedirectTo(url: string, options: any) { return new Promise((resolve, reject) => { uni.redirectTo({ url, ...options, success: resolve, fail: reject, }) }) } function uniSwitchTab(url: string) { return new Promise((resolve, reject) => { uni.switchTab({ url, success: resolve, fail: reject, }) }) } function uniReLaunch(url: string) { return new Promise((resolve, reject) => { uni.reLaunch({ url, success: resolve, fail: reject, }) }) } // ✅ Router API 对象 // ✅ Router API 对象 export const Router = { // 页面跳转,支持登录鉴权 async navigateTo(opt: { url: string; requiresAuth?: boolean } & Record) { return await internalNavigate('navigateTo', opt.url, opt) }, // 页面重定向,支持登录鉴权 async redirectTo(opt: { url: string; requiresAuth?: boolean } & Record) { return await internalNavigate('redirectTo', opt.url, opt) }, // tab 页面切换 async switchTab(opt: { url: string }) { return await internalNavigate('switchTab', opt.url, opt) }, // 重新启动应用跳转 async reLaunch(opt: { url: string }) { return await internalNavigate('reLaunch', opt.url, opt) }, // 重定向别名 async replace(opt: { url: string; requiresAuth?: boolean } & Record) { return await internalNavigate('redirectTo', opt.url, opt) }, // 返回上一级 async back(delta = 1) { return await new Promise((resolve, reject) => { uni.navigateBack({ delta, success: resolve, fail: reject, }) }) }, consumeRedirect, } let cachedRouter: typeof Router | null = null /** * ✅ 全局安全获取 $Router 实例(推荐使用) */ export function useRouter(): typeof Router { if (cachedRouter) return cachedRouter const instance = getCurrentInstance() if (!instance) { throw new Error('useRouter() 必须在 setup() 或生命周期中调用') } const router = instance.appContext.config.globalProperties.$Router if (!router) { throw new Error('$Router 尚未注入,请在 main.ts 中使用 app.use(RouterPlugin)') } cachedRouter = router return router } /** ✅ 注册为全局插件 */ export default { install(app: App) { app.config.globalProperties.$Router = Router }, }