From dd421b5d1e6ca5292b4bed42a4f6ef3f7d6e445b Mon Sep 17 00:00:00 2001 From: zqm Date: Thu, 15 Jan 2026 14:28:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug,=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Windows/Robot/Web/src/DockLayout/Area.vue | 2 +- .../Robot/Web/src/DockLayout/DockLayout.vue | 68 ++++++++++++++- .../Robot/Web/src/DockLayout/eventBus.js | 7 ++ .../src/DockLayout/handlers/PanelHandler.js | 82 ++++++++----------- 4 files changed, 108 insertions(+), 51 deletions(-) diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue index 51f62dd..4176d35 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue @@ -764,7 +764,7 @@ const onToggleMaximize = () => { }) } -const onClose = () => emitEvent(EVENT_TYPES.PANEL_CLOSE_REQUEST, { +const onClose = () => emitEvent(EVENT_TYPES.AREA_CLOSE_REQUEST, { areaId: props.id }, { source: { component: 'Area', areaId: props.id } diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue index eca5bcf..3e04b07 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue @@ -58,7 +58,7 @@ import DockIndicator from './DockIndicator.vue'; import ResizeBar from './ResizeBar.vue'; import Render from './Render.vue'; import { zIndexManager } from './dockLayers'; -import { eventBus, EVENT_TYPES } from './eventBus'; +import { eventBus, EVENT_TYPES, emitEvent } from './eventBus'; import { areaActions } from './handlers/AreaHandler'; import { dragStateActions } from './handlers/DragStateManager'; import { panelActions } from './handlers/PanelHandler'; @@ -349,6 +349,71 @@ const onPanelClose = (event) => { } }; +// 处理Area关闭请求事件 +const onAreaCloseRequest = (event) => { + const { areaId } = event; + + // 查找要关闭的Area + const areaIndex = floatingAreas.value.findIndex(a => a.id === areaId); + if (areaIndex === -1) { + console.error(`❌ 找不到要关闭的Area: ${areaId}`); + return; + } + + const area = floatingAreas.value[areaIndex]; + + // 1. 处理Area下的所有子组件 + if (area.children) { + const areaChildrenArray = Array.isArray(area.children) ? area.children : [area.children]; + + areaChildrenArray.forEach((child, childIndex) => { + if (child.type === 'TabPage') { + // 2. 处理TabPage下的所有Panel + if (child.children) { + const tabChildrenArray = Array.isArray(child.children) ? child.children : [child.children]; + + // 3. 遍历并关闭每个Panel + tabChildrenArray.forEach(panel => { + if (panel.type === 'Panel' && panel.id) { + try { + // 4. 关闭Panel资源(异步执行) + panelActions.close(panel.id, areaId); + // 注意:panelActions.close内部已经会发送PANEL_CLOSED事件,不需要手动发送 + } catch (error) { + console.error(`❌ 关闭Panel ${panel.id}失败:`, error); + // 继续处理下一个Panel,避免单个Panel关闭失败导致整个流程中断 + } + } + }); + + // 6. 清理TabPage的children引用 + child.children = []; + } + + // 7. 从Area中移除TabPage + if (Array.isArray(area.children)) { + area.children.splice(childIndex, 1); + } else { + area.children = null; + } + } + }); + } + + // 8. 关闭Area资源(此时Area的children已清空) + areaActions.closeFloating(areaId); + + // 9. 从floatingAreas中移除Area + floatingAreas.value.splice(areaIndex, 1); + + // 10. 发送Area关闭事件 + emitEvent(EVENT_TYPES.AREA_CLOSED, { + areaId: areaId + }); + + console.log(`✅ 成功关闭Area及其所有子组件: ${areaId}`); +}; + // 简单的拖拽事件处理 const handleMainAreaDragOver = (event) => { event.preventDefault(); @@ -726,6 +791,7 @@ const setupEventListeners = () => { unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_DRAG_LEAVE, handleAreaDragLeave, { componentId: 'dock-layout' })); unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_MERGE_REQUEST, handleAreaMergeRequest, { componentId: 'dock-layout' })); unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_UPDATED, onAreaUpdated, { componentId: 'dock-layout' })); + unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_CLOSE_REQUEST, onAreaCloseRequest, { componentId: 'dock-layout' })); diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/eventBus.js b/AutoRobot/Windows/Robot/Web/src/DockLayout/eventBus.js index a27ac8d..fa285c5 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/eventBus.js +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/eventBus.js @@ -102,6 +102,8 @@ export const EVENT_TYPES = { AREA_DESTROYED: 'area.destroyed', AREA_UPDATED: 'area.updated', AREA_ERROR: 'area.error', + AREA_CLOSED: 'area.closed', + AREA_CLOSE_REQUEST: 'area.close.request', // 浮动区域管理 AREA_FLOATING_CREATE: 'area.floating.create', @@ -145,6 +147,9 @@ export const EVENT_TYPES = { PANEL_MAXIMIZE_SYNC: 'panel.maximize.sync', PANEL_MAXIMIZE: 'panel.maximize', + PANEL_COLLAPSE: 'panel.collapse', + PANEL_EXPAND: 'panel.expand', + PANEL_RESTORE: 'panel.restore', PANEL_CLOSE: 'panel.close', PANEL_CLOSE_REQUEST: 'panel.close.request', PANEL_CLOSED: 'panel.closed', @@ -160,6 +165,8 @@ export const EVENT_TYPES = { PANEL_RESIZE_START: 'panel.resize.start', PANEL_RESIZE_MOVE: 'panel.resize.move', PANEL_RESIZE_END: 'panel.resize.end', + PANEL_ACTIVATED: 'panel.activated', + PANEL_DEACTIVATED: 'panel.deactivated', PANEL_DRAG_START_FROM_TABPAGE: 'panel.drag.start.fromTabPage', PANEL_DRAG_MOVE_FROM_TABPAGE: 'panel.drag.move.fromTabPage', PANEL_DRAG_END_FROM_TABPAGE: 'panel.drag.end.fromTabPage', diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/handlers/PanelHandler.js b/AutoRobot/Windows/Robot/Web/src/DockLayout/handlers/PanelHandler.js index de94727..8d31f9f 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/handlers/PanelHandler.js +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/handlers/PanelHandler.js @@ -1,21 +1,5 @@ import { nanoid } from 'nanoid' -import { emitEvent, onEvent, onceEvent, registerHandler, unregisterHandler, getHandlerSnapshot } from '../eventBus' - -// Panel事件类型常量 -export const PANEL_EVENT_TYPES = { - TOGGLE_COLLAPSE: 'panel.toggleCollapse', - MAXIMIZE: 'panel.maximize', - CLOSE_REQUEST: 'panel.close.request', - CLOSE: 'panel.close', - CLOSED: 'panel.closed', - TOGGLE_TOOLBAR: 'panel.toggleToolbar', - DRAG_START: 'panel.drag.start', - DRAG_MOVE: 'panel.drag.move', - DRAG_END: 'panel.drag.end', - MAXIMIZE_SYNC: 'panel.maximize.sync', - ACTIVATED: 'panel.activated', - DEACTIVATED: 'panel.deactivated' -} +import { emitEvent, onEvent, onceEvent, registerHandler, unregisterHandler, getHandlerSnapshot, EVENT_TYPES } from '../eventBus' /** * Panel事件处理器类 @@ -98,7 +82,7 @@ class PanelEventHandler { this.panelStates.set(panelId, panelState) // 触发事件 - return emitEvent(PANEL_EVENT_TYPES.TOGGLE_COLLAPSE, { + return emitEvent(EVENT_TYPES.PANEL_TOGGLE_COLLAPSE, { panelId, collapsed: panelState.collapsed, source: 'PanelHandler' @@ -120,7 +104,7 @@ class PanelEventHandler { this.panelStates.set(panelId, panelState) // 触发最大化事件 - await emitEvent(PANEL_EVENT_TYPES.MAXIMIZE, { + await emitEvent(EVENT_TYPES.PANEL_MAXIMIZE, { panelId, maximized: true, source: 'PanelHandler' @@ -149,7 +133,7 @@ class PanelEventHandler { this.panelStates.set(panelId, panelState) // 触发最大化事件(false表示还原) - await emitEvent(PANEL_EVENT_TYPES.MAXIMIZE, { + await emitEvent(EVENT_TYPES.PANEL_MAXIMIZE, { panelId, maximized: false }, { @@ -173,7 +157,7 @@ class PanelEventHandler { */ requestClose(eventData) { const { areaId, panelId } = eventData; - emitEvent(PANEL_EVENT_TYPES.CLOSE_REQUEST, { + emitEvent(EVENT_TYPES.PANEL_CLOSE_REQUEST, { areaId, panelId, timestamp: Date.now() @@ -211,7 +195,7 @@ class PanelEventHandler { } // 触发关闭事件 - await emitEvent(PANEL_EVENT_TYPES.CLOSE, { + await emitEvent(EVENT_TYPES.PANEL_CLOSE, { panelId, areaId, source: 'PanelHandler', @@ -220,7 +204,7 @@ class PanelEventHandler { // 延迟触发已关闭事件(给组件销毁留时间) setTimeout(() => { - emitEvent(PANEL_EVENT_TYPES.CLOSED, { + emitEvent(EVENT_TYPES.PANEL_CLOSED, { panelId, areaId, source: 'PanelHandler', @@ -250,7 +234,7 @@ class PanelEventHandler { panelState.lastModified = Date.now() this.panelStates.set(panelId, panelState) - return emitEvent(PANEL_EVENT_TYPES.TOGGLE_TOOLBAR, { + return emitEvent(EVENT_TYPES.PANEL_TOGGLE_TOOLBAR, { panelId, toolbarExpanded: panelState.toolbarExpanded }, { @@ -281,7 +265,7 @@ class PanelEventHandler { this.dragStates.set(panelId, dragState) // 触发拖拽开始事件 - return emitEvent(PANEL_EVENT_TYPES.DRAG_START, { + return emitEvent(EVENT_TYPES.PANEL_DRAG_START, { panelId, event: dragEvent, dragState @@ -311,7 +295,7 @@ class PanelEventHandler { dragState.lastMove = Date.now() // 触发拖拽移动事件 - return emitEvent(PANEL_EVENT_TYPES.DRAG_MOVE, { + return emitEvent(EVENT_TYPES.PANEL_DRAG_MOVE, { panelId, event: dragEvent, dragState, @@ -346,7 +330,7 @@ class PanelEventHandler { } // 触发拖拽结束事件 - const result = await emitEvent(PANEL_EVENT_TYPES.DRAG_END, { + const result = await emitEvent(EVENT_TYPES.PANEL_DRAG_END, { panelId, event: dragEvent, dragState, @@ -379,7 +363,7 @@ class PanelEventHandler { panelState.lastModified = Date.now() this.panelStates.set(panelId, panelState) - return emitEvent(PANEL_EVENT_TYPES.ACTIVATED, { + return emitEvent(EVENT_TYPES.PANEL_ACTIVATED, { panelId }, { priority, @@ -404,7 +388,7 @@ class PanelEventHandler { panelState.lastModified = Date.now() this.panelStates.set(panelId, panelState) - return emitEvent(PANEL_EVENT_TYPES.DEACTIVATED, { + return emitEvent(EVENT_TYPES.PANEL_DEACTIVATED, { panelId }, { priority, @@ -418,7 +402,7 @@ class PanelEventHandler { */ onDragEnd(eventData) { const { areaId, panelId } = eventData; - this.emitEvent(PANEL_EVENT_TYPES.DRAG_END, { + this.emitEvent(EVENT_TYPES.PANEL_DRAG_END, { areaId, panelId, timestamp: Date.now() @@ -431,7 +415,7 @@ class PanelEventHandler { */ onActivate(eventData) { const { areaId, panelId } = eventData; - this.emitEvent(PANEL_EVENT_TYPES.ACTIVATED, { + this.emitEvent(EVENT_TYPES.PANEL_ACTIVATED, { areaId, panelId, timestamp: Date.now() @@ -444,7 +428,7 @@ class PanelEventHandler { */ onDeactivate(eventData) { const { areaId, panelId } = eventData; - this.emitEvent(PANEL_EVENT_TYPES.DEACTIVATED, { + this.emitEvent(EVENT_TYPES.PANEL_DEACTIVATED, { areaId, panelId, timestamp: Date.now() @@ -457,7 +441,7 @@ class PanelEventHandler { */ onCollapse(eventData) { const { areaId, panelId } = eventData; - this.emitEvent(PANEL_EVENT_TYPES.COLLAPSE, { + this.emitEvent(EVENT_TYPES.PANEL_COLLAPSE, { areaId, panelId, timestamp: Date.now() @@ -470,7 +454,7 @@ class PanelEventHandler { */ onExpand(eventData) { const { areaId, panelId } = eventData; - emitEvent(PANEL_EVENT_TYPES.EXPAND, { + emitEvent(EVENT_TYPES.PANEL_EXPAND, { areaId, panelId, timestamp: Date.now() @@ -485,7 +469,7 @@ class PanelEventHandler { */ onMaximize(eventData) { const { areaId, panelId } = eventData; - emitEvent(PANEL_EVENT_TYPES.MAXIMIZE, { + emitEvent(EVENT_TYPES.PANEL_MAXIMIZE, { areaId, panelId, timestamp: Date.now() @@ -500,7 +484,7 @@ class PanelEventHandler { */ onRestore(eventData) { const { areaId, panelId } = eventData; - this.emitEvent(PANEL_EVENT_TYPES.RESTORE, { + this.emitEvent(EVENT_TYPES.PANEL_RESTORE, { areaId, panelId, timestamp: Date.now() @@ -513,7 +497,7 @@ class PanelEventHandler { */ onToggleToolbar(eventData) { const { areaId, panelId } = eventData; - emitEvent(PANEL_EVENT_TYPES.TOGGLE_TOOLBAR, { + emitEvent(EVENT_TYPES.PANEL_TOGGLE_TOOLBAR, { areaId, panelId, timestamp: Date.now() @@ -601,7 +585,7 @@ class PanelEventHandler { if (!panelState) return // 触发Area同步事件 - return emitEvent(PANEL_EVENT_TYPES.MAXIMIZE_SYNC, { + return emitEvent(EVENT_TYPES.PANEL_MAXIMIZE_SYNC, { panelId, maximized, areaId: panelState.areaId @@ -615,11 +599,11 @@ class PanelEventHandler { */ async _registerEventListeners() { const events = [ - PANEL_EVENT_TYPES.CLOSE_REQUEST, - PANEL_EVENT_TYPES.DRAG_START, - PANEL_EVENT_TYPES.DRAG_MOVE, - PANEL_EVENT_TYPES.DRAG_END, - PANEL_EVENT_TYPES.MAXIMIZE_SYNC + EVENT_TYPES.PANEL_CLOSE_REQUEST, + EVENT_TYPES.PANEL_DRAG_START, + EVENT_TYPES.PANEL_DRAG_MOVE, + EVENT_TYPES.PANEL_DRAG_END, + EVENT_TYPES.PANEL_MAXIMIZE_SYNC ] for (const eventType of events) { @@ -642,19 +626,19 @@ class PanelEventHandler { */ _handleEvent(eventType, data, event) { switch (eventType) { - case PANEL_EVENT_TYPES.CLOSE_REQUEST: + case EVENT_TYPES.PANEL_CLOSE_REQUEST: this._handleCloseRequest(data, event) break - case PANEL_EVENT_TYPES.DRAG_START: + case EVENT_TYPES.PANEL_DRAG_START: this._handleDragStart(data, event) break - case PANEL_EVENT_TYPES.DRAG_MOVE: + case EVENT_TYPES.PANEL_DRAG_MOVE: this._handleDragMove(data, event) break - case PANEL_EVENT_TYPES.DRAG_END: + case EVENT_TYPES.PANEL_DRAG_END: this._handleDragEnd(data, event) break - case PANEL_EVENT_TYPES.MAXIMIZE_SYNC: + case EVENT_TYPES.PANEL_MAXIMIZE_SYNC: this._handleMaximizeSync(data, event) break } @@ -930,7 +914,7 @@ export const destroyPanelHandler = () => panelHandler.destroy() // 注册到事件处理器注册表 export const registerPanelHandler = () => { - return registerHandler('PanelHandler', Object.values(PANEL_EVENT_TYPES), panelHandler) + return registerHandler('PanelHandler', Object.values(EVENT_TYPES), panelHandler) } export const unregisterPanelHandler = () => {