增加事件总线
This commit is contained in:
373
AutoRobot/Windows/Robot/Web/src/DockLayout/eventBus.js
Normal file
373
AutoRobot/Windows/Robot/Web/src/DockLayout/eventBus.js
Normal file
@@ -0,0 +1,373 @@
|
|||||||
|
import { mitt } from 'mitt'
|
||||||
|
import { nanoid } from 'nanoid'
|
||||||
|
|
||||||
|
// 事件类型常量
|
||||||
|
export const EVENT_TYPES = {
|
||||||
|
// 区域事件
|
||||||
|
AREA_CLOSE: 'area.close',
|
||||||
|
AREA_POSITION_UPDATE: 'area.position.update',
|
||||||
|
AREA_DRAG_START: 'area.drag.start',
|
||||||
|
AREA_DRAG_MOVE: 'area.drag.move',
|
||||||
|
AREA_DRAG_END: 'area.drag.end',
|
||||||
|
AREA_DRAG_OVER: 'area.drag.over',
|
||||||
|
AREA_DRAG_LEAVE: 'area.drag.leave',
|
||||||
|
AREA_PANEL_CLOSED: 'area.panel.closed',
|
||||||
|
|
||||||
|
// 面板事件
|
||||||
|
PANEL_MAXIMIZE_SYNC: 'panel.maximize.sync',
|
||||||
|
PANEL_MAXIMIZE: 'panel.maximize',
|
||||||
|
PANEL_CLOSE: 'panel.close',
|
||||||
|
PANEL_CLOSE_REQUEST: 'panel.close.request',
|
||||||
|
PANEL_CLOSED: 'panel.closed',
|
||||||
|
PANEL_TOGGLE_COLLAPSE: 'panel.toggleCollapse',
|
||||||
|
PANEL_TOGGLE_TOOLBAR: 'panel.toggleToolbar',
|
||||||
|
|
||||||
|
// 面板拖拽事件
|
||||||
|
PANEL_DRAG_START: 'panel.drag.start',
|
||||||
|
PANEL_DRAG_MOVE: 'panel.drag.move',
|
||||||
|
PANEL_DRAG_END: 'panel.drag.end',
|
||||||
|
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',
|
||||||
|
|
||||||
|
// 标签页事件
|
||||||
|
TAB_CHANGE: 'tab.change',
|
||||||
|
TAB_CLOSE: 'tab.close',
|
||||||
|
TAB_ADD: 'tab.add',
|
||||||
|
TAB_DRAG_START: 'tab.drag.start',
|
||||||
|
TAB_DRAG_MOVE: 'tab.drag.move',
|
||||||
|
TAB_DRAG_END: 'tab.drag.end',
|
||||||
|
|
||||||
|
// 指示器事件
|
||||||
|
INDICATOR_SHOW: 'indicator.show',
|
||||||
|
INDICATOR_HIDE: 'indicator.hide',
|
||||||
|
INDICATOR_UPDATE: 'indicator.update',
|
||||||
|
|
||||||
|
// 调整大小事件
|
||||||
|
RESIZE_START: 'resize.start',
|
||||||
|
RESIZE_MOVE: 'resize.move',
|
||||||
|
RESIZE_END: 'resize.end',
|
||||||
|
|
||||||
|
// 窗口状态事件
|
||||||
|
WINDOW_STATE_CHANGE: 'window.state.change',
|
||||||
|
Z_INDEX_UPDATE: 'zIndex.update'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 增强的事件总线类
|
||||||
|
class EnhancedEventBus {
|
||||||
|
constructor() {
|
||||||
|
this.bus = mitt()
|
||||||
|
this.instanceId = nanoid()
|
||||||
|
this.debugMode = false
|
||||||
|
this.eventHistory = []
|
||||||
|
this.maxHistorySize = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用/禁用调试模式
|
||||||
|
*/
|
||||||
|
setDebugMode(enabled) {
|
||||||
|
this.debugMode = enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订阅事件
|
||||||
|
*/
|
||||||
|
on(eventType, callback, options = {}) {
|
||||||
|
const unsubscribe = this.bus.on(eventType, (data) => {
|
||||||
|
const event = {
|
||||||
|
id: nanoid(),
|
||||||
|
type: eventType,
|
||||||
|
data,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
source: {
|
||||||
|
instanceId: this.instanceId,
|
||||||
|
...options.source
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.debugMode) {
|
||||||
|
console.log(`[EventBus] ${eventType} event received:`, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录事件历史
|
||||||
|
this.recordEvent(event)
|
||||||
|
|
||||||
|
try {
|
||||||
|
callback(event.data, event)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[EventBus] Error in event listener for ${eventType}:`, error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 返回增强的取消订阅函数
|
||||||
|
return () => {
|
||||||
|
unsubscribe()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发事件
|
||||||
|
*/
|
||||||
|
emit(eventType, data, options = {}) {
|
||||||
|
const event = {
|
||||||
|
id: nanoid(),
|
||||||
|
type: eventType,
|
||||||
|
data,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
source: {
|
||||||
|
instanceId: this.instanceId,
|
||||||
|
...options.source
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.debugMode) {
|
||||||
|
console.log(`[EventBus] Emitting ${eventType}:`, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.recordEvent(event)
|
||||||
|
this.bus.emit(eventType, data)
|
||||||
|
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发一次性事件
|
||||||
|
*/
|
||||||
|
once(eventType, callback, options = {}) {
|
||||||
|
const unsubscribe = this.on(eventType, (data, event) => {
|
||||||
|
callback(data, event)
|
||||||
|
unsubscribe()
|
||||||
|
}, options)
|
||||||
|
|
||||||
|
return unsubscribe
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消订阅
|
||||||
|
*/
|
||||||
|
off(eventType, callback) {
|
||||||
|
this.bus.off(eventType, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有监听器
|
||||||
|
*/
|
||||||
|
clear() {
|
||||||
|
this.bus.all.clear()
|
||||||
|
this.eventHistory = []
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录事件历史
|
||||||
|
*/
|
||||||
|
recordEvent(event) {
|
||||||
|
this.eventHistory.push(event)
|
||||||
|
|
||||||
|
// 限制历史记录大小
|
||||||
|
if (this.eventHistory.length > this.maxHistorySize) {
|
||||||
|
this.eventHistory.shift()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取事件历史
|
||||||
|
*/
|
||||||
|
getEventHistory(limit = 20) {
|
||||||
|
return this.eventHistory.slice(-limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取监听器统计
|
||||||
|
*/
|
||||||
|
getStats() {
|
||||||
|
const stats = {}
|
||||||
|
for (const [eventType, listeners] of this.bus.all.entries()) {
|
||||||
|
stats[eventType] = Array.isArray(listeners) ? listeners.length : 1
|
||||||
|
}
|
||||||
|
return stats
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建全局事件总线实例
|
||||||
|
export const eventBus = new EnhancedEventBus()
|
||||||
|
|
||||||
|
// 拖拽状态管理器
|
||||||
|
export class DragStateManager {
|
||||||
|
constructor(eventBus) {
|
||||||
|
this.eventBus = eventBus
|
||||||
|
this.dragStates = new Map()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始拖拽
|
||||||
|
*/
|
||||||
|
startDrag(dragInfo) {
|
||||||
|
const { type, id, event } = dragInfo
|
||||||
|
|
||||||
|
this.dragStates.set(id, {
|
||||||
|
type,
|
||||||
|
startTime: Date.now(),
|
||||||
|
initialPosition: { x: event.clientX, y: event.clientY },
|
||||||
|
currentPosition: { x: event.clientX, y: event.clientY },
|
||||||
|
isActive: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// 触发拖拽开始事件
|
||||||
|
const eventType = `${type}.drag.start`
|
||||||
|
this.eventBus.emit(eventType, {
|
||||||
|
id,
|
||||||
|
position: { x: event.clientX, y: event.clientY },
|
||||||
|
initialPosition: { x: event.clientX, y: event.clientY }
|
||||||
|
})
|
||||||
|
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拖拽移动
|
||||||
|
*/
|
||||||
|
moveDrag(id, event) {
|
||||||
|
const dragState = this.dragStates.get(id)
|
||||||
|
if (!dragState || !dragState.isActive) return
|
||||||
|
|
||||||
|
dragState.currentPosition = { x: event.clientX, y: event.clientY }
|
||||||
|
const delta = {
|
||||||
|
x: event.clientX - dragState.initialPosition.x,
|
||||||
|
y: event.clientY - dragState.initialPosition.y
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发拖拽移动事件
|
||||||
|
const eventType = `${dragState.type}.drag.move`
|
||||||
|
this.eventBus.emit(eventType, {
|
||||||
|
id,
|
||||||
|
position: dragState.currentPosition,
|
||||||
|
delta,
|
||||||
|
startTime: dragState.startTime
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束拖拽
|
||||||
|
*/
|
||||||
|
endDrag(id, event) {
|
||||||
|
const dragState = this.dragStates.get(id)
|
||||||
|
if (!dragState) return
|
||||||
|
|
||||||
|
dragState.isActive = false
|
||||||
|
dragState.endTime = Date.now()
|
||||||
|
dragState.finalPosition = { x: event.clientX, y: event.clientY }
|
||||||
|
|
||||||
|
// 触发拖拽结束事件
|
||||||
|
const eventType = `${dragState.type}.drag.end`
|
||||||
|
this.eventBus.emit(eventType, {
|
||||||
|
id,
|
||||||
|
position: dragState.finalPosition,
|
||||||
|
initialPosition: dragState.initialPosition,
|
||||||
|
duration: dragState.endTime - dragState.startTime
|
||||||
|
})
|
||||||
|
|
||||||
|
// 清理拖拽状态
|
||||||
|
setTimeout(() => {
|
||||||
|
this.dragStates.delete(id)
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
return dragState
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取拖拽状态
|
||||||
|
*/
|
||||||
|
getDragState(id) {
|
||||||
|
return this.dragStates.get(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否有活动的拖拽
|
||||||
|
*/
|
||||||
|
hasActiveDrag(id = null) {
|
||||||
|
if (id) {
|
||||||
|
const state = this.dragStates.get(id)
|
||||||
|
return state && state.isActive
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const state of this.dragStates.values()) {
|
||||||
|
if (state.isActive) return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消所有拖拽
|
||||||
|
*/
|
||||||
|
cancelAllDrags() {
|
||||||
|
for (const [id, state] of this.dragStates.entries()) {
|
||||||
|
if (state.isActive) {
|
||||||
|
this.endDrag(id, {
|
||||||
|
clientX: state.currentPosition.x,
|
||||||
|
clientY: state.currentPosition.y
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建拖拽状态管理器实例
|
||||||
|
export const dragStateManager = new DragStateManager(eventBus)
|
||||||
|
|
||||||
|
// 便捷的拖拽事件触发函数
|
||||||
|
export const triggerDragEvent = {
|
||||||
|
area: {
|
||||||
|
start: (areaId, event) => {
|
||||||
|
return dragStateManager.startDrag({ type: 'area', id: areaId, event })
|
||||||
|
},
|
||||||
|
move: (areaId, event) => {
|
||||||
|
dragStateManager.moveDrag(areaId, event)
|
||||||
|
},
|
||||||
|
end: (areaId, event) => {
|
||||||
|
dragStateManager.endDrag(areaId, event)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
tab: {
|
||||||
|
start: (tabId, event) => {
|
||||||
|
return dragStateManager.startDrag({ type: 'tab', id: tabId, event })
|
||||||
|
},
|
||||||
|
move: (tabId, event) => {
|
||||||
|
dragStateManager.moveDrag(tabId, event)
|
||||||
|
},
|
||||||
|
end: (tabId, event) => {
|
||||||
|
dragStateManager.endDrag(tabId, event)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
panel: {
|
||||||
|
start: (panelId, event) => {
|
||||||
|
return dragStateManager.startDrag({ type: 'panel', id: panelId, event })
|
||||||
|
},
|
||||||
|
move: (panelId, event) => {
|
||||||
|
dragStateManager.moveDrag(panelId, event)
|
||||||
|
},
|
||||||
|
end: (panelId, event) => {
|
||||||
|
dragStateManager.endDrag(panelId, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出便捷触发函数
|
||||||
|
export const emitEvent = (eventType, data, options = {}) => {
|
||||||
|
return eventBus.emit(eventType, data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const onEvent = (eventType, callback, options = {}) => {
|
||||||
|
return eventBus.on(eventType, callback, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const onceEvent = (eventType, callback, options = {}) => {
|
||||||
|
return eventBus.once(eventType, callback, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const offEvent = (eventType, callback) => {
|
||||||
|
return eventBus.off(eventType, callback)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user