From d69b1444ff2342413810b8755eaff590f7fa659a Mon Sep 17 00:00:00 2001 From: admin Date: Tue, 2 Jun 2026 20:09:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9C=AA=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E8=AE=BF=E9=97=AE=E8=B4=AD=E7=89=A9=E8=BD=A6=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=8A=A5=E9=94=99=E4=B8=8D=E8=B7=B3=E8=BD=AC=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 给需要认证的路由添加 requiresAuth meta - 修改 API 拦截器,401 错误时跳转登录页 - 路由守卫在用户未登录时拦截并跳转登录页 - 避免公开接口和登录/注册接口的 401 错误触发跳转 Co-Authored-By: Claude Opus 4.8 --- frontend/src/router/index.ts | 22 +++++++++++----------- frontend/src/utils/request.ts | 18 +++++++++--------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index ba0b323..4d19cea 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -15,17 +15,17 @@ const routes = [ { path: '', name: 'Home', component: () => import('../views/user/Home.vue') }, { path: 'products', name: 'Products', component: () => import('../views/user/Products.vue') }, { path: 'products/:id', name: 'ProductDetail', component: () => import('../views/user/ProductDetail.vue') }, - { path: 'cart', name: 'Cart', component: () => import('../views/user/Cart.vue') }, - { path: 'orders', name: 'Orders', component: () => import('../views/user/Orders.vue') }, - { path: 'orders/:id', name: 'OrderDetail', component: () => import('../views/user/OrderDetail.vue') }, - { path: 'checkout/:id', name: 'Checkout', component: () => import('../views/user/Checkout.vue') }, - { path: 'profile', name: 'Profile', component: () => import('../views/user/Profile.vue') }, - { path: 'addresses', name: 'Addresses', component: () => import('../views/user/Addresses.vue') }, - { path: 'lotteries', name: 'Lotteries', component: () => import('../views/user/Lotteries.vue') }, - { path: 'lotteries/:id', name: 'LotteryDetail', component: () => import('../views/user/LotteryDetail.vue') }, - { path: 'tickets', name: 'Tickets', component: () => import('../views/user/Tickets.vue') }, - { path: 'tickets/create', name: 'CreateTicket', component: () => import('../views/user/CreateTicket.vue') }, - { path: 'tickets/:id', name: 'TicketDetail', component: () => import('../views/user/TicketDetail.vue') }, + { path: 'cart', name: 'Cart', component: () => import('../views/user/Cart.vue'), meta: { requiresAuth: true } }, + { path: 'orders', name: 'Orders', component: () => import('../views/user/Orders.vue'), meta: { requiresAuth: true } }, + { path: 'orders/:id', name: 'OrderDetail', component: () => import('../views/user/OrderDetail.vue'), meta: { requiresAuth: true } }, + { path: 'checkout/:id', name: 'Checkout', component: () => import('../views/user/Checkout.vue'), meta: { requiresAuth: true } }, + { path: 'profile', name: 'Profile', component: () => import('../views/user/Profile.vue'), meta: { requiresAuth: true } }, + { path: 'addresses', name: 'Addresses', component: () => import('../views/user/Addresses.vue'), meta: { requiresAuth: true } }, + { path: 'lotteries', name: 'Lotteries', component: () => import('../views/user/Lotteries.vue'), meta: { requiresAuth: true } }, + { path: 'lotteries/:id', name: 'LotteryDetail', component: () => import('../views/user/LotteryDetail.vue'), meta: { requiresAuth: true } }, + { path: 'tickets', name: 'Tickets', component: () => import('../views/user/Tickets.vue'), meta: { requiresAuth: true } }, + { path: 'tickets/create', name: 'CreateTicket', component: () => import('../views/user/CreateTicket.vue'), meta: { requiresAuth: true } }, + { path: 'tickets/:id', name: 'TicketDetail', component: () => import('../views/user/TicketDetail.vue'), meta: { requiresAuth: true } }, { path: 'articles', name: 'Articles', component: () => import('../views/user/Articles.vue') }, { path: 'articles/:id', name: 'ArticleDetail', component: () => import('../views/user/ArticleDetail.vue') }, { path: 'login', name: 'Login', component: () => import('../views/auth/Login.vue'), meta: { guest: true, hideSidebar: true } }, diff --git a/frontend/src/utils/request.ts b/frontend/src/utils/request.ts index 3476953..693bc61 100644 --- a/frontend/src/utils/request.ts +++ b/frontend/src/utils/request.ts @@ -27,18 +27,18 @@ api.interceptors.response.use( const message = error.response?.data?.error || error.message || 'Request failed' if (error.response?.status === 401) { const isLoginRequest = error.config?.url?.includes('/auth/login') - if (isLoginRequest) { + const isRegisterRequest = error.config?.url?.includes('/auth/register') + const isPublicRequest = error.config?.url?.includes('/settings/public') || error.config?.url?.includes('/installed') + + if (isLoginRequest || isRegisterRequest) { ElMessage.error(message) - } else { - const hadToken = !!localStorage.getItem('token') + } else if (!isPublicRequest) { localStorage.removeItem('token') localStorage.removeItem('user') - if (hadToken) { - ElMessage.error('登录已过期,请重新登录') - router.push('/login') - } else { - ElMessage.error(message) - } + ElMessage.error('请先登录') + router.push('/login') + } else { + ElMessage.error(message) } } else { ElMessage.error(message)