mirror of
https://gitee.com/mirrors/AllinSSL.git
synced 2026-03-13 10:00:53 +08:00
146 lines
5.3 KiB
TypeScript
146 lines
5.3 KiB
TypeScript
import type { RouteRecordRaw } from 'vue-router'
|
|
import { kebabCase } from '@baota/utils/string'
|
|
|
|
// 路由配置选项
|
|
export interface RouteOptions {
|
|
framework: string[] // 框架路由
|
|
system: string[] // 系统路由
|
|
sort: { name: string; title: string }[] // 路由排序
|
|
disabled: string[] // 禁用路由
|
|
}
|
|
|
|
/**
|
|
* 自动导入路由配置
|
|
* 自动导入 src/views 下的路由组件
|
|
*
|
|
* 路由命名规则:
|
|
* 1. 路由路径使用 kebab-case 命名法(短横线命名法)
|
|
* 2. 路由名称使用 camelCase 命名法(驼峰命令法)
|
|
* 3. 子路由路径会自动拼接父路由路径
|
|
*
|
|
* 例如:
|
|
* src/views/userManagement/index.tsx -> /user-management
|
|
* src/views/userManagement/children/userDetail/index.tsx -> /user-management/user-detail
|
|
*/
|
|
export function generateRoutes(
|
|
mainRoute: Record<string, () => Promise<unknown>>,
|
|
childrenRoutes: Record<string, () => Promise<unknown>>,
|
|
routesOptions: RouteOptions,
|
|
): { system: RouteRecordRaw[]; framework: RouteRecordRaw[]; routes: RouteRecordRaw[] } {
|
|
const { framework, system, sort: routesSort, disabled: routesDisabled } = routesOptions
|
|
|
|
const routes: RouteRecordRaw[] = [] // 路由列表
|
|
const systemRoutes: RouteRecordRaw[] = [] // 系统路由
|
|
const frameworkRoutes: RouteRecordRaw[] = [] // 框架路由
|
|
|
|
// 导入所有视图组件,基于 src/views 目录
|
|
// 使用 Vite 的 import.meta.glob 进行自动导入
|
|
const modules = mainRoute
|
|
const childrenModules = childrenRoutes
|
|
const modulesRegex = /\/views\/([^/]+)\/index\.tsx$/
|
|
const childrenModulesRegex = /\/views\/([^/]+)\/children\/([^/]+)\/index\.tsx$/
|
|
|
|
// 遍历所有视图组件
|
|
for (const path in modules) {
|
|
// 路由禁用,用于测试和开发处理
|
|
if (routesDisabled.includes(path)) continue
|
|
|
|
// 提取路由名称
|
|
const routeName = path.match(modulesRegex)![1] || ''
|
|
|
|
// 获取路由中文标题
|
|
const metaName = routesSort.find((item) => item.name === routeName)
|
|
|
|
// 创建路由配置
|
|
const route: RouteRecordRaw = {
|
|
name: routeName,
|
|
path: `/${kebabCase(routeName)}`,
|
|
meta: { title: metaName?.title || routeName, icon: routeName },
|
|
component: modules[path],
|
|
children: [],
|
|
}
|
|
|
|
// 系统路由
|
|
if (system.length && system.includes(routeName)) {
|
|
systemRoutes.push(route)
|
|
// 框架路由
|
|
} else if (framework.length && framework.includes(routeName)) {
|
|
route.path = '/' // 框架路由路径为根路径
|
|
// 查找第一个未禁用的路由作为重定向目标
|
|
const firstEnabledRoute = routesSort.find((item) => !routesDisabled.includes(item.name))
|
|
route.redirect = firstEnabledRoute?.name // 框架路由重定向为第一个未禁用的路由
|
|
frameworkRoutes.push(route)
|
|
} else {
|
|
// 非系统路由,添加到路由列表,并处理子路由
|
|
for (const childPath in childrenModules) {
|
|
const [, routeName, childRouteName] = childPath.match(childrenModulesRegex) || []
|
|
|
|
// 非当前路由的子路由,跳过
|
|
if (routeName !== route.name) continue
|
|
// 获取路由中文标题
|
|
const metaName = routesSort.find((item) => item.name === childRouteName)
|
|
// 添加子路由配置
|
|
route.children.push({
|
|
path: kebabCase(childRouteName || ''),
|
|
name: kebabCase(childRouteName || ''),
|
|
meta: { title: metaName?.title || routeName },
|
|
component: childrenModules[childPath] as unknown as Promise<unknown>,
|
|
})
|
|
}
|
|
routes.push(route)
|
|
}
|
|
}
|
|
return { system: systemRoutes, framework: frameworkRoutes, routes }
|
|
}
|
|
|
|
/**
|
|
* 过滤系统路由
|
|
* @param {RouteRecordRaw[]} routes 路由配置
|
|
* @param {string[]} rolesName 允许的路由名称列表
|
|
* @returns {RouteRecordRaw[]} 过滤后的路由配置
|
|
*/
|
|
export function filterSystemRoutes(routes: RouteRecordRaw[], rolesName: string[]): RouteRecordRaw[] {
|
|
return routes.filter((route) => {
|
|
const routeName = route.name
|
|
return typeof routeName === 'string' && rolesName.includes(routeName)
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 排序路由
|
|
* @param {RouteRecordRaw[]} routes 路由配置
|
|
* @returns {RouteRecordRaw[]} 排序后的路由配置
|
|
*/
|
|
export function sortRoutes(routes: RouteRecordRaw[], rolesSort: { name: string; title: string }[]): RouteRecordRaw[] {
|
|
// 根据 rolesSort 顺序进行排序
|
|
return routes.sort((a, b) => {
|
|
const aIndex = rolesSort.findIndex((item) => item.name === a.name)
|
|
const bIndex = rolesSort.findIndex((item) => item.name === b.name)
|
|
return aIndex - bIndex
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 获取异步路由,基于框架路由和系统路由
|
|
* @param {string[]} frameworkRoutes 框架路由
|
|
* @param {string[]} systemRoutes 系统路由
|
|
* @param {RouteRecordRaw[]} routesSort 路由排序
|
|
* @returns {RouteRecordRaw[]} 异步路由配置
|
|
*/
|
|
export function getBuildRoutes(
|
|
mainRoute: Record<string, () => Promise<unknown>>,
|
|
childrenRoutes: Record<string, () => Promise<unknown>>,
|
|
routesOptions: RouteOptions,
|
|
): { routeGroup: RouteRecordRaw[]; routes: RouteRecordRaw[] } {
|
|
// 生成框架路由
|
|
const { framework, system, routes } = generateRoutes(mainRoute, childrenRoutes, routesOptions)
|
|
// 排序路由
|
|
const sortedRoutes = sortRoutes(routes, [...routesOptions.sort])
|
|
// 如果框架路由存在,则将排序后的路由添加到框架路由的子路由中
|
|
if (framework[0]) framework[0].children = [...sortedRoutes]
|
|
// 返回排序后的路由
|
|
return { routeGroup: [...framework, ...system], routes }
|
|
}
|
|
|
|
export default getBuildRoutes
|