|
@@ -138,6 +138,7 @@ interface MenuAction {
|
|
|
menuOrder?: number; // 新增:用于菜单项排序
|
|
menuOrder?: number; // 新增:用于菜单项排序
|
|
|
orderNum?: number; // 新增:用于存储菜单的原始排序号
|
|
orderNum?: number; // 新增:用于存储菜单的原始排序号
|
|
|
logoUrl?: string; // 新增:用于存储随机logo图片路径
|
|
logoUrl?: string; // 新增:用于存储随机logo图片路径
|
|
|
|
|
+ isExternal?: boolean; // 是否外链
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 菜单模块配置
|
|
// 菜单模块配置
|
|
@@ -320,23 +321,30 @@ const flattenMenus = (menus: any[], parentChain: string[] = [], parentPath = '',
|
|
|
console.log('工作流菜单父路径:', parentPath);
|
|
console.log('工作流菜单父路径:', parentPath);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 构建完整路径 - 移到外层,确保在递归调用中也能访问
|
|
|
|
|
- let fullPath = menu.path;
|
|
|
|
|
|
|
+ // 识别外链菜单
|
|
|
|
|
+ const rawLink = menu.meta?.link || menu.path;
|
|
|
|
|
+ const isExternalLink = typeof rawLink === 'string' && /^https?:\/\//i.test(rawLink);
|
|
|
|
|
|
|
|
- // 如果当前路径不是以 '/' 开头,需要拼接父路径
|
|
|
|
|
- if (!menu.path.startsWith('/')) {
|
|
|
|
|
- if (parentPath) {
|
|
|
|
|
- // 确保父路径以 '/' 开头
|
|
|
|
|
- const normalizedParentPath = parentPath.startsWith('/') ? parentPath : '/' + parentPath;
|
|
|
|
|
- fullPath = normalizedParentPath + '/' + menu.path;
|
|
|
|
|
- } else {
|
|
|
|
|
- // 如果没有父路径但不是绝对路径,添加 '/' 前缀
|
|
|
|
|
- fullPath = '/' + menu.path;
|
|
|
|
|
|
|
+ // 构建完整路径 - 外链直接使用原始链接,内部路由按层级拼接
|
|
|
|
|
+ let fullPath = menu.path;
|
|
|
|
|
+ if (isExternalLink) {
|
|
|
|
|
+ fullPath = rawLink;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果当前路径不是以 '/' 开头,需要拼接父路径
|
|
|
|
|
+ if (!menu.path.startsWith('/')) {
|
|
|
|
|
+ if (parentPath) {
|
|
|
|
|
+ // 确保父路径以 '/' 开头
|
|
|
|
|
+ const normalizedParentPath = parentPath.startsWith('/') ? parentPath : '/' + parentPath;
|
|
|
|
|
+ fullPath = normalizedParentPath + '/' + menu.path;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果没有父路径但不是绝对路径,添加 '/' 前缀
|
|
|
|
|
+ fullPath = '/' + menu.path;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- // 清理路径中的双斜杠
|
|
|
|
|
- fullPath = fullPath.replace(/\/+/g, '/');
|
|
|
|
|
|
|
+ // 清理路径中的双斜杠
|
|
|
|
|
+ fullPath = fullPath.replace(/\/+/g, '/');
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 处理有meta信息且有标题的菜单项
|
|
// 处理有meta信息且有标题的菜单项
|
|
|
if (menu.meta && menu.meta.title) {
|
|
if (menu.meta && menu.meta.title) {
|
|
@@ -381,10 +389,11 @@ const flattenMenus = (menus: any[], parentChain: string[] = [], parentPath = '',
|
|
|
// 2. 组件为Vue对象且没有子菜单(可能是目录)
|
|
// 2. 组件为Vue对象且没有子菜单(可能是目录)
|
|
|
// 3. menuType为'M'(目录类型)
|
|
// 3. menuType为'M'(目录类型)
|
|
|
const isDirectoryMenu =
|
|
const isDirectoryMenu =
|
|
|
- menu.component === 'Layout' ||
|
|
|
|
|
- menu.component === 'ParentView' ||
|
|
|
|
|
- (typeof menu.component === 'object' && !hasVisibleChildren) ||
|
|
|
|
|
- menu.menuType === 'M';
|
|
|
|
|
|
|
+ !isExternalLink &&
|
|
|
|
|
+ (menu.component === 'Layout' ||
|
|
|
|
|
+ menu.component === 'ParentView' ||
|
|
|
|
|
+ (typeof menu.component === 'object' && !hasVisibleChildren) ||
|
|
|
|
|
+ menu.menuType === 'M');
|
|
|
|
|
|
|
|
// 添加工作流菜单的详细调试信息
|
|
// 添加工作流菜单的详细调试信息
|
|
|
if (menu.meta?.title === '工作流' || menu.name === 'Workflow11616') {
|
|
if (menu.meta?.title === '工作流' || menu.name === 'Workflow11616') {
|
|
@@ -410,7 +419,7 @@ const flattenMenus = (menus: any[], parentChain: string[] = [], parentPath = '',
|
|
|
// 不创建菜单项,直接跳过
|
|
// 不创建菜单项,直接跳过
|
|
|
}
|
|
}
|
|
|
// 只有叶子节点(没有子菜单或子菜单都是隐藏的)且不是目录菜单才作为可点击的菜单项
|
|
// 只有叶子节点(没有子菜单或子菜单都是隐藏的)且不是目录菜单才作为可点击的菜单项
|
|
|
- else if (!hasVisibleChildren && !isDirectoryMenu && fullPath && fullPath !== '/') {
|
|
|
|
|
|
|
+ else if ((!hasVisibleChildren && !isDirectoryMenu && fullPath && fullPath !== '/') || (isExternalLink && fullPath)) {
|
|
|
const menuAction: MenuAction = {
|
|
const menuAction: MenuAction = {
|
|
|
id: `menu-${menu.name || fullPath}`,
|
|
id: `menu-${menu.name || fullPath}`,
|
|
|
title: menu.meta.title,
|
|
title: menu.meta.title,
|
|
@@ -427,7 +436,8 @@ const flattenMenus = (menus: any[], parentChain: string[] = [], parentPath = '',
|
|
|
moduleOrder: moduleOrder, // 添加模块顺序
|
|
moduleOrder: moduleOrder, // 添加模块顺序
|
|
|
menuOrder: menuIndex, // 添加菜单在当前层级的顺序
|
|
menuOrder: menuIndex, // 添加菜单在当前层级的顺序
|
|
|
orderNum: menu.orderNum || 0, // 添加菜单的原始排序号
|
|
orderNum: menu.orderNum || 0, // 添加菜单的原始排序号
|
|
|
- logoUrl: getIconPath(iconKey) // 根据icon名称获取对应图标
|
|
|
|
|
|
|
+ logoUrl: getIconPath(iconKey), // 根据icon名称获取对应图标
|
|
|
|
|
+ isExternal: isExternalLink
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 添加调试日志来验证路径构建和排序
|
|
// 添加调试日志来验证路径构建和排序
|
|
@@ -574,6 +584,13 @@ const handleQuickAction = (action: any) => {
|
|
|
|
|
|
|
|
console.log('action', action);
|
|
console.log('action', action);
|
|
|
|
|
|
|
|
|
|
+ // 外链菜单:在新标签页直接打开原始地址,不拼接
|
|
|
|
|
+ if (action.isExternal) {
|
|
|
|
|
+ window.open(action.route, '_blank');
|
|
|
|
|
+ ElMessage.success(`正在打开${action.title}...`);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
// 使用路由跳转,系统会自动在tab页中打开
|
|
// 使用路由跳转,系统会自动在tab页中打开
|
|
|
router
|
|
router
|