import type { Router } from 'vue-router';
import type { FlatMenuItem } from '@core/stores/menu';
/**
* 根据路径约定推断页面组件。
*
* 约定规则(纯前端约定,无需后端改造):
* - /create、/new、/add 结尾 → form.vue(新建表单)
* - /edit/:id、/update/:id → form.vue(编辑表单)
* - 其余路径 → index.vue(列表页)
*/
function resolvePageComponent(path: string) {
if (/\/(create|new|add)$/.test(path) || /\/(edit|update)(\/|$)/.test(path)) {
return () => import('@core/views/form.vue');
}
return () => import('@core/views/index.vue');
}
/**
* 将菜单叶子节点批量注册为动态路由。
*
* 优先级说明:
* - 已存在路径(应用级预注册)不会被覆盖
* - 每个菜单叶子节点默认使用框架 index.vue / form.vue
*
* @param router Vue Router 实例
* @param menus 已拍平的菜单列表(来自 menuStore.flatMenus)
*/
export function registerMenuRoutes(router: Router, menus: FlatMenuItem[]): void {
// 获取已注册路径,保护应用级预注册路由
const existingPaths = new Set(router.getRoutes().map((r) => r.path));
// 筛选叶子节点:没有其他 menu 以其 id 为 parentId 的即为叶子
const parentIds = new Set(menus.map((m) => m.parentId).filter(Boolean));
const leafMenus = menus.filter((m) => !parentIds.has(m.id) && m.path);
for (const menu of leafMenus) {
if (existingPaths.has(menu.path)) continue; // 应用级路由优先,跳过
router.addRoute({
path: menu.path,
name: `menu-${menu.name || menu.id}`,
component: resolvePageComponent(menu.path),
meta: {
auth: true,
menuId: menu.id,
title: menu.title ?? menu.name,
},
});
}
}
|