fix: 修复路由重复 (#7590)
* fix: 修复路由重复 优化mixed模式路由合并逻辑。以backend 为基础,并从frontend补充 * fix: 修复名称冲突时子项合并顺序/覆盖(后端子项可能会丢失)。 * fix: 优化可访问性判断逻辑 * fix: error Forbidden non-null assertion * refactor(access): 调整可访问性判断逻辑pull/336/head
parent
a4736a49f8
commit
83a0c9662d
|
|
@ -25,6 +25,7 @@ async function generateAccessible(
|
||||||
const { router } = options;
|
const { router } = options;
|
||||||
|
|
||||||
options.routes = cloneDeep(options.routes);
|
options.routes = cloneDeep(options.routes);
|
||||||
|
|
||||||
// 生成路由
|
// 生成路由
|
||||||
const accessibleRoutes = await generateRoutes(mode, options);
|
const accessibleRoutes = await generateRoutes(mode, options);
|
||||||
|
|
||||||
|
|
@ -101,8 +102,10 @@ async function generateRoutes(
|
||||||
generateRoutesByFrontend(routes, roles || [], forbiddenComponent),
|
generateRoutesByFrontend(routes, roles || [], forbiddenComponent),
|
||||||
generateRoutesByBackend(options),
|
generateRoutesByBackend(options),
|
||||||
]);
|
]);
|
||||||
|
resultRoutes = mergeRoutesByName(
|
||||||
resultRoutes = [...frontend_resultRoutes, ...backend_resultRoutes];
|
backend_resultRoutes,
|
||||||
|
frontend_resultRoutes,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,4 +156,60 @@ async function generateRoutes(
|
||||||
return resultRoutes;
|
return resultRoutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 name 合并前后端路由
|
||||||
|
* @param baseRoutes 后端路由
|
||||||
|
* @param extraRoutes 前端路由
|
||||||
|
*/
|
||||||
|
function mergeRoutesByName(
|
||||||
|
baseRoutes: RouteRecordRaw[],
|
||||||
|
extraRoutes: RouteRecordRaw[],
|
||||||
|
): RouteRecordRaw[] {
|
||||||
|
const result: RouteRecordRaw[] = [];
|
||||||
|
const routeMap = new Map<string, RouteRecordRaw>();
|
||||||
|
|
||||||
|
for (const route of baseRoutes) {
|
||||||
|
const clone = { ...route } as RouteRecordRaw;
|
||||||
|
result.push(clone);
|
||||||
|
if (clone.name && isString(clone.name)) {
|
||||||
|
routeMap.set(clone.name as string, clone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const route of extraRoutes) {
|
||||||
|
if (
|
||||||
|
route.name &&
|
||||||
|
isString(route.name) &&
|
||||||
|
routeMap.has(route.name as string)
|
||||||
|
) {
|
||||||
|
const existing = routeMap.get(route.name as string)!;
|
||||||
|
const existingChildren = existing.children ?? [];
|
||||||
|
const routeChildren = route.children ?? [];
|
||||||
|
|
||||||
|
const merged = {
|
||||||
|
...route,
|
||||||
|
...existing, // keep backend as base
|
||||||
|
meta: {
|
||||||
|
...route.meta,
|
||||||
|
...existing.meta, // backend meta wins on conflicts
|
||||||
|
},
|
||||||
|
} as RouteRecordRaw;
|
||||||
|
|
||||||
|
if (existingChildren.length > 0 || routeChildren.length > 0) {
|
||||||
|
merged.children = mergeRoutesByName(existingChildren, routeChildren);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(existing, merged);
|
||||||
|
} else {
|
||||||
|
const clone = { ...route } as RouteRecordRaw;
|
||||||
|
result.push(clone);
|
||||||
|
if (clone.name && isString(clone.name)) {
|
||||||
|
routeMap.set(clone.name as string, clone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export { generateAccessible };
|
export { generateAccessible };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue