Files
KCGL/inventory-web/src/router/index.ts

183 lines
5.1 KiB
TypeScript
Raw Normal View History

import { createRouter, createWebHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
import Layout from '@/layout/index.vue'
2026-02-04 14:29:59 +08:00
import { useUserStore } from '@/stores/user'
const routes: Array<RouteRecordRaw> = [
2026-02-04 14:29:59 +08:00
// 1. 登录页
2026-02-04 13:30:07 +08:00
{
path: '/login',
name: 'Login',
component: () => import('@/views/login/index.vue'),
2026-02-04 14:29:59 +08:00
meta: { hidden: true }
2026-02-04 13:30:07 +08:00
},
2026-02-04 14:29:59 +08:00
// 2. 首页 Dashboard
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index.vue'),
meta: { title: '首页', icon: 'HomeFilled' }
}
]
},
2026-02-04 14:29:59 +08:00
// 3. 基础信息
{
path: '/material',
component: Layout,
redirect: '/material/index',
children: [
{
path: 'index',
name: 'MaterialBase',
component: () => import('@/views/material/list.vue'),
meta: { title: '基础信息', icon: 'Box' }
}
]
},
2026-02-04 14:29:59 +08:00
// 4. 库存管理
{
path: '/inventory',
component: Layout,
meta: { title: '库存管理', icon: 'Shop' },
redirect: '/inventory/buy',
children: [
{
path: 'buy',
name: 'InventoryBuy',
component: () => import('@/views/stock/inbound/buy.vue'),
meta: { title: '采购件' }
},
{
path: 'semi',
name: 'InventorySemi',
component: () => import('@/views/stock/inbound/semi.vue'),
meta: { title: '半成品' }
},
{
path: 'product',
name: 'InventoryProduct',
component: () => import('@/views/stock/inbound/product.vue'),
meta: { title: '成品' }
},
{
path: 'service',
name: 'InventoryService',
component: () => import('@/views/stock/inbound/service.vue'),
meta: { title: '服务权益' }
}
]
},
2026-02-04 14:29:59 +08:00
// 5. 业务操作
{
path: '/operation',
component: Layout,
meta: { title: '业务操作', icon: 'Operation' },
redirect: '/operation/borrow',
children: [
{
path: 'borrow',
name: 'OpBorrow',
component: () => import('@/views/transaction/borrow.vue'),
meta: { title: '借库' }
},
{
path: 'repair',
name: 'OpRepair',
component: () => import('@/views/transaction/return.vue'),
meta: { title: '维修' }
},
{
path: 'scrap',
name: 'OpScrap',
component: () => import('@/views/transaction/scrap.vue'),
meta: { title: '报废' }
}
]
},
2026-02-04 14:29:59 +08:00
// 6. 系统管理
2026-02-04 13:30:07 +08:00
{
path: '/system',
component: Layout,
meta: {
title: '系统管理',
icon: 'Setting',
roles: ['super_admin', 'supervisor']
},
children: [
{
path: 'user-create',
name: 'UserCreate',
component: () => import('@/views/system/UserCreate.vue'),
meta: { title: '账号开通', icon: 'User' }
2026-02-04 14:29:59 +08:00
}
2026-02-04 13:30:07 +08:00
]
},
// 404 路由
{
path: '/:pathMatch(.*)*',
redirect: '/dashboard',
meta: { hidden: true }
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
2026-02-04 13:30:07 +08:00
// ==========================================
2026-02-04 14:29:59 +08:00
// [关键修改] 全局路由守卫
2026-02-04 13:30:07 +08:00
// ==========================================
router.beforeEach((to, from, next) => {
const userStore = useUserStore()
2026-02-04 14:29:59 +08:00
// 1. 实时获取 Token (优先取 store,防止 store 未初始化取 localStorage)
const token = userStore.token || localStorage.getItem('token')
const userRole = userStore.role || localStorage.getItem('role') || 'user'
// 2. 如果要去的是登录页
2026-02-04 13:30:07 +08:00
if (to.path === '/login') {
2026-02-04 14:29:59 +08:00
// 如果有 Token,说明已登录,踢回首页 (防止重复登录)
if (token) {
next('/')
} else {
// 没有 Token,允许访问登录页
next()
}
2026-02-04 13:30:07 +08:00
return
}
2026-02-04 14:29:59 +08:00
// 3. 如果去的不是登录页,但没有 Token
2026-02-04 13:30:07 +08:00
if (!token) {
2026-02-04 14:29:59 +08:00
// 强制重定向到登录页
// 使用 replace 防止用户点击浏览器“返回”按钮时进入死循环
next({ path: '/login', replace: true })
2026-02-04 13:30:07 +08:00
return
}
2026-02-04 14:29:59 +08:00
// 4. 权限判断 (已有 Token)
2026-02-04 13:30:07 +08:00
if (to.meta.roles && Array.isArray(to.meta.roles)) {
if (to.meta.roles.includes(userRole)) {
next()
} else {
2026-02-04 14:29:59 +08:00
// 权限不足,跳回首页
2026-02-04 13:30:07 +08:00
next('/dashboard')
}
} else {
2026-02-04 14:29:59 +08:00
// 无特殊权限要求,放行
2026-02-04 13:30:07 +08:00
next()
}
})
export default router