| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- 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<string, any> = {},
- ) {
- 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<string, any>) {
- return await internalNavigate('navigateTo', opt.url, opt)
- },
- // 页面重定向,支持登录鉴权
- async redirectTo(opt: { url: string; requiresAuth?: boolean } & Record<string, any>) {
- 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<string, any>) {
- 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
- },
- }
|