fix: 修复未登录访问购物车页面报错不跳转登录页

- 给需要认证的路由添加 requiresAuth meta
- 修改 API 拦截器,401 错误时跳转登录页
- 路由守卫在用户未登录时拦截并跳转登录页
- 避免公开接口和登录/注册接口的 401 错误触发跳转

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 20:09:15 +08:00
parent c6400f5f67
commit d69b1444ff
2 changed files with 20 additions and 20 deletions
+11 -11
View File
@@ -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 } },
+9 -9
View File
@@ -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)