72 lines
1.9 KiB
TypeScript
72 lines
1.9 KiB
TypeScript
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()
|
|
}
|