This commit is contained in:
孟彦祖 2024-08-30 13:59:33 +08:00 committed by 玲娜贝er
parent b336d3612f
commit 73ab356269

View File

@ -94,145 +94,190 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
}; };
/** /**
* vben路由 * vben
* *
* todo
* @param menuList * @param menuList
* @param parentPath * @param parentPath
* @returns vben路由 * @returns vben
*/ */
function backMenuToVbenMenu( function backMenuToVbenMenu(
menuList: Menu[], menuList: Menu[],
parentPath = '', parentPath = '',
): RouteRecordStringComponent[] { ): RouteRecordStringComponent[] {
const resultList: RouteRecordStringComponent[] = []; const resultList: RouteRecordStringComponent[] = [];
menuList.forEach((menu) => { menuList.forEach((menu) => {
// 根目录为菜单形式 // 根目录处理
// 固定有一个children children为当前菜单 if (isRootMenu(menu)) {
if (menu.path === '/' && menu.children && menu.children.length === 1) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
menu.meta = menu.children[0]!.meta; menu.meta = menu.children[0]!.meta;
/**
* todo
*/
menu.path = '/root_menu';
menu.component = 'RootMenu'; menu.component = 'RootMenu';
} }
// 外链: http开头 & 组件为Layout || ParentView
// 正则判断是否为http://或者https://开头 // 外链处理
if ( if (isExternalLink(menu)) {
/^https?:\/\//.test(menu.path) &&
(menu.component === 'Layout' || menu.component === 'ParentView')
) {
menu.component = 'Link'; menu.component = 'Link';
} }
// 内嵌iframe 组件为InnerLink
if (menu.meta?.link && menu.component === 'InnerLink') { // 内嵌 iframe 处理
if (isIframe(menu)) {
menu.component = 'IFrameView'; menu.component = 'IFrameView';
} }
// path // 处理路径
if (parentPath) { menu.path = formatPath(menu.path, parentPath);
menu.path = `${parentPath}/${menu.path}`;
}
const vbenRoute: RouteRecordStringComponent = { const vbenRoute: RouteRecordStringComponent = createVbenRoute(menu);
component: menu.component,
meta: {
// 当前路由不在菜单显示 但是可以通过链接访问
// 不可访问的路由由后端控制隐藏(不返回对应路由)
hideInMenu: menu.hidden,
icon: menu.meta?.icon,
keepAlive: !menu.meta?.noCache,
title: menu.meta?.title,
},
name: menu.name,
path: menu.path,
};
/** // 处理组件类型
* handleComponentType(menu, vbenRoute);
*/
switch (menu.component) {
case 'Layout': {
vbenRoute.component = 'BasicLayout';
break;
}
/**
* iframe内嵌
*/
case 'IFrameView': {
vbenRoute.component = 'IFrameView';
if (vbenRoute.meta) {
vbenRoute.meta.iframeSrc = menu.meta.link;
}
/**
* vue的hash是带#
* aaa.com/#/bbb path会转换为 aaa/com/#/bbb
* aaa.com/?bbb=xxx
* #
*/
/**
* todo
*/
if (vbenRoute.path.includes('/#/')) {
vbenRoute.path = vbenRoute.path.replace('/#/', '');
}
if (vbenRoute.path.includes('#')) {
vbenRoute.path = vbenRoute.path.replace('#', '');
}
if (vbenRoute.path.includes('?') || vbenRoute.path.includes('&')) {
vbenRoute.path = vbenRoute.path.replace('?', '');
vbenRoute.path = vbenRoute.path.replace('&', '');
}
break;
}
/**
*
*/
case 'Link': {
if (vbenRoute.meta) {
vbenRoute.meta.link = menu.meta.link;
}
vbenRoute.component = 'BasicLayout';
break;
}
/**
*
*/
case 'RootMenu': {
if (vbenRoute.meta) {
vbenRoute.meta.hideChildrenInMenu = true;
}
vbenRoute.component = 'BasicLayout';
break;
}
/**
* layout BasicLayout
*/
case 'ParentView': {
vbenRoute.component = '';
break;
}
/**
* system/user/index /
*/
default: {
vbenRoute.component = `/${menu.component}`;
break;
}
}
// children处理 // 递归处理子路由
if (menu.children && menu.children.length > 0) { if (menu.children && menu.children.length > 0) {
vbenRoute.children = backMenuToVbenMenu(menu.children, menu.path); vbenRoute.children = backMenuToVbenMenu(menu.children, menu.path);
} }
resultList.push(vbenRoute); resultList.push(vbenRoute);
}); });
return resultList; return resultList;
} }
/**
*
* @param menu
*/
function isRootMenu(menu: Menu): boolean {
return menu.path === '/' && menu.children && menu.children.length === 1;
}
/**
*
* @param menu
*/
function isExternalLink(menu: Menu): boolean {
return (
/^https?:\/\//.test(menu.path) &&
(menu.component === 'Layout' || menu.component === 'ParentView')
);
}
/**
* iframe
* @param menu
*/
function isIframe(menu: Menu): boolean {
return !!menu.meta?.link && menu.component === 'InnerLink';
}
/**
*
* @param path
* @param parentPath
*/
function formatPath(path: string, parentPath: string): string {
// 如果父路径是根目录且当前路径不是根目录,避免多余的斜杠
if (parentPath === '/' && path !== '/') {
return `/${path}`;
}
// 如果当前路径是根目录,直接返回
if (path === '/') {
return parentPath ? `${parentPath}` : path;
}
// 处理其他正常情况
return parentPath ? `${parentPath}/${path}` : path;
}
/**
* vben
* @param menu
*/
function createVbenRoute(menu: Menu): RouteRecordStringComponent {
return {
component: menu.component,
meta: {
hideInMenu: menu.hidden,
icon: menu.meta?.icon,
keepAlive: !menu.meta?.noCache,
title: menu.meta?.title,
},
name: menu.name,
path: menu.path,
};
}
/**
*
* @param menu
* @param vbenRoute
*/
function handleComponentType(
menu: Menu,
vbenRoute: RouteRecordStringComponent,
) {
switch (menu.component) {
case 'Layout': {
vbenRoute.component = 'BasicLayout';
break;
}
/**
* iframe内嵌
*/
case 'IFrameView': {
vbenRoute.component = 'IFrameView';
handleIframePath(vbenRoute);
break;
}
/**
*
*/
case 'Link': {
vbenRoute.component = 'BasicLayout';
break;
}
/**
*
*/
case 'RootMenu': {
if (vbenRoute.meta) {
vbenRoute.meta.hideChildrenInMenu = true;
}
vbenRoute.component = 'BasicLayout';
break;
}
/**
* layout BasicLayout
*/
case 'ParentView': {
vbenRoute.component = '';
break;
}
/**
* system/user/index /
*/
default: {
vbenRoute.component = `/${menu.component}`;
}
}
}
/**
* iframe
* @param vbenRoute
*/
function handleIframePath(vbenRoute: RouteRecordStringComponent) {
if (vbenRoute.meta) {
vbenRoute.meta.iframeSrc = vbenRoute.meta.link;
const specialChars = ['#', '?', '&'];
specialChars.forEach((char) => {
if (vbenRoute.path.includes(char)) {
vbenRoute.path = vbenRoute.path.replace(char, '');
}
});
}
}
return await generateAccessible(preferences.app.accessMode, { return await generateAccessible(preferences.app.accessMode, {
...options, ...options,
fetchMenuListAsync: async () => { fetchMenuListAsync: async () => {
@ -240,6 +285,7 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
content: `${$t('common.loadingMenu')}...`, content: `${$t('common.loadingMenu')}...`,
duration: 1, duration: 1,
}); });
// 后台返回路由/菜单 // 后台返回路由/菜单
const backMenuList = await getAllMenusApi(); const backMenuList = await getAllMenusApi();
// 转换为vben能用的路由 // 转换为vben能用的路由
@ -247,6 +293,7 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
// 特别注意 这里要深拷贝 // 特别注意 这里要深拷贝
const menuList = [...cloneDeep(localMenuList), ...vbenMenuList]; const menuList = [...cloneDeep(localMenuList), ...vbenMenuList];
console.log('menuList', menuList); console.log('menuList', menuList);
return menuList; return menuList;
}, },
// 可以指定没有权限跳转403页面 // 可以指定没有权限跳转403页面