f4f7268045
新增 src/pages/error/NotFoundPage.vue(el-result + 返回首页),router 在业务路由 之后注册 :pathMatch(.*)* 兜底(无 menuKey,不参与权限门禁),保留壳层 chrome; main.css 增加 .not-found 布局。
53 lines
1.7 KiB
TypeScript
53 lines
1.7 KiB
TypeScript
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
|
|
import type { AdminMenuNode } from '@/types/admin'
|
|
import AdminLayout from '@/layout/AdminLayout.vue'
|
|
import NotFoundPage from '@/pages/error/NotFoundPage.vue'
|
|
import { useAdminSessionStore } from '@/stores/admin-session'
|
|
import { APP_BASE_PATH } from '@/config/app'
|
|
import { adminRouteRecords } from './routes'
|
|
import { defineLazyPage } from './lazy-page'
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(APP_BASE_PATH),
|
|
routes: [
|
|
{
|
|
path: '/',
|
|
component: AdminLayout,
|
|
children: [
|
|
...adminRouteRecords.map((record) => ({
|
|
...record,
|
|
component: defineLazyPage(record.component as () => Promise<{ default: unknown }>),
|
|
})),
|
|
{ path: ':pathMatch(.*)*', component: NotFoundPage, meta: { title: '页面不存在' } },
|
|
] as RouteRecordRaw[],
|
|
},
|
|
],
|
|
})
|
|
|
|
router.beforeEach(async (to) => {
|
|
const session = useAdminSessionStore()
|
|
if (!session.initialized) {
|
|
try {
|
|
await session.initialize()
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
// 根路由:有可见页面时跳到首个可见页;没有任何页面时停留根路由展示无菜单空态。
|
|
if (to.path === '/') {
|
|
return session.firstVisible || true
|
|
}
|
|
const menuKey = to.meta.menuKey
|
|
if (menuKey && !session.isSuperAdmin && !hasMenu(session.menuTree, menuKey)) {
|
|
// 无权限页面:回退到首个可见页面;一个都没有则回根路由空态。
|
|
return session.firstVisible || '/'
|
|
}
|
|
return true
|
|
})
|
|
|
|
function hasMenu(nodes: AdminMenuNode[], key: string): boolean {
|
|
return nodes.some((node) => node.key === key || hasMenu(node.children || [], key))
|
|
}
|
|
|
|
export default router
|