2026-01-26 17:00:12 +08:00
|
|
|
|
import { createRouter, createWebHistory } from 'vue-router'
|
2026-02-04 13:30:07 +08:00
|
|
|
|
// 使用 'type' 关键字导入 RouteRecordRaw
|
2026-01-27 15:50:23 +08:00
|
|
|
|
import type { RouteRecordRaw } from 'vue-router'
|
|
|
|
|
|
import Layout from '@/layout/index.vue'
|
2026-02-04 13:30:07 +08:00
|
|
|
|
import { useUserStore } from '@/stores/user' // [新增] 引入 Store 用于权限判断
|
2026-01-26 17:00:12 +08:00
|
|
|
|
|
2026-01-27 15:50:23 +08:00
|
|
|
|
const routes: Array<RouteRecordRaw> = [
|
2026-02-04 13:30:07 +08:00
|
|
|
|
// [新增] 登录页 (不需要 Layout)
|
|
|
|
|
|
{
|
|
|
|
|
|
path: '/login',
|
|
|
|
|
|
name: 'Login',
|
|
|
|
|
|
component: () => import('@/views/login/index.vue'),
|
|
|
|
|
|
meta: { hidden: true } // 不在侧边栏显示
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-01-27 15:50:23 +08:00
|
|
|
|
// 1. 首页 Dashboard
|
2026-01-26 17:00:12 +08:00
|
|
|
|
{
|
|
|
|
|
|
path: '/',
|
2026-01-27 15:50:23 +08:00
|
|
|
|
component: Layout,
|
|
|
|
|
|
redirect: '/dashboard',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
|
|
|
|
|
path: 'dashboard',
|
|
|
|
|
|
name: 'Dashboard',
|
|
|
|
|
|
component: () => import('@/views/dashboard/index.vue'),
|
|
|
|
|
|
meta: { title: '首页', icon: 'HomeFilled' }
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2026-01-26 17:00:12 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
2026-01-28 08:54:11 +08:00
|
|
|
|
// 2. 基础信息 (对应 views/material/list.vue)
|
2026-01-26 17:00:12 +08:00
|
|
|
|
{
|
2026-01-27 15:50:23 +08:00
|
|
|
|
path: '/material',
|
|
|
|
|
|
component: Layout,
|
|
|
|
|
|
redirect: '/material/index',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
|
|
|
|
|
path: 'index',
|
|
|
|
|
|
name: 'MaterialBase',
|
2026-01-28 08:54:11 +08:00
|
|
|
|
// 基础信息列表
|
2026-01-27 15:50:23 +08:00
|
|
|
|
component: () => import('@/views/material/list.vue'),
|
2026-01-28 08:54:11 +08:00
|
|
|
|
meta: { title: '基础信息', icon: 'Box' }
|
2026-01-27 15:50:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 库存管理 (采购/半成品/成品/权益)
|
|
|
|
|
|
{
|
|
|
|
|
|
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: '服务权益' }
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 业务操作 (借库/维修/报废)
|
|
|
|
|
|
{
|
|
|
|
|
|
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',
|
|
|
|
|
|
// 维修页面 (指向 return.vue)
|
|
|
|
|
|
component: () => import('@/views/transaction/return.vue'),
|
|
|
|
|
|
meta: { title: '维修' }
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
path: 'scrap',
|
|
|
|
|
|
name: 'OpScrap',
|
|
|
|
|
|
// 报废页面
|
|
|
|
|
|
component: () => import('@/views/transaction/scrap.vue'),
|
|
|
|
|
|
meta: { title: '报废' }
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-02-04 13:30:07 +08:00
|
|
|
|
// 5. [修改] 系统管理 (权限控制 + 用户创建)
|
|
|
|
|
|
{
|
|
|
|
|
|
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' }
|
|
|
|
|
|
},
|
|
|
|
|
|
// 原有的日志页面保留 (如果文件存在)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// path: 'log',
|
|
|
|
|
|
// name: 'OpLog',
|
|
|
|
|
|
// component: () => import('@/views/system/log.vue'),
|
|
|
|
|
|
// meta: { title: '操作日志', icon: 'Document' }
|
|
|
|
|
|
// }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/* * 暂时屏蔽 BOM
|
2026-01-27 15:50:23 +08:00
|
|
|
|
*/
|
|
|
|
|
|
// {
|
|
|
|
|
|
// path: '/bom',
|
|
|
|
|
|
// component: Layout,
|
|
|
|
|
|
// children: [
|
|
|
|
|
|
// {
|
|
|
|
|
|
// path: 'index',
|
|
|
|
|
|
// name: 'BOM',
|
|
|
|
|
|
// component: () => import('@/views/bom/index.vue'),
|
|
|
|
|
|
// meta: { title: 'BOM管理', icon: 'List' }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// ]
|
|
|
|
|
|
// },
|
|
|
|
|
|
|
|
|
|
|
|
// 404 路由
|
|
|
|
|
|
{
|
|
|
|
|
|
path: '/:pathMatch(.*)*',
|
|
|
|
|
|
redirect: '/dashboard',
|
|
|
|
|
|
meta: { hidden: true }
|
2026-01-26 17:00:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const router = createRouter({
|
|
|
|
|
|
history: createWebHistory(),
|
|
|
|
|
|
routes
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-02-04 13:30:07 +08:00
|
|
|
|
// ==========================================
|
|
|
|
|
|
// [新增] 全局路由守卫:处理登录拦截与权限验证
|
|
|
|
|
|
// ==========================================
|
|
|
|
|
|
router.beforeEach((to, from, next) => {
|
|
|
|
|
|
const userStore = useUserStore()
|
|
|
|
|
|
const token = userStore.token
|
|
|
|
|
|
const userRole = userStore.role
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 白名单:如果是去登录页,直接放行
|
|
|
|
|
|
if (to.path === '/login') {
|
|
|
|
|
|
next()
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 无 Token:强制跳转登录页
|
|
|
|
|
|
if (!token) {
|
|
|
|
|
|
next('/login')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 权限判断:检查 meta.roles
|
|
|
|
|
|
if (to.meta.roles && Array.isArray(to.meta.roles)) {
|
|
|
|
|
|
// 如果当前用户角色在允许列表中,放行
|
|
|
|
|
|
if (to.meta.roles.includes(userRole)) {
|
|
|
|
|
|
next()
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 权限不足,重定向到首页或 403 页面 (这里简单跳回 dashboard)
|
|
|
|
|
|
// 可以在这里触发一个 Element Plus 的 Message 提示
|
|
|
|
|
|
next('/dashboard')
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 没有定义权限要求的页面,默认放行
|
|
|
|
|
|
next()
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-01-26 17:00:12 +08:00
|
|
|
|
export default router
|