| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /**
- * 路由守卫
- */
- import type { Router } from 'vue-router'
- import { useUserStore, type UserRole } from '@/store/modules/user'
- import { useAppStore } from '@/store/modules/app'
- import { showToast } from 'vant'
- import i18n from '@/locale'
- const { t } = i18n.global
- /**
- * 前置守卫
- */
- export function setupRouterGuards(router: Router) {
- router.beforeEach(async (to, from, next) => {
- const userStore = useUserStore()
- const appStore = useAppStore()
- // 0. 模式守卫
- if (to.path === '/index') {
- // 进入首页,切换为平台模式
- if (!appStore.isPlatformMode) {
- appStore.enterPlatformMode()
- }
- } else if (to.path === '/menu') {
- // 进入菜单页,检查是否有店铺上下文
- const queryShopId = to.query.shopId as string
-
- // 如果URL有shopId,优先使用(处理直接访问)
- if (queryShopId && (!appStore.currentShop || appStore.currentShop.id !== queryShopId)) {
- // TODO: 这里应该从API加载店铺信息
- // 暂时只设置简单的上下文
- appStore.enterShopMode({ id: queryShopId, name: '加载中...', status: 'operating', companyId: '', address: '' })
- }
- // 如果没有context且没有query参数,重定向回首页
- else if (!appStore.currentShop) {
- showToast('请先选择店铺')
- next('/index')
- return
- }
- }
- // 1. 检查是否需要登录
- // guest 用户允许访问菜单和购物车,但不能访问需要登录的页面
- if (to.meta.requiresAuth) {
- // 检查是否登录或有有效会话
- if (!userStore.isLogin && !userStore.isGuest) {
-
- // 特殊处理:如果是Shop Mode下的购物车/结算,提示登录
- if (appStore.isShopMode && ['/cart', '/payment'].some(p => to.path.startsWith(p))) {
- // 允许访问,但在页面内处理登录逻辑
- // 或者跳转登录
- showToast(t('common.pleaseLogin'))
- next({
- path: '/login',
- query: { redirect: to.fullPath }
- })
- return
- }
- showToast(t('common.pleaseLogin'))
- next({
- path: '/login',
- query: { redirect: to.fullPath }
- })
- return
- }
- // guest 用户尝试访问需要登录的页面
- if (userStore.isGuest && to.meta.requiresAuth) {
- // 允许 guest 访问部分页面(订单创建相关)
- const guestAllowedPaths = ['/cart', '/payment', '/order/detail']
- if (!guestAllowedPaths.some(p => to.path.startsWith(p))) {
- showToast(t('common.pleaseLogin'))
- next({
- path: '/login',
- query: { redirect: to.fullPath }
- })
- return
- }
- }
- }
- // 2. 检查角色要求
- if (to.meta.requiresRole) {
- const requiredRoles = Array.isArray(to.meta.requiresRole)
- ? to.meta.requiresRole as UserRole[]
- : [to.meta.requiresRole] as UserRole[]
- const hasRole = requiredRoles.some(role =>
- userStore.availableRoles.includes(role)
- )
- if (!hasRole) {
- showToast(t('role.noPermission'))
- next(false)
- return
- }
- // 3. 自动切换角色(如果当前角色不匹配)
- if (!requiredRoles.includes(userStore.currentRole)) {
- // 如果当前角色不匹配,但用户拥有所需角色,自动切换
- const targetRole = requiredRoles.find(role =>
- userStore.availableRoles.includes(role)
- )
- if (targetRole) {
- userStore.setCurrentRole(targetRole)
- }
- }
- }
- // 4. 检查权限(可选)
- if (to.meta.requiresPermission) {
- const permission = to.meta.requiresPermission as string
- if (!userStore.can(permission)) {
- showToast(t('role.noPermission'))
- next(false)
- return
- }
- }
- next()
- })
- router.afterEach((to) => {
- // 设置页面标题(支持国际化)
- if (to.meta.title) {
- const title = typeof to.meta.title === 'string'
- ? t(to.meta.title)
- : to.meta.title
- document.title = typeof title === 'string' ? title : 'FastEat'
- }
- })
- }
|