diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue index e89fc76..6cc6ccc 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue @@ -446,7 +446,83 @@ const onTabChange = async (data) => { const onTabClose = async (data) => { try { - await tabPageActions.requestClose(data.tabPageId, data.areaId); + // 适配数据结构:从data.id获取Panel ID + const panelId = data.id; + if (!panelId) { + console.error('Tab close event missing panelId'); + return; + } + + console.log(`📋 处理标签页关闭事件:`, { data, panelId }); + + // 1. 查找包含该Panel的Area + let targetArea = null; + let targetTabPage = null; + let panelIndex = -1; + let areaId = null; + + for (const area of floatingAreas.value) { + if (area.children && area.children.type === 'TabPage') { + const tabPage = area.children; + if (tabPage.children) { + const childrenArray = Array.isArray(tabPage.children) ? tabPage.children : [tabPage.children]; + const index = childrenArray.findIndex(child => child.id === panelId); + + if (index !== -1) { + targetArea = area; + targetTabPage = tabPage; + panelIndex = index; + areaId = area.id; + break; + } + } + } + } + + if (!targetArea || !targetTabPage || !areaId) { + console.error(`❌ 找不到包含Panel ${panelId}的Area`); + return; + } + + const tabPageId = targetTabPage.id || `tabPage-${areaId}`; + + console.log(`✅ 找到目标Area和TabPage:`, { areaId, tabPageId, panelId }); + + // 2. 调用TabPageActions处理关闭请求 + await tabPageActions.requestClose(tabPageId, areaId); + + // 3. 移除Panel + if (Array.isArray(targetTabPage.children)) { + targetTabPage.children.splice(panelIndex, 1); + console.log(`📌 从TabPage移除Panel后,剩余Panel数量: ${targetTabPage.children.length}`); + } else { + targetTabPage.children = null; + console.log(`📌 移除了唯一的Panel`); + } + + // 4. 如果TabPage没有子元素了,移除整个TabPage + if (!targetTabPage.children || (Array.isArray(targetTabPage.children) && targetTabPage.children.length === 0)) { + // 从Area的children中移除TabPage + targetArea.children = null; + console.log(`📌 TabPage已无Panel,移除TabPage`); + } + + // 5. 更新floatingAreas中的Area配置 + const areaIndex = floatingAreas.value.findIndex(a => a.id === areaId); + if (areaIndex !== -1) { + floatingAreas.value[areaIndex] = { ...targetArea }; + console.log(`📌 更新floatingAreas中的Area配置`); + + // 6. 触发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) { console.error('Failed to handle tab close:', error); } diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/handlers/PanelHandler.js b/AutoRobot/Windows/Robot/Web/src/DockLayout/handlers/PanelHandler.js index 7dc3a06..e8963ae 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/handlers/PanelHandler.js +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/handlers/PanelHandler.js @@ -182,22 +182,36 @@ class PanelEventHandler { }); } + /** + * 关闭Panel + */ + async close(panelId, areaId, options = {}) { + const { priority = 1 } = options + + console.log(`[PanelHandler] 关闭Panel: ${panelId}, areaId: ${areaId}`) + + // 执行关闭操作 + return this._executeClose(panelId, areaId) + } + /** * 执行Panel关闭 */ - async _executeClose(panelId) { - console.log(`[PanelHandler] 执行Panel关闭: ${panelId}`) + async _executeClose(panelId, areaId) { + console.log(`[PanelHandler] 执行Panel关闭: ${panelId}, areaId: ${areaId}`) // 更新状态 const panelState = this.panelStates.get(panelId) if (panelState) { panelState.closed = true panelState.closedAt = Date.now() + panelState.areaId = areaId } // 触发关闭事件 await emitEvent(PANEL_EVENT_TYPES.CLOSE, { panelId, + areaId, source: 'PanelHandler', timestamp: Date.now() }) @@ -206,6 +220,7 @@ class PanelEventHandler { setTimeout(() => { emitEvent(PANEL_EVENT_TYPES.CLOSED, { panelId, + areaId, source: 'PanelHandler', timestamp: Date.now() }) @@ -838,6 +853,7 @@ export const panelActions = { toggleCollapse: (panelId, options) => panelHandler.toggleCollapse(panelId, options), maximize: (panelId, options) => panelHandler.maximize(panelId, options), restore: (panelId, options) => panelHandler.restore(panelId, options), + close: (panelId, areaId, options) => panelHandler.close(panelId, areaId, options), requestClose: (panelId, options) => panelHandler.requestClose(panelId, options), toggleToolbar: (panelId, options) => panelHandler.toggleToolbar(panelId, options),