From 40da33a81eb148e5f3c0e364538c3e9429cdb3ba Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 8 Jan 2026 14:51:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E7=A7=BB=E9=99=A4=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Robot/Web/src/DockLayout/DockLayout.vue | 159 +++++++++++++----- 1 file changed, 113 insertions(+), 46 deletions(-) diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue index ed0a812..a4ab497 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue @@ -262,48 +262,78 @@ const onPanelClose = (event) => { const areaId = event.areaId; const panelId = event.panelId; - if (shouldOperateAreaInsteadOfPanel(areaId)) { - onCloseFloatingArea({ areaId }); - } else { - panelActions.close(panelId, areaId); - const area = floatingAreas.value.find(a => a.id === areaId); - if (area && area.children) { - for (const child of area.children) { - if (child.type === 'TabPage' && child.children) { - // 处理TabPage的children,可能是单个Panel或Panel数组 - const isArray = Array.isArray(child.children); - const childrenArray = isArray ? child.children : [child.children]; - - // 检查每个子项是否为Panel组件 - for (let i = 0; i < childrenArray.length; i++) { - const item = childrenArray[i]; - if (item.type === 'Panel' && item.id === panelId) { - // 从数组中移除Panel - if (isArray) { - child.children.splice(i, 1); - } else { - // 如果是单个Panel,移除整个TabPage - const tabPageIndex = area.children.indexOf(child); - if (tabPageIndex !== -1) { - area.children.splice(tabPageIndex, 1); - } - break; - } - - // 如果Panel数组为空,移除TabPage - if (child.children.length === 0) { - const tabPageIndex = area.children.indexOf(child); - if (tabPageIndex !== -1) { + // 始终只关闭面板,不关闭整个Area,除非没有剩余面板 + panelActions.close(panelId, areaId); + const area = floatingAreas.value.find(a => a.id === areaId); + if (area && area.children) { + const areaChildrenArray = Array.isArray(area.children) ? area.children : [area.children]; + for (const child of areaChildrenArray) { + if (child.type === 'TabPage' && child.children) { + // 处理TabPage的children,可能是单个Panel或Panel数组 + const isArray = Array.isArray(child.children); + const childrenArray = isArray ? child.children : [child.children]; + + // 检查每个子项是否为Panel组件 + for (let i = 0; i < childrenArray.length; i++) { + const item = childrenArray[i]; + if (item.type === 'Panel' && item.id === panelId) { + // 从数组中移除Panel + if (isArray) { + child.children.splice(i, 1); + } else { + // 如果是单个Panel,移除整个TabPage + const tabPageIndex = areaChildrenArray.indexOf(child); + if (tabPageIndex !== -1) { + if (Array.isArray(area.children)) { area.children.splice(tabPageIndex, 1); + } else { + // 如果area.children是单个对象,直接设为null + area.children = null; } } break; } + + // 如果Panel数组为空,移除TabPage + if (Array.isArray(child.children) && child.children.length === 0) { + const tabPageIndex = areaChildrenArray.indexOf(child); + if (tabPageIndex !== -1) { + if (Array.isArray(area.children)) { + area.children.splice(tabPageIndex, 1); + } else { + // 如果area.children是单个对象,直接设为null + area.children = null; + } + } + } + break; } + } + break; + } + } + } + + // 检查Area是否还有子元素,如果没有,关闭整个Area + if (area && area.children) { + let hasChildren = false; + const areaChildrenArray = Array.isArray(area.children) ? area.children : [area.children]; + for (const child of areaChildrenArray) { + if (child.type === 'TabPage' && child.children) { + const tabChildrenArray = Array.isArray(child.children) ? child.children : [child.children]; + if (tabChildrenArray.length > 0) { + hasChildren = true; break; } } } + + if (!hasChildren) { + onCloseFloatingArea({ areaId }); + } + } else { + // Area没有children,直接关闭 + onCloseFloatingArea({ areaId }); } }; @@ -492,39 +522,76 @@ const onTabClose = async (data) => { console.log(`✅ 找到目标Area和TabPage:`, { areaId, tabPageId, panelId }); - // 2. 调用TabPageActions处理关闭请求 + // 2. 调用PanelHandler的close方法回收Panel资源 + panelActions.close(panelId, areaId); + console.log(`📌 调用PanelHandler回收Panel资源`); + + // 3. 调用TabPageActions处理关闭请求 await tabPageActions.requestClose(tabPageId, areaId); - // 3. 移除Panel + // 4. 移除Panel if (Array.isArray(targetTabPage.children)) { targetTabPage.children.splice(panelIndex, 1); console.log(`📌 从TabPage移除Panel后,剩余Panel数量: ${targetTabPage.children.length}`); } else { + // 当TabPage只有一个Panel时,我们将children设置为null + // 这样shouldShowTabs计算属性会返回false,不显示标签栏 + // 但TabPage仍然存在 targetTabPage.children = null; - console.log(`📌 移除了唯一的Panel`); + console.log(`📌 移除了唯一的Panel,TabPage不显示标签栏`); } - // 4. 如果TabPage没有子元素了,移除整个TabPage - if (!targetTabPage.children || (Array.isArray(targetTabPage.children) && targetTabPage.children.length === 0)) { - // 从Area的children中移除TabPage - targetArea.children = null; + // 5. 检查TabPage是否还有子元素 + // 当targetTabPage.children为null时,TabPage仍然存在,只是不显示标签栏 + // 只有当children为undefined或空数组时,才认为TabPage没有子元素 + let hasTabPageChildren = true; + if (Array.isArray(targetTabPage.children)) { + hasTabPageChildren = targetTabPage.children.length > 0; + } else if (targetTabPage.children === undefined) { + hasTabPageChildren = false; + } + + // 6. 只有当TabPage没有任何子元素时,才移除TabPage + if (!hasTabPageChildren) { console.log(`📌 TabPage已无Panel,移除TabPage`); + + // 7. 实际从Area的children中移除TabPage + if (Array.isArray(targetArea.children)) { + const tabPageIndex = targetArea.children.indexOf(targetTabPage); + if (tabPageIndex !== -1) { + targetArea.children.splice(tabPageIndex, 1); + } + } else { + // 如果Area的children是单个TabPage,直接设为null + targetArea.children = null; + } + + // 8. 检查Area是否还有子元素 + let hasAreaChildren = false; + if (Array.isArray(targetArea.children)) { + hasAreaChildren = targetArea.children.length > 0; + } else { + hasAreaChildren = !!targetArea.children; + } + + // 9. 只有当Area没有任何子元素时,才关闭整个Area + if (!hasAreaChildren) { + console.log(`📌 Area已无子元素,关闭整个Area`); + onCloseFloatingArea({ areaId }); + return; + } } - // 5. 更新floatingAreas中的Area配置 + // 10. 更新floatingAreas中的Area配置 const areaIndex = floatingAreas.value.findIndex(a => a.id === areaId); if (areaIndex !== -1) { floatingAreas.value[areaIndex] = { ...targetArea }; console.log(`📌 更新floatingAreas中的Area配置`); - // 6. 触发Area更新事件,确保状态同步 + // 11. 触发Area更新事件,确保状态同步 areaActions.updateState(areaId, { children: targetArea.children }); console.log(`📌 触发Area更新事件`); - // 7. 调用PanelHandler的close方法回收Panel资源 - panelActions.close(panelId, areaId); - console.log(`📌 调用PanelHandler回收Panel资源`); - console.log(`✅ 成功移除标签页和回收Panel: areaId=${areaId}, panelId=${panelId}`); } } catch (error) { @@ -642,7 +709,7 @@ const setupEventListeners = () => { // Panel相关事件 unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.PANEL_TOGGLE_COLLAPSE, () => emit('toggleCollapse'), { componentId: 'dock-layout' })); unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.PANEL_MAXIMIZE, onMaximize, { componentId: 'dock-layout' })); - unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.PANEL_CLOSE_REQUEST, onCloseFloatingArea, { componentId: 'dock-layout' })); + unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.PANEL_CLOSE_REQUEST, onPanelClose, { componentId: 'dock-layout' })); unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.PANEL_CLOSE, onPanelClose, { componentId: 'dock-layout' })); unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.PANEL_TOGGLE_TOOLBAR, () => emit('toggleToolbar'), { componentId: 'dock-layout' })); unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.PANEL_MAXIMIZE_SYNC, onPanelMaximizeSync, { componentId: 'dock-layout' }));