fix(project): split product detail module and restore detail route

This commit is contained in:
2026-02-22 10:12:38 +08:00
parent 99a947cad4
commit d6e5138e53
8 changed files with 1100 additions and 814 deletions

View File

@@ -1,6 +1,7 @@
import type {
ComponentRecordType,
GenerateMenuAndRoutesOptions,
RouteRecordStringComponent,
} from '@vben/types';
import { generateAccessible } from '@vben/access';
@@ -14,6 +15,11 @@ import { $t } from '#/locales';
const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');
const PRODUCT_PATH = '/product';
const PRODUCT_DETAIL_PATH = '/product/detail';
const PRODUCT_DETAIL_NAME = 'ProductDetail';
const PRODUCT_LIST_PATH = '/product/list';
async function generateAccess(options: GenerateMenuAndRoutesOptions) {
const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');
@@ -29,7 +35,8 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
content: `${$t('common.loadingMenu')}...`,
duration: 1.5,
});
return await getAllMenusApi();
const menuList = await getAllMenusApi();
return ensureProductDetailRoute(menuList);
},
// 可以指定没有权限跳转403页面
forbiddenComponent,
@@ -39,4 +46,93 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
});
}
function ensureProductDetailRoute(
routes: RouteRecordStringComponent[],
): RouteRecordStringComponent[] {
const clonedRoutes = cloneMenuRoutes(routes);
if (containsRoute(clonedRoutes, PRODUCT_DETAIL_PATH, PRODUCT_DETAIL_NAME)) {
return clonedRoutes;
}
const productRoute = findProductRoute(clonedRoutes);
if (!productRoute) {
return clonedRoutes;
}
const productChildren = [...(productRoute.children ?? [])];
const listMeta = productChildren.find(
(item) => String(item.path || '').trim() === PRODUCT_LIST_PATH,
)?.meta;
productChildren.push({
name: PRODUCT_DETAIL_NAME,
path: PRODUCT_DETAIL_PATH,
component: '/views/product/detail/index.vue',
meta: {
...(listMeta ?? {}),
title: '商品详情',
hideInMenu: true,
},
});
productRoute.children = productChildren;
return clonedRoutes;
}
function cloneMenuRoutes(
routes: RouteRecordStringComponent[],
): RouteRecordStringComponent[] {
return routes.map((route) => ({
...route,
meta: route.meta ? { ...route.meta } : route.meta,
children: route.children ? cloneMenuRoutes(route.children) : undefined,
}));
}
function containsRoute(
routes: RouteRecordStringComponent[],
path: string,
name: string,
): boolean {
for (const route of routes) {
const routePath = String(route.path || '').trim();
const routeName = String(route.name || '').trim();
if (routePath === path || routeName === name) {
return true;
}
if (route.children && containsRoute(route.children, path, name)) {
return true;
}
}
return false;
}
function findProductRoute(
routes: RouteRecordStringComponent[],
): null | RouteRecordStringComponent {
for (const route of routes) {
const routePath = String(route.path || '').trim();
const routeName = String(route.name || '').trim();
const hasProductListChild = (route.children ?? []).some(
(item) => String(item.path || '').trim() === PRODUCT_LIST_PATH,
);
if (
routePath === PRODUCT_PATH ||
routeName === 'Product' ||
hasProductListChild
) {
return route;
}
if (route.children) {
const nestedMatch = findProductRoute(route.children);
if (nestedMatch) {
return nestedMatch;
}
}
}
return null;
}
export { generateAccess };