|
@@ -1,12 +1,10 @@
|
|
|
-/**
|
|
|
|
|
- * 路由守卫
|
|
|
|
|
- */
|
|
|
|
|
-
|
|
|
|
|
import type { Router } from 'vue-router'
|
|
import type { Router } from 'vue-router'
|
|
|
import { useUserStore, type UserRole } from '@/store/modules/user'
|
|
import { useUserStore, type UserRole } from '@/store/modules/user'
|
|
|
import { useAppStore } from '@/store/modules/app'
|
|
import { useAppStore } from '@/store/modules/app'
|
|
|
import { showToast } from 'vant'
|
|
import { showToast } from 'vant'
|
|
|
import i18n from '@/locale'
|
|
import i18n from '@/locale'
|
|
|
|
|
+import { guestLogin } from '@/api/guest'
|
|
|
|
|
+import { storage } from '@/utils/storage'
|
|
|
|
|
|
|
|
const { t } = i18n.global
|
|
const { t } = i18n.global
|
|
|
|
|
|
|
@@ -27,13 +25,55 @@ export function setupRouterGuards(router: Router) {
|
|
|
} else if (to.path === '/menu') {
|
|
} else if (to.path === '/menu') {
|
|
|
// 进入菜单页,检查是否有店铺上下文
|
|
// 进入菜单页,检查是否有店铺上下文
|
|
|
const queryShopId = to.query.shopId as string
|
|
const queryShopId = to.query.shopId as string
|
|
|
|
|
+ const queryTableCode = to.query.tableCode as string
|
|
|
|
|
|
|
|
// 如果URL有shopId,优先使用(处理直接访问)
|
|
// 如果URL有shopId,优先使用(处理直接访问)
|
|
|
- if (queryShopId && (!appStore.currentShop || appStore.currentShop.id !== queryShopId)) {
|
|
|
|
|
- // TODO: 这里应该从API加载店铺信息
|
|
|
|
|
- // 暂时只设置简单的上下文
|
|
|
|
|
- appStore.enterShopMode({ id: queryShopId, name: '加载中...', status: 'operating', companyId: '', address: '' })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (queryShopId) {
|
|
|
|
|
+ // 1. 桌台模式 (带 tableCode)
|
|
|
|
|
+ if (queryTableCode) {
|
|
|
|
|
+ // 设置应用状态为桌台模式
|
|
|
|
|
+ const mockShop = { id: queryShopId, name: '加载中...', status: 'operating' as const, companyId: '', address: '' }
|
|
|
|
|
+ const mockTable = { id: queryTableCode, code: queryTableCode, name: `${queryTableCode}桌` } // 简单模拟
|
|
|
|
|
+
|
|
|
|
|
+ // 只有当当前状态不一致时才更新,避免重复调用
|
|
|
|
|
+ if (!appStore.isTableMode || appStore.tableCode !== queryTableCode) {
|
|
|
|
|
+ appStore.enterTableMode(mockShop, mockTable)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果未登录,初始化访客会话并调用游客登录API
|
|
|
|
|
+ if (!userStore.isLogin && !userStore.isGuest) {
|
|
|
|
|
+ // 获取或创建设备ID
|
|
|
|
|
+ const deviceId = userStore.getOrCreateDeviceId()
|
|
|
|
|
+ // 保存到localStorage供request拦截器使用
|
|
|
|
|
+ storage.set('guestDeviceId', deviceId)
|
|
|
|
|
+
|
|
|
|
|
+ // 初始化本地访客状态
|
|
|
|
|
+ userStore.initGuestSession({
|
|
|
|
|
+ tableId: queryTableCode,
|
|
|
|
|
+ tableCode: queryTableCode,
|
|
|
|
|
+ tableName: `${queryTableCode}桌`,
|
|
|
|
|
+ shopId: queryShopId,
|
|
|
|
|
+ sessionId: `guest_${Date.now()}`,
|
|
|
|
|
+ createdAt: Date.now()
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 异步调用游客登录API(不阻塞路由)
|
|
|
|
|
+ guestLogin({ deviceId }).then((res) => {
|
|
|
|
|
+ if (res?.token) {
|
|
|
|
|
+ userStore.setGuestToken(res.token)
|
|
|
|
|
+ storage.set('guestToken', res.token)
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch((err) => {
|
|
|
|
|
+ console.warn('Guest login failed:', err)
|
|
|
|
|
+ // 即使登录失败,也允许访问菜单(离线模式)
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 2. 普通店铺模式 (不带 tableCode)
|
|
|
|
|
+ else if (!appStore.currentShop || appStore.currentShop.id !== queryShopId) {
|
|
|
|
|
+ appStore.enterShopMode({ id: queryShopId, name: '加载中...', status: 'operating' as const, companyId: '', address: '' })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
// 如果没有context且没有query参数,重定向回首页
|
|
// 如果没有context且没有query参数,重定向回首页
|
|
|
else if (!appStore.currentShop) {
|
|
else if (!appStore.currentShop) {
|
|
|
showToast('请先选择店铺')
|
|
showToast('请先选择店铺')
|
|
@@ -45,6 +85,28 @@ export function setupRouterGuards(router: Router) {
|
|
|
// 1. 检查是否需要登录
|
|
// 1. 检查是否需要登录
|
|
|
// guest 用户允许访问菜单和购物车,但不能访问需要登录的页面
|
|
// guest 用户允许访问菜单和购物车,但不能访问需要登录的页面
|
|
|
if (to.meta.requiresAuth) {
|
|
if (to.meta.requiresAuth) {
|
|
|
|
|
+ // 定义 guest 可访问的路径(订单相关)
|
|
|
|
|
+ const guestAllowedPaths = ['/cart', '/payment', '/order/detail', '/order']
|
|
|
|
|
+ const isGuestAllowedPath = guestAllowedPaths.some(p => to.path.startsWith(p))
|
|
|
|
|
+
|
|
|
|
|
+ // 如果是 Table Mode(appStore 有桌台信息),自动视为 Guest 允许访问特定路由
|
|
|
|
|
+ if (appStore.isTableMode && isGuestAllowedPath) {
|
|
|
|
|
+ // 如果仍然没有 guest session,补充初始化
|
|
|
|
|
+ if (!userStore.isLogin && !userStore.isGuest && appStore.currentTable) {
|
|
|
|
|
+ userStore.initGuestSession({
|
|
|
|
|
+ tableId: appStore.currentTable.code,
|
|
|
|
|
+ tableCode: appStore.currentTable.code,
|
|
|
|
|
+ tableName: appStore.currentTable.name,
|
|
|
|
|
+ shopId: appStore.currentShop?.id || '',
|
|
|
|
|
+ sessionId: `guest_${Date.now()}`,
|
|
|
|
|
+ createdAt: Date.now()
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ // Table Mode 下访问允许的路径,直接放行
|
|
|
|
|
+ next()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 检查是否登录或有有效会话
|
|
// 检查是否登录或有有效会话
|
|
|
if (!userStore.isLogin && !userStore.isGuest) {
|
|
if (!userStore.isLogin && !userStore.isGuest) {
|
|
|
|
|
|
|
@@ -70,9 +132,8 @@ export function setupRouterGuards(router: Router) {
|
|
|
|
|
|
|
|
// guest 用户尝试访问需要登录的页面
|
|
// guest 用户尝试访问需要登录的页面
|
|
|
if (userStore.isGuest && to.meta.requiresAuth) {
|
|
if (userStore.isGuest && to.meta.requiresAuth) {
|
|
|
- // 允许 guest 访问部分页面(订单创建相关)
|
|
|
|
|
- const guestAllowedPaths = ['/cart', '/payment', '/order/detail']
|
|
|
|
|
- if (!guestAllowedPaths.some(p => to.path.startsWith(p))) {
|
|
|
|
|
|
|
+ // 允许 guest 访问部分页面(订单创建相关 + 订单列表)
|
|
|
|
|
+ if (!isGuestAllowedPath) {
|
|
|
showToast(t('common.pleaseLogin'))
|
|
showToast(t('common.pleaseLogin'))
|
|
|
next({
|
|
next({
|
|
|
path: '/login',
|
|
path: '/login',
|