通用中后台框架第一版
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import type { Component } from 'vue'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
import type { MenuNode } from '@/types/auth'
|
||||
|
||||
const viewModules = import.meta.glob('../features/**/index.vue')
|
||||
|
||||
const dynamicRouteNames = new Set<string>()
|
||||
|
||||
function normalizePath(path: string) {
|
||||
if (!path.startsWith('/')) return `/${path}`
|
||||
return path
|
||||
}
|
||||
|
||||
function routeNameByMenu(menu: MenuNode) {
|
||||
if (menu.name && menu.name.trim().length > 0) {
|
||||
return menu.name.trim()
|
||||
}
|
||||
return `menu-${menu.id}`
|
||||
}
|
||||
|
||||
function resolveViewComponent(componentPath?: string | null): Component {
|
||||
if (!componentPath) {
|
||||
return () => import('@/views/errors/NotFoundView.vue')
|
||||
}
|
||||
const normalized = componentPath.endsWith('.vue') ? componentPath : `${componentPath}.vue`
|
||||
const fullPath = `../features/${normalized}`
|
||||
const component = viewModules[fullPath]
|
||||
if (!component) {
|
||||
return () => import('@/views/errors/NotFoundView.vue')
|
||||
}
|
||||
return component as unknown as Component
|
||||
}
|
||||
|
||||
function toRoute(menu: MenuNode): RouteRecordRaw | null {
|
||||
if (menu.type !== 'MENU') return null
|
||||
if (!menu.path || !menu.component || !menu.visible) return null
|
||||
|
||||
const name = routeNameByMenu(menu)
|
||||
dynamicRouteNames.add(name)
|
||||
|
||||
return {
|
||||
path: normalizePath(menu.path),
|
||||
name,
|
||||
component: resolveViewComponent(menu.component),
|
||||
meta: {
|
||||
title: menu.title,
|
||||
permission: menu.permission ?? undefined,
|
||||
keepAlive: menu.keepAlive,
|
||||
requiresAuth: true,
|
||||
dynamic: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function flattenMenus(menus: MenuNode[]): MenuNode[] {
|
||||
return menus.flatMap((item) => [item, ...flattenMenus(item.children ?? [])])
|
||||
}
|
||||
|
||||
export function buildDynamicRoutes(menus: MenuNode[]) {
|
||||
return flattenMenus(menus)
|
||||
.map(toRoute)
|
||||
.filter((item): item is RouteRecordRaw => Boolean(item))
|
||||
}
|
||||
|
||||
export function consumeDynamicRouteNames() {
|
||||
return [...dynamicRouteNames]
|
||||
}
|
||||
|
||||
export function resetDynamicRouteNames() {
|
||||
dynamicRouteNames.clear()
|
||||
}
|
||||
Reference in New Issue
Block a user