ims-front/src/router/index.ts
my_ong ee0525e62b
All checks were successful
Release / lint (push) Successful in 27s
Release / Release (push) Successful in 1m21s
sparkles: 引入菜单权限控制
2024-12-18 12:43:51 +08:00

198 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import UserLayout from '@/layout/user-layout.vue'
import AdminLayout from '@/layout/admin-layout.vue'
import BlankLayout from '@/layout/blank-layout.vue'
export const routes: Array<RouteRecordRaw> = [
{
path: '/admin/dashboard',
meta: { title: 'menus.dashboard', icon: 'icon-dashboard', flat: true },
name: 'Dashboard',
component: () => import('../views/admin/dashboard-page.vue'),
},
{
path: '/admin/acl', // 系统管理
name: 'ACL',
meta: { title: 'menus.acl.name', icon: 'icon-acl', flat: true },
component: BlankLayout,
redirect: () => ({ name: 'Users' }),
children: [
{
path: '/admin/acl/users', //用户列表
name: 'Users',
meta: { title: 'menus.acl.users', icon: 'icon-user' },
component: () => import('../views/admin/acl/users/user-list.vue'),
},
{
path: '/admin/acl/role', // 角色列表
name: 'Role',
meta: { title: 'menus.acl.role', icon: 'icon-role' },
component: () => import('../views/admin/acl/role/role-list.vue'),
},
{
path: '/admin/acl/permission', //权限
name: 'Permission',
meta: { title: 'menus.acl.permission', icon: 'icon-permission' },
component: () => import('../views/admin/acl/permission/permission-management.vue'),
},
{
path: '/admin/acl/material', //物料
name: 'Material',
meta: { title: 'menus.acl.material', icon: 'icon-permission' },
component: () => import('../views/stock/material/material-page.vue'),
},
],
},
{
path: '/stock/name', // 库存管理
name: 'STOCK',
meta: { title: 'menus.stock.name', icon: 'icon-acl', flat: true },
component: BlankLayout,
redirect: () => ({ name: 'Inbound' }),
children: [
{
path: '/stock/inbound', //入库
name: 'Inbound',
meta: { title: 'menus.stock.inbound', icon: 'icon-permission' },
component: () => import('../views/stock/inboud/inboud-page.vue'),
},
{
path: '/stock/outbound', //出库
name: 'Outbound',
meta: { title: 'menus.stock.outbound', icon: 'icon-permission' },
component: () => import('../views/stock/outboud/outbound-page.vue'),
},
{
path: '/stock/stocktaking', //盘点
name: 'Stocktaking',
meta: { title: 'menus.stock.stocktaking', icon: 'icon-permission' },
component: () => import('../views/stock/stocktaking/stocktaking-page.vue'),
},
],
},
{
path: '/statistic/name', // 统计报表
name: 'STATISTIC',
meta: { title: 'menus.statistic.name', icon: 'icon-acl', flat: true },
component: BlankLayout,
redirect: () => ({ name: 'S-Inbound' }),
children: [
{
path: '/statistic/stock', //库存
name: 'S-stock',
meta: { title: 'menus.statistic.stock', icon: 'icon-permission' },
component: () => import('../views/stock/report/materialReport-page.vue'),
},
{
path: '/statistic/inbound', //入库
name: 'S-Inbound',
meta: { title: 'menus.statistic.inbound', icon: 'icon-permission' },
component: () => import('../views/stock/report/inboundReport-page.vue'),
},
{
path: '/statistic/outbound', //出库
name: 'S-Outbound',
meta: { title: 'menus.statistic.outbound', icon: 'icon-permission' },
component: () => import('../views/stock/report/outboundReport-page.vue'),
},
{
path: '/statistic/stocktaking', //盘点
name: 'S-stocktaking',
meta: { title: 'menus.statistic.stocktaking', icon: 'icon-permission' },
component: () => import('../views/stock/report/stocktakingReport-page.vue'),
},
],
},
]
export default createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
name: 'Index',
redirect: '/login',
},
{
path: '/login',
name: 'Login',
redirect: '/login/user',
component: UserLayout,
children: [
{
path: 'user',
name: 'LoginPage',
component: () => import('../views/login/user-login.vue'),
},
],
},
{
path: '/admin',
name: 'Admin',
redirect: '/admin/dashboard',
component: AdminLayout,
meta: { title: 'menus.index', icon: 'icon-home' },
children: routes,
},
{
path: '/:catchAll(.*)',
redirect: '/message',
},
{
path: '/message',
name: 'Message',
component: () => import('@/views/message/message-page.vue'),
},
],
})
export const getP = (permissions: Array<string>): RouteRecordRaw => {
const newRoutes: RouteRecordRaw[] = filterRoutesByPermission(routes, permissions)
return {
path: '/admin',
name: 'Admin',
redirect: '/admin/dashboard',
component: AdminLayout,
meta: { title: 'menus.index', icon: 'icon-home' },
children: newRoutes,
}
}
// 过滤路由,最多两层
const filterRoutesByPermission = (routes: RouteRecordRaw[], permissions: string[]): RouteRecordRaw[] => {
return routes
.map((route) => {
// 确保 route.name 是字符串
const parentName = typeof route.name === 'string' ? route.name : undefined
if ('Dashboard' === parentName) return route // 首页不做权限过滤
const hasParentPermission = parentName && permissions.includes(parentName)
// 如果有子路由,过滤子路由
if (Array.isArray(route.children) && route.children.length > 0) {
route.children = route.children.filter((child) => {
// 确保 child.name 是字符串
const childName = typeof child.name === 'string' ? child.name : undefined
// 拼接父级和子级的权限字符串
const fullName = parentName && childName ? `${parentName}.${childName}` : childName
// 确保 fullName 是字符串并且存在于 permissions 中
return typeof fullName === 'string' && permissions.includes(fullName)
})
// 如果子路由中有任何一个有权限,或者父级路由本身有权限,则保留该父级路由
if (route.children.length > 0 || hasParentPermission) {
return route
}
} else if (hasParentPermission) {
// 如果没有子路由,直接检查父级路由的权限
return route
}
// 如果不符合任何条件,返回 undefined表示该路由将被过滤掉
return undefined
})
.filter((route): route is RouteRecordRaw => route !== undefined) // 过滤掉 undefined 的项并确保类型正确
}