From 68b8feffc1880f063737ad8ba035c3d8a81d9752 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Fri, 12 Dec 2025 16:04:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E9=A6=96=E9=A1=B5=E4=B8=AD=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=A4=96=E9=93=BE=E8=8F=9C=E5=8D=95,=E9=80=82?= =?UTF-8?q?=E9=85=8D=E8=B6=85=E6=98=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/views/index.vue | 57 ++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/web/src/views/index.vue b/web/src/views/index.vue index bf4d18c9..ce8242bf 100644 --- a/web/src/views/index.vue +++ b/web/src/views/index.vue @@ -138,6 +138,7 @@ interface MenuAction { menuOrder?: number; // 新增:用于菜单项排序 orderNum?: number; // 新增:用于存储菜单的原始排序号 logoUrl?: string; // 新增:用于存储随机logo图片路径 + isExternal?: boolean; // 是否外链 } // 菜单模块配置 @@ -320,23 +321,30 @@ const flattenMenus = (menus: any[], parentChain: string[] = [], parentPath = '', console.log('工作流菜单父路径:', parentPath); } - // 构建完整路径 - 移到外层,确保在递归调用中也能访问 + // 识别外链菜单 + const rawLink = menu.meta?.link || menu.path; + const isExternalLink = typeof rawLink === 'string' && /^https?:\/\//i.test(rawLink); + + // 构建完整路径 - 外链直接使用原始链接,内部路由按层级拼接 let fullPath = menu.path; - - // 如果当前路径不是以 '/' 开头,需要拼接父路径 - if (!menu.path.startsWith('/')) { - if (parentPath) { - // 确保父路径以 '/' 开头 - const normalizedParentPath = parentPath.startsWith('/') ? parentPath : '/' + parentPath; - fullPath = normalizedParentPath + '/' + menu.path; - } else { - // 如果没有父路径但不是绝对路径,添加 '/' 前缀 - 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信息且有标题的菜单项 if (menu.meta && menu.meta.title) { @@ -381,10 +389,11 @@ const flattenMenus = (menus: any[], parentChain: string[] = [], parentPath = '', // 2. 组件为Vue对象且没有子菜单(可能是目录) // 3. menuType为'M'(目录类型) 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') { @@ -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 = { id: `menu-${menu.name || fullPath}`, title: menu.meta.title, @@ -427,7 +436,8 @@ const flattenMenus = (menus: any[], parentChain: string[] = [], parentPath = '', moduleOrder: moduleOrder, // 添加模块顺序 menuOrder: menuIndex, // 添加菜单在当前层级的顺序 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); + // 外链菜单:在新标签页直接打开原始地址,不拼接 + if (action.isExternal) { + window.open(action.route, '_blank'); + ElMessage.success(`正在打开${action.title}...`); + return; + } + try { // 使用路由跳转,系统会自动在tab页中打开 router