1
This commit is contained in:
@@ -2,40 +2,34 @@
|
||||
<BuiltInApp app-id="calculator" title="计算器">
|
||||
<div class="calculator">
|
||||
<div class="display">
|
||||
<input
|
||||
v-model="displayValue"
|
||||
type="text"
|
||||
readonly
|
||||
class="display-input"
|
||||
:class="{ 'error': hasError }"
|
||||
>
|
||||
<input v-model="displayValue" type="text" readonly class="display-input" :class="{ 'error': hasError }">
|
||||
</div>
|
||||
|
||||
|
||||
<div class="buttons">
|
||||
<!-- 第一行 -->
|
||||
<button @click="clear" class="btn btn-clear">C</button>
|
||||
<button @click="deleteLast" class="btn btn-operation">←</button>
|
||||
<button @click="appendOperation('/')" class="btn btn-operation">÷</button>
|
||||
<button @click="appendOperation('*')" class="btn btn-operation">×</button>
|
||||
|
||||
|
||||
<!-- 第二行 -->
|
||||
<button @click="appendNumber('7')" class="btn btn-number">7</button>
|
||||
<button @click="appendNumber('8')" class="btn btn-number">8</button>
|
||||
<button @click="appendNumber('9')" class="btn btn-number">9</button>
|
||||
<button @click="appendOperation('-')" class="btn btn-operation">-</button>
|
||||
|
||||
|
||||
<!-- 第三行 -->
|
||||
<button @click="appendNumber('4')" class="btn btn-number">4</button>
|
||||
<button @click="appendNumber('5')" class="btn btn-number">5</button>
|
||||
<button @click="appendNumber('6')" class="btn btn-number">6</button>
|
||||
<button @click="appendOperation('+')" class="btn btn-operation">+</button>
|
||||
|
||||
|
||||
<!-- 第四行 -->
|
||||
<button @click="appendNumber('1')" class="btn btn-number">1</button>
|
||||
<button @click="appendNumber('2')" class="btn btn-number">2</button>
|
||||
<button @click="appendNumber('3')" class="btn btn-number">3</button>
|
||||
<button @click="calculate" class="btn btn-equals" rowspan="2">=</button>
|
||||
|
||||
|
||||
<!-- 第五行 -->
|
||||
<button @click="appendNumber('0')" class="btn btn-number btn-zero">0</button>
|
||||
<button @click="appendNumber('.')" class="btn btn-number">.</button>
|
||||
@@ -79,27 +73,28 @@ const saveHistory = async (expression: string, result: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 直接使用事件服务发送通知
|
||||
const showNotification = (message: string) => {
|
||||
if (systemService) {
|
||||
const eventService = systemService.getEventService()
|
||||
eventService.sendMessage('calculator', 'user-interaction', {
|
||||
type: 'notification',
|
||||
message,
|
||||
timestamp: new Date()
|
||||
})
|
||||
}
|
||||
}
|
||||
// 移除事件服务相关代码
|
||||
// // 直接使用事件服务发送通知
|
||||
// const showNotification = (message: string) => {
|
||||
// if (systemService) {
|
||||
// const eventService = systemService.getEventService()
|
||||
// eventService.sendMessage('calculator', 'user-interaction', {
|
||||
// type: 'notification',
|
||||
// message,
|
||||
// timestamp: new Date()
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// 添加数字
|
||||
const appendNumber = (num: string) => {
|
||||
hasError.value = false
|
||||
|
||||
|
||||
if (shouldResetDisplay.value) {
|
||||
displayValue.value = '0'
|
||||
shouldResetDisplay.value = false
|
||||
}
|
||||
|
||||
|
||||
if (num === '.') {
|
||||
if (!displayValue.value.includes('.')) {
|
||||
displayValue.value += num
|
||||
@@ -117,10 +112,10 @@ const appendNumber = (num: string) => {
|
||||
const appendOperation = (op: string) => {
|
||||
hasError.value = false
|
||||
shouldResetDisplay.value = false
|
||||
|
||||
|
||||
const lastChar = displayValue.value.slice(-1)
|
||||
const operations = ['+', '-', '*', '/']
|
||||
|
||||
|
||||
// 如果最后一个字符是运算符,替换它
|
||||
if (operations.includes(lastChar)) {
|
||||
displayValue.value = displayValue.value.slice(0, -1) + op
|
||||
@@ -136,29 +131,30 @@ const calculate = async () => {
|
||||
let expression = displayValue.value
|
||||
.replace(/×/g, '*')
|
||||
.replace(/÷/g, '/')
|
||||
|
||||
|
||||
// 简单的表达式验证
|
||||
if (/[+\-*/]$/.test(expression)) {
|
||||
return // 以运算符结尾,不计算
|
||||
}
|
||||
|
||||
|
||||
const originalExpression = displayValue.value
|
||||
const result = eval(expression)
|
||||
|
||||
|
||||
if (!isFinite(result)) {
|
||||
throw new Error('除零错误')
|
||||
}
|
||||
|
||||
|
||||
displayValue.value = result.toString()
|
||||
lastResult.value = result
|
||||
shouldResetDisplay.value = true
|
||||
|
||||
|
||||
// 保存历史记录
|
||||
await saveHistory(originalExpression, result.toString())
|
||||
|
||||
// 发送通知
|
||||
showNotification(`计算结果: ${result}`)
|
||||
|
||||
|
||||
// 移除事件服务相关代码
|
||||
// // 发送通知
|
||||
// showNotification(`计算结果: ${result}`)
|
||||
|
||||
} catch (error) {
|
||||
hasError.value = true
|
||||
displayValue.value = '错误'
|
||||
@@ -179,12 +175,12 @@ const clear = () => {
|
||||
// 删除最后一个字符
|
||||
const deleteLast = () => {
|
||||
hasError.value = false
|
||||
|
||||
|
||||
if (shouldResetDisplay.value) {
|
||||
clear()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (displayValue.value.length > 1) {
|
||||
displayValue.value = displayValue.value.slice(0, -1)
|
||||
} else {
|
||||
@@ -195,9 +191,9 @@ const deleteLast = () => {
|
||||
// 键盘事件处理
|
||||
const handleKeyboard = (event: KeyboardEvent) => {
|
||||
event.preventDefault()
|
||||
|
||||
|
||||
const key = event.key
|
||||
|
||||
|
||||
if (/[0-9.]/.test(key)) {
|
||||
appendNumber(key)
|
||||
} else if (['+', '-', '*', '/'].includes(key)) {
|
||||
@@ -330,17 +326,17 @@ onMounted(() => {
|
||||
margin: 10px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
|
||||
.display-input {
|
||||
height: 60px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
.buttons {
|
||||
height: 280px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
|
||||
.btn {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ const appContext = {
|
||||
systemService,
|
||||
// 直接暴露系统服务的方法,简化调用
|
||||
storage: systemService?.getResourceService(),
|
||||
events: systemService?.getEventService(),
|
||||
// 移除 events: systemService?.getEventService(),
|
||||
lifecycle: systemService?.getLifecycleManager(),
|
||||
window: {
|
||||
setTitle: (title: string) => {
|
||||
@@ -52,11 +52,11 @@ onMounted(async () => {
|
||||
version: '1.0.0',
|
||||
permissions: ['storage', 'notification']
|
||||
})
|
||||
|
||||
|
||||
if (props.title) {
|
||||
await window.SystemSDK.window.setTitle(props.title)
|
||||
}
|
||||
|
||||
|
||||
console.log(`内置应用 ${props.appId} 初始化成功`)
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,10 +1,48 @@
|
||||
import type { IDestroyable } from '@/common/types/IDestroyable'
|
||||
import type { WindowState } from '@/services/WindowService'
|
||||
import type { ResourceType } from '@/services/ResourceService'
|
||||
|
||||
/**
|
||||
* 窗体数据更新参数
|
||||
*/
|
||||
export interface WindowFormDataUpdateParams {
|
||||
/** 窗口id */
|
||||
id: string
|
||||
/** 窗口状态 */
|
||||
state: WindowState
|
||||
/** 窗口宽度 */
|
||||
width: number
|
||||
/** 窗口高度 */
|
||||
height: number
|
||||
/** 窗口x坐标(左上角) */
|
||||
x: number
|
||||
/** 窗口y坐标(左上角) */
|
||||
y: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件定义
|
||||
* @interface IEventMap 事件定义 键是事件名称,值是事件处理函数
|
||||
*/
|
||||
export interface IEventMap {
|
||||
// 系统就绪事件
|
||||
onSystemReady: (data: { timestamp: Date; services: string[] }) => void
|
||||
|
||||
// 窗体相关事件
|
||||
onWindowStateChanged: (windowId: string, newState: string, oldState: string) => void
|
||||
onWindowFormDataUpdate: (data: WindowFormDataUpdateParams) => void
|
||||
onWindowFormResizeStart: (windowId: string) => void
|
||||
onWindowFormResizing: (windowId: string, width: number, height: number) => void
|
||||
onWindowFormResizeEnd: (windowId: string) => void
|
||||
onWindowClose: (windowId: string) => void
|
||||
|
||||
// 应用生命周期事件
|
||||
onAppLifecycle: (data: { appId: string; event: string; timestamp: Date }) => void
|
||||
|
||||
// 资源相关事件
|
||||
onResourceQuotaExceeded: (appId: string, resourceType: ResourceType) => void
|
||||
onPerformanceAlert: (data: { type: 'memory' | 'cpu'; usage: number; limit: number }) => void
|
||||
|
||||
/**
|
||||
* 事件处理函数映射
|
||||
*/
|
||||
@@ -29,7 +67,7 @@ export interface IEventBuilder<Events extends IEventMap> extends IDestroyable {
|
||||
immediate?: boolean
|
||||
immediateArgs?: Parameters<F>
|
||||
once?: boolean
|
||||
},
|
||||
}
|
||||
): void
|
||||
|
||||
/**
|
||||
@@ -46,5 +84,8 @@ export interface IEventBuilder<Events extends IEventMap> extends IDestroyable {
|
||||
* @param args 参数
|
||||
* @returns void
|
||||
*/
|
||||
notifyEvent<E extends keyof Events, F extends Events[E]>(eventName: E, ...args: Parameters<F>): void
|
||||
}
|
||||
notifyEvent<E extends keyof Events, F extends Events[E]>(
|
||||
eventName: E,
|
||||
...args: Parameters<F>
|
||||
): void
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { reactive } from 'vue'
|
||||
import type { WindowService } from './WindowService'
|
||||
import type { ResourceService } from './ResourceService'
|
||||
import type { EventCommunicationService } from './EventCommunicationService'
|
||||
import type { ApplicationSandboxEngine } from './ApplicationSandboxEngine'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { externalAppDiscovery } from './ExternalAppDiscovery'
|
||||
@@ -121,21 +120,16 @@ export class ApplicationLifecycleManager {
|
||||
|
||||
private windowService: WindowService
|
||||
private resourceService: ResourceService
|
||||
private eventService: EventCommunicationService
|
||||
private sandboxEngine: ApplicationSandboxEngine
|
||||
|
||||
constructor(
|
||||
windowService: WindowService,
|
||||
resourceService: ResourceService,
|
||||
eventService: EventCommunicationService,
|
||||
sandboxEngine: ApplicationSandboxEngine
|
||||
) {
|
||||
this.windowService = windowService
|
||||
this.resourceService = resourceService
|
||||
this.eventService = eventService
|
||||
this.sandboxEngine = sandboxEngine
|
||||
|
||||
this.setupEventListeners()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,49 +379,6 @@ export class ApplicationLifecycleManager {
|
||||
}
|
||||
}
|
||||
|
||||
// 私有方法
|
||||
|
||||
/**
|
||||
* 为内置应用挂载 AppRenderer 组件
|
||||
*/
|
||||
private async mountBuiltInApp(appId: string, windowInstance: any): Promise<void> {
|
||||
try {
|
||||
// 动态导入 Vue 和 AppRenderer
|
||||
const { createApp } = await import('vue')
|
||||
const AppRenderer = (await import('../ui/components/AppRenderer.vue')).default
|
||||
|
||||
console.log(`[LifecycleManager] 为内置应用 ${appId} 创建 AppRenderer 组件`)
|
||||
|
||||
console.log('----------------------------------')
|
||||
|
||||
const app = createApp({
|
||||
components: { AppRenderer },
|
||||
template: `<AppRenderer :app-id="'${appId}'" :window-id="'${windowInstance.id}'"/>`
|
||||
})
|
||||
|
||||
// 提供系统服务(使用当前实例所在的系统服务)
|
||||
app.provide('systemService', {
|
||||
getWindowService: () => this.windowService,
|
||||
getResourceService: () => this.resourceService,
|
||||
getEventService: () => this.eventService,
|
||||
getSandboxEngine: () => this.sandboxEngine,
|
||||
getLifecycleManager: () => this
|
||||
})
|
||||
|
||||
// 挂载到窗口内容区域
|
||||
const contentArea = windowInstance.element?.querySelector('.window-content')
|
||||
if (contentArea) {
|
||||
app.mount(contentArea)
|
||||
console.log(`[LifecycleManager] AppRenderer 组件已挂载到窗口 ${windowInstance.id}`)
|
||||
} else {
|
||||
throw new Error('未找到窗口内容区域')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`内置应用 ${appId} 挂载失败:`, error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查权限
|
||||
*/
|
||||
@@ -510,28 +461,6 @@ export class ApplicationLifecycleManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置事件监听器
|
||||
*/
|
||||
private setupEventListeners(): void {
|
||||
// 监听沙箱状态变化
|
||||
this.eventService.subscribe('system', 'sandbox-state-change', (message) => {
|
||||
const { sandboxId, newState } = message.payload
|
||||
|
||||
// 查找对应的应用
|
||||
for (const app of this.installedApps.values()) {
|
||||
if (app.sandboxId === sandboxId) {
|
||||
if (newState === 'error') {
|
||||
this.handleAppError(app.id, new Error('沙箱错误'))
|
||||
} else if (newState === 'destroyed') {
|
||||
this.handleAppCrash(app.id, '沙箱被销毁')
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理应用错误
|
||||
*/
|
||||
@@ -541,12 +470,6 @@ export class ApplicationLifecycleManager {
|
||||
|
||||
app.errorCount++
|
||||
|
||||
this.eventService.sendMessage('system', 'app-lifecycle', {
|
||||
type: 'error',
|
||||
appId,
|
||||
error: error.message
|
||||
})
|
||||
|
||||
console.error(`应用 ${appId} 发生错误:`, error)
|
||||
}
|
||||
|
||||
@@ -577,11 +500,12 @@ export class ApplicationLifecycleManager {
|
||||
const oldState = app.state
|
||||
app.state = newState
|
||||
|
||||
this.eventService.sendMessage('system', 'app-lifecycle', {
|
||||
type: 'stateChanged',
|
||||
appId: app.id,
|
||||
newState,
|
||||
oldState
|
||||
})
|
||||
// 移除事件服务消息发送
|
||||
// this.eventService.sendMessage('system', 'app-lifecycle', {
|
||||
// type: 'stateChanged',
|
||||
// appId: app.id,
|
||||
// newState,
|
||||
// oldState
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { reactive } from 'vue'
|
||||
import type { ResourceService } from './ResourceService'
|
||||
import type { EventCommunicationService } from './EventCommunicationService'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
/**
|
||||
@@ -107,11 +106,9 @@ export class ApplicationSandboxEngine {
|
||||
private performanceData = reactive(new Map<string, SandboxPerformance[]>())
|
||||
private monitoringInterval: number | null = null
|
||||
private resourceService: ResourceService
|
||||
private eventService: EventCommunicationService
|
||||
|
||||
constructor(resourceService: ResourceService, eventService: EventCommunicationService) {
|
||||
constructor(resourceService: ResourceService) {
|
||||
this.resourceService = resourceService
|
||||
this.eventService = eventService
|
||||
this.startPerformanceMonitoring()
|
||||
}
|
||||
|
||||
@@ -1163,27 +1160,7 @@ export class ApplicationSandboxEngine {
|
||||
/**
|
||||
* 检查性能阈值
|
||||
*/
|
||||
private checkPerformanceThresholds(sandbox: SandboxInstance, metrics: SandboxPerformance): void {
|
||||
// 内存使用检查
|
||||
if (metrics.memoryUsage > sandbox.config.maxMemoryUsage) {
|
||||
this.eventService.sendMessage('system', 'performance-alert', {
|
||||
sandboxId: sandbox.id,
|
||||
type: 'memory',
|
||||
usage: metrics.memoryUsage,
|
||||
limit: sandbox.config.maxMemoryUsage
|
||||
})
|
||||
}
|
||||
|
||||
// CPU使用检查
|
||||
if (metrics.cpuUsage > sandbox.config.maxCpuUsage) {
|
||||
this.eventService.sendMessage('system', 'performance-alert', {
|
||||
sandboxId: sandbox.id,
|
||||
type: 'cpu',
|
||||
usage: metrics.cpuUsage,
|
||||
limit: sandbox.config.maxCpuUsage
|
||||
})
|
||||
}
|
||||
}
|
||||
private checkPerformanceThresholds(sandbox: SandboxInstance, metrics: SandboxPerformance): void {}
|
||||
|
||||
/**
|
||||
* 开始性能监控
|
||||
@@ -1220,11 +1197,11 @@ export class ApplicationSandboxEngine {
|
||||
const oldState = sandbox.state
|
||||
sandbox.state = newState
|
||||
|
||||
// 触发状态变化事件
|
||||
this.eventService.sendMessage('system', 'sandbox-state-change', {
|
||||
sandboxId: sandbox.id,
|
||||
newState,
|
||||
oldState
|
||||
})
|
||||
// 移除事件服务消息发送
|
||||
// this.eventService.sendMessage('system', 'sandbox-state-change', {
|
||||
// sandboxId: sandbox.id,
|
||||
// newState,
|
||||
// oldState
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,748 +0,0 @@
|
||||
import { reactive } from 'vue'
|
||||
import type { IEventBuilder, IEventMap } from '@/events/IEventBuilder'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import type { WindowState } from './WindowService'
|
||||
import type { ResourceType } from './ResourceService'
|
||||
|
||||
/**
|
||||
* 消息类型枚举
|
||||
*/
|
||||
export enum MessageType {
|
||||
/** 系统事件 */
|
||||
SYSTEM = 'system',
|
||||
/** 应用事件 */
|
||||
APPLICATION = 'application',
|
||||
/** 用户交互事件 */
|
||||
USER_INTERACTION = 'user_interaction',
|
||||
/** 跨应用事件 */
|
||||
CROSS_APP = 'cross_app',
|
||||
/** 广播事件 */
|
||||
BROADCAST = 'broadcast'
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息优先级枚举
|
||||
*/
|
||||
export enum MessagePriority {
|
||||
/** 低优先级 */
|
||||
LOW = 0,
|
||||
/** 正常优先级 */
|
||||
NORMAL = 1,
|
||||
/** 高优先级 */
|
||||
HIGH = 2,
|
||||
/** 紧急优先级 */
|
||||
CRITICAL = 3
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息状态枚举
|
||||
*/
|
||||
export enum MessageStatus {
|
||||
/** 等待发送 */
|
||||
PENDING = 'pending',
|
||||
/** 已发送 */
|
||||
SENT = 'sent',
|
||||
/** 已送达 */
|
||||
DELIVERED = 'delivered',
|
||||
/** 发送失败 */
|
||||
FAILED = 'failed',
|
||||
/** 已取消 */
|
||||
EXPIRED = 'expired'
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件消息接口
|
||||
*/
|
||||
export interface EventMessage {
|
||||
/** 消息ID */
|
||||
id: string
|
||||
/** 消息类型 */
|
||||
type: MessageType
|
||||
/** 消息优先级 */
|
||||
priority: MessagePriority
|
||||
/** 发送者ID */
|
||||
senderId: string
|
||||
/** 接收者ID, undefined表示广播消息 */
|
||||
receiverId?: string
|
||||
/** 消息频道 */
|
||||
channel: string
|
||||
/** 消息内容 */
|
||||
payload: any
|
||||
/** 消息发送时间 */
|
||||
timestamp: Date
|
||||
/** 消息过期时间 */
|
||||
expiresAt?: Date
|
||||
/** 消息状态 */
|
||||
status: MessageStatus
|
||||
/** 重试次数 */
|
||||
retryCount: number
|
||||
/** 最大重试次数 */
|
||||
maxRetries: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件订阅者接口
|
||||
*/
|
||||
export interface EventSubscriber {
|
||||
/** 订阅者ID */
|
||||
id: string
|
||||
/** 应用ID */
|
||||
appId: string
|
||||
/** 消息频道 */
|
||||
channel: string
|
||||
/** 订阅者处理函数 */
|
||||
handler: (message: EventMessage) => void | Promise<void>
|
||||
/** 消息过滤器 */
|
||||
filter?: (message: EventMessage) => boolean
|
||||
/** 订阅者优先级 */
|
||||
priority: MessagePriority
|
||||
/** 创建时间 */
|
||||
createdAt: Date
|
||||
/** 是否启用 */
|
||||
active: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 通信通道接口
|
||||
*/
|
||||
export interface CommunicationChannel {
|
||||
/** 通道名称 */
|
||||
name: string
|
||||
/** 通道描述 */
|
||||
description: string
|
||||
/** 是否需要权限 */
|
||||
restricted: boolean
|
||||
/** 允许的源应用ID列表 */
|
||||
/** 允许访问的应用ID列表 */
|
||||
allowedApps: string[]
|
||||
/** 最大消息大小(字节) */
|
||||
maxMessageSize: number
|
||||
/** 消息保留时间(毫秒) */
|
||||
messageRetention: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件统计信息
|
||||
*/
|
||||
export interface EventStatistics {
|
||||
/** 总发送消息数 */
|
||||
totalMessagesSent: number
|
||||
/** 总接收消息数 */
|
||||
totalMessagesReceived: number
|
||||
/** 总广播数 */
|
||||
totalBroadcasts: number
|
||||
/** 失败消息数 */
|
||||
failedMessages: number
|
||||
/** 激活的订阅者数 */
|
||||
activeSubscribers: number
|
||||
/** 通道使用情况 */
|
||||
channelUsage: Map<string, number>
|
||||
}
|
||||
|
||||
/**
|
||||
* 窗体数据更新参数
|
||||
*/
|
||||
export interface WindowFormDataUpdateParams {
|
||||
/** 窗口id */
|
||||
id: string
|
||||
/** 窗口状态 */
|
||||
state: WindowState
|
||||
/** 窗口宽度 */
|
||||
width: number
|
||||
/** 窗口高度 */
|
||||
height: number
|
||||
/** 窗口x坐标(左上角) */
|
||||
x: number
|
||||
/** 窗口y坐标(左上角) */
|
||||
y: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件通信服务事件接口
|
||||
*/
|
||||
export interface EventCommunicationEvents extends IEventMap {
|
||||
// 系统就绪事件
|
||||
onSystemReady: (data: { timestamp: Date; services: string[] }) => void
|
||||
|
||||
// 窗体相关事件
|
||||
onWindowStateChanged: (windowId: string, newState: string, oldState: string) => void
|
||||
onWindowFormDataUpdate: (data: WindowFormDataUpdateParams) => void
|
||||
onWindowFormResizeStart: (windowId: string) => void
|
||||
onWindowFormResizing: (windowId: string, width: number, height: number) => void
|
||||
onWindowFormResizeEnd: (windowId: string) => void
|
||||
onWindowClose: (windowId: string) => void
|
||||
|
||||
// 应用生命周期事件
|
||||
onAppLifecycle: (data: { appId: string; event: string; timestamp: Date }) => void
|
||||
|
||||
// 资源相关事件
|
||||
onResourceQuotaExceeded: (appId: string, resourceType: ResourceType) => void
|
||||
onPerformanceAlert: (data: { type: 'memory' | 'cpu'; usage: number; limit: number }) => void
|
||||
|
||||
// 消息处理事件
|
||||
onMessageProcessed: (message: EventMessage) => void
|
||||
onMessageFailed: (message: EventMessage, error: any) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件通信服务类
|
||||
*/
|
||||
export class EventCommunicationService {
|
||||
private subscribers = reactive(new Map<string, EventSubscriber>())
|
||||
private messageQueue = reactive(new Map<string, EventMessage[]>()) // 按应用分组的消息队列
|
||||
private messageHistory = reactive(new Map<string, EventMessage[]>()) // 消息历史记录
|
||||
private channels = reactive(new Map<string, CommunicationChannel>())
|
||||
private statistics = reactive<EventStatistics>({
|
||||
totalMessagesSent: 0,
|
||||
totalMessagesReceived: 0,
|
||||
totalBroadcasts: 0,
|
||||
failedMessages: 0,
|
||||
activeSubscribers: 0,
|
||||
channelUsage: new Map()
|
||||
})
|
||||
|
||||
private processingInterval: number | null = null
|
||||
private lastProcessTime: number = 0
|
||||
private processInterval: number = 100 // 处理间隔(毫秒)
|
||||
private eventBus: IEventBuilder<EventCommunicationEvents>
|
||||
|
||||
constructor(eventBus: IEventBuilder<EventCommunicationEvents>) {
|
||||
this.eventBus = eventBus
|
||||
this.initializeDefaultChannels()
|
||||
this.startMessageProcessing()
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅事件频道
|
||||
*/
|
||||
subscribe(
|
||||
appId: string,
|
||||
channel: string,
|
||||
handler: (message: EventMessage) => void | Promise<void>,
|
||||
options: {
|
||||
filter?: (message: EventMessage) => boolean
|
||||
priority?: MessagePriority
|
||||
} = {}
|
||||
): string {
|
||||
// 检查通道权限
|
||||
if (!this.canAccessChannel(appId, channel)) {
|
||||
throw new Error(`应用 ${appId} 无权访问频道 ${channel}`)
|
||||
}
|
||||
|
||||
const subscriberId = uuidv4()
|
||||
const subscriber: EventSubscriber = {
|
||||
id: subscriberId,
|
||||
appId,
|
||||
channel,
|
||||
handler,
|
||||
filter: options.filter,
|
||||
priority: options.priority || MessagePriority.NORMAL,
|
||||
createdAt: new Date(),
|
||||
active: true
|
||||
}
|
||||
|
||||
this.subscribers.set(subscriberId, subscriber)
|
||||
this.updateActiveSubscribersCount()
|
||||
|
||||
console.log(`应用 ${appId} 订阅了频道 ${channel}`)
|
||||
return subscriberId
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订阅
|
||||
*/
|
||||
unsubscribe(subscriberId: string): boolean {
|
||||
const result = this.subscribers.delete(subscriberId)
|
||||
if (result) {
|
||||
this.updateActiveSubscribersCount()
|
||||
console.log(`取消订阅: ${subscriberId}`)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*/
|
||||
async sendMessage(
|
||||
senderId: string,
|
||||
channel: string,
|
||||
payload: any,
|
||||
options: {
|
||||
receiverId?: string
|
||||
priority?: MessagePriority
|
||||
type?: MessageType
|
||||
expiresIn?: number // 过期时间(毫秒)
|
||||
maxRetries?: number
|
||||
} = {}
|
||||
): Promise<string> {
|
||||
if (this.getChannelSubscriberCount(channel) === 0) {
|
||||
throw new Error(`频道 ${channel} 无订阅者`)
|
||||
}
|
||||
// 检查发送者权限
|
||||
if (!this.canAccessChannel(senderId, channel)) {
|
||||
throw new Error(`应用 ${senderId} 无权向频道 ${channel} 发送消息`)
|
||||
}
|
||||
|
||||
// 检查消息大小
|
||||
const messageSize = JSON.stringify(payload).length
|
||||
const channelConfig = this.channels.get(channel)
|
||||
if (channelConfig && messageSize > channelConfig.maxMessageSize) {
|
||||
throw new Error(`消息大小超出限制: ${messageSize} > ${channelConfig.maxMessageSize}`)
|
||||
}
|
||||
|
||||
const messageId = uuidv4()
|
||||
const now = new Date()
|
||||
|
||||
const message: EventMessage = {
|
||||
id: messageId,
|
||||
type: options.type || MessageType.APPLICATION,
|
||||
priority: options.priority || MessagePriority.NORMAL,
|
||||
senderId,
|
||||
receiverId: options.receiverId,
|
||||
channel,
|
||||
payload,
|
||||
timestamp: now,
|
||||
expiresAt: options.expiresIn ? new Date(now.getTime() + options.expiresIn) : undefined,
|
||||
status: MessageStatus.PENDING,
|
||||
retryCount: 0,
|
||||
maxRetries: options.maxRetries || 3
|
||||
}
|
||||
|
||||
// 如果是点对点消息,直接发送
|
||||
if (options.receiverId) {
|
||||
await this.deliverMessage(message)
|
||||
} else {
|
||||
// 广播消息,加入队列处理
|
||||
this.addToQueue(message)
|
||||
}
|
||||
|
||||
// 更新统计信息
|
||||
this.statistics.totalMessagesSent++
|
||||
if (!options.receiverId) {
|
||||
this.statistics.totalBroadcasts++
|
||||
}
|
||||
|
||||
const channelUsage = this.statistics.channelUsage.get(channel) || 0
|
||||
this.statistics.channelUsage.set(channel, channelUsage + 1)
|
||||
|
||||
// 记录消息历史
|
||||
this.recordMessage(message)
|
||||
|
||||
console.log(
|
||||
`[EventCommunication] 消息 ${messageId} 已发送到频道 ${channel}[发送者: ${senderId}]`
|
||||
)
|
||||
return messageId
|
||||
}
|
||||
|
||||
/**
|
||||
* 广播消息到所有订阅者
|
||||
*/
|
||||
async broadcast(
|
||||
senderId: string,
|
||||
channel: string,
|
||||
payload: any,
|
||||
options: {
|
||||
priority?: MessagePriority
|
||||
expiresIn?: number
|
||||
} = {}
|
||||
): Promise<string> {
|
||||
return this.sendMessage(senderId, channel, payload, {
|
||||
...options,
|
||||
type: MessageType.BROADCAST
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送跨应用消息
|
||||
*/
|
||||
async sendCrossAppMessage(
|
||||
senderId: string,
|
||||
receiverId: string,
|
||||
payload: any,
|
||||
options: {
|
||||
priority?: MessagePriority
|
||||
expiresIn?: number
|
||||
} = {}
|
||||
): Promise<string> {
|
||||
const channel = 'cross-app'
|
||||
|
||||
return this.sendMessage(senderId, channel, payload, {
|
||||
...options,
|
||||
receiverId,
|
||||
type: MessageType.CROSS_APP
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息历史
|
||||
*/
|
||||
getMessageHistory(
|
||||
appId: string,
|
||||
options: {
|
||||
channel?: string
|
||||
limit?: number
|
||||
since?: Date
|
||||
} = {}
|
||||
): EventMessage[] {
|
||||
const history = this.messageHistory.get(appId) || []
|
||||
|
||||
let filtered = history.filter((msg) => msg.senderId === appId || msg.receiverId === appId)
|
||||
|
||||
if (options.channel) {
|
||||
filtered = filtered.filter((msg) => msg.channel === options.channel)
|
||||
}
|
||||
|
||||
if (options.since) {
|
||||
filtered = filtered.filter((msg) => msg.timestamp >= options.since!)
|
||||
}
|
||||
|
||||
if (options.limit) {
|
||||
filtered = filtered.slice(-options.limit)
|
||||
}
|
||||
|
||||
return filtered.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime())
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用的订阅列表
|
||||
*/
|
||||
getAppSubscriptions(appId: string): EventSubscriber[] {
|
||||
return Array.from(this.subscribers.values()).filter((sub) => sub.appId === appId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取频道订阅者数量
|
||||
*/
|
||||
getChannelSubscriberCount(channel: string): number {
|
||||
return Array.from(this.subscribers.values()).filter(
|
||||
(sub) => sub.channel === channel && sub.active
|
||||
).length
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建通信频道
|
||||
*/
|
||||
createChannel(channel: string, config: Omit<CommunicationChannel, 'name'>): boolean {
|
||||
if (this.channels.has(channel)) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.channels.set(channel, {
|
||||
name: channel,
|
||||
...config
|
||||
})
|
||||
|
||||
console.log(`创建通信频道: ${channel}`)
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除通信频道
|
||||
*/
|
||||
deleteChannel(channel: string): boolean {
|
||||
// 移除所有相关订阅
|
||||
const subscribersToRemove = Array.from(this.subscribers.entries())
|
||||
.filter(([, sub]) => sub.channel === channel)
|
||||
.map(([id]) => id)
|
||||
|
||||
subscribersToRemove.forEach((id) => this.unsubscribe(id))
|
||||
|
||||
// 删除频道
|
||||
const result = this.channels.delete(channel)
|
||||
|
||||
if (result) {
|
||||
console.log(`删除通信频道: ${channel}`)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取统计信息
|
||||
*/
|
||||
getStatistics(): EventStatistics {
|
||||
return { ...this.statistics }
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理过期消息和订阅
|
||||
*/
|
||||
cleanup(): void {
|
||||
const now = new Date()
|
||||
|
||||
// 清理过期消息
|
||||
for (const [appId, messages] of this.messageQueue.entries()) {
|
||||
const validMessages = messages.filter((msg) => !msg.expiresAt || msg.expiresAt > now)
|
||||
|
||||
if (validMessages.length !== messages.length) {
|
||||
this.messageQueue.set(appId, validMessages)
|
||||
}
|
||||
}
|
||||
|
||||
// 清理消息历史(保留最近7天)
|
||||
const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)
|
||||
for (const [appId, history] of this.messageHistory.entries()) {
|
||||
const recentHistory = history.filter((msg) => msg.timestamp > sevenDaysAgo)
|
||||
this.messageHistory.set(appId, recentHistory)
|
||||
}
|
||||
|
||||
console.log('事件通信服务清理完成')
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁服务
|
||||
*/
|
||||
destroy(): void {
|
||||
if (this.processingInterval) {
|
||||
cancelAnimationFrame(this.processingInterval)
|
||||
this.processingInterval = null
|
||||
}
|
||||
|
||||
this.subscribers.clear()
|
||||
this.messageQueue.clear()
|
||||
this.messageHistory.clear()
|
||||
this.channels.clear()
|
||||
|
||||
console.log('事件通信服务已销毁')
|
||||
}
|
||||
|
||||
// 私有方法
|
||||
|
||||
/**
|
||||
* 初始化默认频道
|
||||
*/
|
||||
private initializeDefaultChannels(): void {
|
||||
// 系统事件频道
|
||||
this.createChannel('system', {
|
||||
description: '系统级事件通信',
|
||||
restricted: true,
|
||||
allowedApps: ['system'],
|
||||
maxMessageSize: 1024 * 10, // 10KB
|
||||
messageRetention: 24 * 60 * 60 * 1000 // 24小时
|
||||
})
|
||||
|
||||
// 应用间通信频道
|
||||
this.createChannel('cross-app', {
|
||||
description: '应用间通信',
|
||||
restricted: false,
|
||||
allowedApps: [],
|
||||
maxMessageSize: 1024 * 100, // 100KB
|
||||
messageRetention: 7 * 24 * 60 * 60 * 1000 // 7天
|
||||
})
|
||||
|
||||
// 用户交互频道
|
||||
this.createChannel('user-interaction', {
|
||||
description: '用户交互事件',
|
||||
restricted: false,
|
||||
allowedApps: [],
|
||||
maxMessageSize: 1024 * 5, // 5KB
|
||||
messageRetention: 60 * 60 * 1000 // 1小时
|
||||
})
|
||||
|
||||
// 广播频道
|
||||
this.createChannel('broadcast', {
|
||||
description: '系统广播',
|
||||
restricted: true,
|
||||
allowedApps: ['system'],
|
||||
maxMessageSize: 1024 * 50, // 50KB
|
||||
messageRetention: 24 * 60 * 60 * 1000 // 24小时
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查应用是否可以访问频道
|
||||
*/
|
||||
private canAccessChannel(appId: string, channel: string): boolean {
|
||||
const channelConfig = this.channels.get(channel)
|
||||
|
||||
if (!channelConfig) {
|
||||
// 频道不存在,默认允许
|
||||
return true
|
||||
}
|
||||
|
||||
if (!channelConfig.restricted) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 系统应用总是有权限
|
||||
if (appId === 'system') {
|
||||
return true
|
||||
}
|
||||
|
||||
return channelConfig.allowedApps.includes(appId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加消息到队列
|
||||
*/
|
||||
private addToQueue(message: EventMessage): void {
|
||||
const queueKey = message.receiverId || 'broadcast'
|
||||
|
||||
if (!this.messageQueue.has(queueKey)) {
|
||||
this.messageQueue.set(queueKey, [])
|
||||
}
|
||||
|
||||
const queue = this.messageQueue.get(queueKey)!
|
||||
|
||||
// 按优先级插入
|
||||
const insertIndex = queue.findIndex((msg) => msg.priority < message.priority)
|
||||
if (insertIndex === -1) {
|
||||
queue.push(message)
|
||||
} else {
|
||||
queue.splice(insertIndex, 0, message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接投递消息
|
||||
*/
|
||||
private async deliverMessage(message: EventMessage): Promise<void> {
|
||||
try {
|
||||
const subscribers = this.getRelevantSubscribers(message)
|
||||
|
||||
if (subscribers.length === 0) {
|
||||
message.status = MessageStatus.FAILED
|
||||
// 只对非系统频道显示警告信息
|
||||
if (message.channel !== 'system') {
|
||||
console.warn(
|
||||
`[EventCommunication] 没有找到频道 ${message.channel} 的订阅者[消息 ID: ${message.id}]`
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 并行发送给所有订阅者
|
||||
const deliveryPromises = subscribers.map(async (subscriber) => {
|
||||
try {
|
||||
// 应用过滤器
|
||||
if (subscriber.filter && !subscriber.filter(message)) {
|
||||
return
|
||||
}
|
||||
|
||||
await subscriber.handler(message)
|
||||
this.statistics.totalMessagesReceived++
|
||||
console.log(
|
||||
`[EventCommunication] 消息 ${message.id} 已投递给订阅者 ${subscriber.id}[频道: ${message.channel}]`
|
||||
)
|
||||
} catch (error) {
|
||||
console.error(`向订阅者 ${subscriber.id} 发送消息失败:`, error)
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
await Promise.allSettled(deliveryPromises)
|
||||
message.status = MessageStatus.DELIVERED
|
||||
} catch (error) {
|
||||
message.status = MessageStatus.FAILED
|
||||
this.statistics.failedMessages++
|
||||
console.error('消息投递失败:', error)
|
||||
|
||||
// 重试机制
|
||||
if (message.retryCount < message.maxRetries) {
|
||||
message.retryCount++
|
||||
message.status = MessageStatus.PENDING
|
||||
setTimeout(() => this.deliverMessage(message), 1000 * message.retryCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取相关订阅者
|
||||
*/
|
||||
private getRelevantSubscribers(message: EventMessage): EventSubscriber[] {
|
||||
return Array.from(this.subscribers.values()).filter((subscriber) => {
|
||||
if (!subscriber.active) return false
|
||||
if (subscriber.channel !== message.channel) return false
|
||||
|
||||
// 点对点消息检查接收者
|
||||
if (message.receiverId && subscriber.appId !== message.receiverId) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始消息处理循环
|
||||
*/
|
||||
private startMessageProcessing(): void {
|
||||
const processFrame = (timestamp: number) => {
|
||||
// 如果距离上次处理时间超过设定间隔,则处理消息
|
||||
if (timestamp - this.lastProcessTime >= this.processInterval) {
|
||||
this.processMessageQueue()
|
||||
this.cleanupExpiredMessages()
|
||||
this.lastProcessTime = timestamp
|
||||
}
|
||||
|
||||
// 继续下一帧
|
||||
this.processingInterval = requestAnimationFrame(processFrame)
|
||||
}
|
||||
|
||||
// 启动处理循环
|
||||
this.processingInterval = requestAnimationFrame(processFrame)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理消息队列
|
||||
*/
|
||||
private processMessageQueue(): void {
|
||||
for (const [queueKey, messages] of this.messageQueue.entries()) {
|
||||
if (messages.length === 0) continue
|
||||
|
||||
// 处理优先级最高的消息
|
||||
const message = messages.shift()!
|
||||
|
||||
// 检查消息是否过期
|
||||
if (message.expiresAt && message.expiresAt <= new Date()) {
|
||||
message.status = MessageStatus.EXPIRED
|
||||
continue
|
||||
}
|
||||
|
||||
this.deliverMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理过期消息
|
||||
*/
|
||||
private cleanupExpiredMessages(): void {
|
||||
const now = new Date()
|
||||
|
||||
for (const [queueKey, messages] of this.messageQueue.entries()) {
|
||||
const validMessages = messages.filter((msg) => !msg.expiresAt || msg.expiresAt > now)
|
||||
|
||||
if (validMessages.length !== messages.length) {
|
||||
this.messageQueue.set(queueKey, validMessages)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录消息历史
|
||||
*/
|
||||
private recordMessage(message: EventMessage): void {
|
||||
// 记录发送者历史
|
||||
if (!this.messageHistory.has(message.senderId)) {
|
||||
this.messageHistory.set(message.senderId, [])
|
||||
}
|
||||
this.messageHistory.get(message.senderId)!.push(message)
|
||||
|
||||
// 记录接收者历史
|
||||
if (message.receiverId && message.receiverId !== message.senderId) {
|
||||
if (!this.messageHistory.has(message.receiverId)) {
|
||||
this.messageHistory.set(message.receiverId, [])
|
||||
}
|
||||
this.messageHistory.get(message.receiverId)!.push(message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新活跃订阅者数量
|
||||
*/
|
||||
private updateActiveSubscribersCount(): void {
|
||||
this.statistics.activeSubscribers = Array.from(this.subscribers.values()).filter(
|
||||
(sub) => sub.active
|
||||
).length
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,11 @@
|
||||
import { reactive, ref } from 'vue'
|
||||
import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl'
|
||||
import type { IEventBuilder } from '@/events/IEventBuilder'
|
||||
import type {
|
||||
EventCommunicationEvents,
|
||||
WindowFormDataUpdateParams
|
||||
} from './EventCommunicationService'
|
||||
import type { IEventBuilder, IEventMap, WindowFormDataUpdateParams } from '@/events/IEventBuilder'
|
||||
import type { ResourceType } from './ResourceService'
|
||||
|
||||
// 导入所有服务
|
||||
import { WindowService } from './WindowService'
|
||||
import { ResourceService } from './ResourceService'
|
||||
import { EventCommunicationService } from './EventCommunicationService'
|
||||
import { ApplicationSandboxEngine } from './ApplicationSandboxEngine'
|
||||
import { ApplicationLifecycleManager } from './ApplicationLifecycleManager'
|
||||
import { externalAppDiscovery } from './ExternalAppDiscovery'
|
||||
@@ -33,7 +28,6 @@ export interface SystemStatus {
|
||||
servicesStatus: {
|
||||
windowService: boolean // 窗体服务是否启动
|
||||
resourceService: boolean // 资源服务是否启动
|
||||
eventService: boolean // 事件服务是否启动
|
||||
sandboxEngine: boolean // 沙箱引擎是否启动
|
||||
lifecycleManager: boolean // 生命周期管理器是否启动
|
||||
}
|
||||
@@ -62,10 +56,9 @@ export class SystemServiceIntegration {
|
||||
private startTime: Date
|
||||
|
||||
// 核心服务实例
|
||||
private eventBus: IEventBuilder<EventCommunicationEvents>
|
||||
private eventBus: IEventBuilder<any>
|
||||
private windowService!: WindowService
|
||||
private resourceService!: ResourceService
|
||||
private eventService!: EventCommunicationService
|
||||
private sandboxEngine!: ApplicationSandboxEngine
|
||||
private lifecycleManager!: ApplicationLifecycleManager
|
||||
|
||||
@@ -76,7 +69,6 @@ export class SystemServiceIntegration {
|
||||
servicesStatus: {
|
||||
windowService: false,
|
||||
resourceService: false,
|
||||
eventService: false,
|
||||
sandboxEngine: false,
|
||||
lifecycleManager: false
|
||||
},
|
||||
@@ -96,7 +88,7 @@ export class SystemServiceIntegration {
|
||||
}
|
||||
|
||||
this.startTime = new Date()
|
||||
this.eventBus = new EventBuilderImpl<EventCommunicationEvents>()
|
||||
this.eventBus = new EventBuilderImpl<any>()
|
||||
|
||||
this.setupGlobalErrorHandling()
|
||||
}
|
||||
@@ -104,7 +96,7 @@ export class SystemServiceIntegration {
|
||||
/**
|
||||
* 初始化系统服务
|
||||
*/
|
||||
async initialize(): Promise<void> {
|
||||
private async initialize(): Promise<void> {
|
||||
if (this.initialized.value) {
|
||||
throw new Error('系统服务已初始化')
|
||||
}
|
||||
@@ -138,12 +130,6 @@ export class SystemServiceIntegration {
|
||||
this.systemStatus.running = true
|
||||
|
||||
console.log('系统服务初始化完成')
|
||||
|
||||
// 发送系统就绪事件
|
||||
this.eventService.sendMessage('system', 'system-ready', {
|
||||
timestamp: new Date(),
|
||||
services: Object.keys(this.systemStatus.servicesStatus)
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('系统服务初始化失败:', error)
|
||||
this.systemStatus.lastError = error instanceof Error ? error.message : String(error)
|
||||
@@ -174,14 +160,6 @@ export class SystemServiceIntegration {
|
||||
return this.resourceService
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取事件服务
|
||||
*/
|
||||
getEventService(): EventCommunicationService {
|
||||
this.checkInitialized()
|
||||
return this.eventService
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取沙箱引擎
|
||||
*/
|
||||
@@ -243,7 +221,7 @@ export class SystemServiceIntegration {
|
||||
/**
|
||||
* 关闭系统服务
|
||||
*/
|
||||
async shutdown(): Promise<void> {
|
||||
private async shutdown(): Promise<void> {
|
||||
console.log('关闭系统服务...')
|
||||
|
||||
this.running.value = false
|
||||
@@ -277,10 +255,6 @@ export class SystemServiceIntegration {
|
||||
this.sandboxEngine.destroy()
|
||||
}
|
||||
|
||||
if (this.eventService) {
|
||||
this.eventService.destroy()
|
||||
}
|
||||
|
||||
if (this.windowService) {
|
||||
// 关闭所有窗体
|
||||
const windows = this.windowService.getAllWindows()
|
||||
@@ -307,11 +281,6 @@ export class SystemServiceIntegration {
|
||||
this.resourceService = new ResourceService(this.eventBus)
|
||||
this.systemStatus.servicesStatus.resourceService = true
|
||||
|
||||
// 2. 初始化事件通信服务
|
||||
console.log('初始化事件通信服务...')
|
||||
this.eventService = new EventCommunicationService(this.eventBus)
|
||||
this.systemStatus.servicesStatus.eventService = true
|
||||
|
||||
// 3. 初始化窗体服务
|
||||
console.log('初始化窗体服务...')
|
||||
this.windowService = new WindowService(this.eventBus)
|
||||
@@ -319,7 +288,7 @@ export class SystemServiceIntegration {
|
||||
|
||||
// 4. 初始化沙箱引擎
|
||||
console.log('初始化沙箱引擎...')
|
||||
this.sandboxEngine = new ApplicationSandboxEngine(this.resourceService, this.eventService)
|
||||
this.sandboxEngine = new ApplicationSandboxEngine(this.resourceService)
|
||||
this.systemStatus.servicesStatus.sandboxEngine = true
|
||||
|
||||
// 5. 初始化生命周期管理器
|
||||
@@ -327,7 +296,6 @@ export class SystemServiceIntegration {
|
||||
this.lifecycleManager = new ApplicationLifecycleManager(
|
||||
this.windowService,
|
||||
this.resourceService,
|
||||
this.eventService,
|
||||
this.sandboxEngine
|
||||
)
|
||||
this.systemStatus.servicesStatus.lifecycleManager = true
|
||||
@@ -337,16 +305,6 @@ export class SystemServiceIntegration {
|
||||
* 设置服务间通信
|
||||
*/
|
||||
private setupServiceCommunication(): void {
|
||||
// 监听应用生命周期事件
|
||||
this.eventService.subscribe('system', 'app-lifecycle', (message) => {
|
||||
this.debugLog('[AppLifecycle] 应用生命周期事件:', message.payload)
|
||||
})
|
||||
|
||||
// 监听窗口状态变化事件
|
||||
this.eventService.subscribe('system', 'window-state-change', (message) => {
|
||||
this.debugLog('[WindowState] 窗口状态变化消息已处理:', message.payload)
|
||||
})
|
||||
|
||||
// 监听窗体状态变化(来自 WindowService 的 onStateChange 事件)
|
||||
this.eventBus.addEventListener(
|
||||
'onWindowStateChanged',
|
||||
@@ -354,12 +312,6 @@ export class SystemServiceIntegration {
|
||||
console.log(
|
||||
`[SystemIntegration] 接收到窗体状态变化事件: ${windowId} ${oldState} -> ${newState}`
|
||||
)
|
||||
this.eventService.sendMessage('system', 'window-state-change', {
|
||||
windowId,
|
||||
newState,
|
||||
oldState
|
||||
})
|
||||
console.log(`[SystemIntegration] 已发送 window-state-change 消息到事件通信服务`)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -384,13 +336,11 @@ export class SystemServiceIntegration {
|
||||
// 监听窗体数据更新事件
|
||||
this.eventBus.addEventListener('onWindowFormDataUpdate', (data: WindowFormDataUpdateParams) => {
|
||||
console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data)
|
||||
this.eventService.sendMessage('system', 'window-form-data-update', data)
|
||||
})
|
||||
|
||||
// 监听窗体调整尺寸开始事件
|
||||
this.eventBus.addEventListener('onWindowFormResizeStart', (windowId: string) => {
|
||||
console.log(`[SystemIntegration] 接收到窗体调整尺寸开始事件: ${windowId}`)
|
||||
this.eventService.sendMessage('system', 'window-form-resize-start', { windowId })
|
||||
})
|
||||
|
||||
// 监听窗体调整尺寸过程中事件
|
||||
@@ -401,18 +351,12 @@ export class SystemServiceIntegration {
|
||||
width,
|
||||
height
|
||||
})
|
||||
this.eventService.sendMessage('system', 'window-form-resizing', {
|
||||
windowId,
|
||||
width,
|
||||
height
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
// 监听窗体调整尺寸结束事件
|
||||
this.eventBus.addEventListener('onWindowFormResizeEnd', (windowId: string) => {
|
||||
console.log(`[SystemIntegration] 接收到窗体调整尺寸结束事件: ${windowId}`)
|
||||
this.eventService.sendMessage('system', 'window-form-resize-end', { windowId })
|
||||
})
|
||||
}
|
||||
|
||||
@@ -677,35 +621,7 @@ export class SystemServiceIntegration {
|
||||
* 执行事件相关方法
|
||||
*/
|
||||
private async executeEventMethod(action: string, data: any, appId: string): Promise<any> {
|
||||
switch (action) {
|
||||
case 'emit':
|
||||
return this.eventService.sendMessage(appId, data.channel, data.data)
|
||||
|
||||
case 'on':
|
||||
return this.eventService.subscribe(appId, data.channel, (message) => {
|
||||
// 发送事件到应用
|
||||
const app = this.lifecycleManager.getApp(appId)
|
||||
if (app?.sandboxId) {
|
||||
this.sandboxEngine.sendMessage(app.sandboxId, {
|
||||
type: 'system:event',
|
||||
subscriptionId: data.subscriptionId,
|
||||
message
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
case 'off':
|
||||
return this.eventService.unsubscribe(data.subscriptionId)
|
||||
|
||||
case 'broadcast':
|
||||
return this.eventService.broadcast(appId, data.channel, data.data)
|
||||
|
||||
case 'sendTo':
|
||||
return this.eventService.sendCrossAppMessage(appId, data.targetAppId, data.data)
|
||||
|
||||
default:
|
||||
throw new Error(`未知的事件操作: ${action}`)
|
||||
}
|
||||
throw new Error('事件服务已被移除')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -794,11 +710,16 @@ export class SystemServiceIntegration {
|
||||
* 开始自动清理
|
||||
*/
|
||||
private startAutoCleanup(): void {
|
||||
if (!this.config.cleanupInterval) return
|
||||
|
||||
this.cleanupInterval = setInterval(() => {
|
||||
this.debugLog('执行自动清理...')
|
||||
|
||||
// 清理事件服务
|
||||
this.eventService.cleanup()
|
||||
// 移除资源服务清理(方法不存在)
|
||||
// this.resourceService.cleanup()
|
||||
|
||||
// 移除事件服务清理
|
||||
// this.eventService.cleanup()
|
||||
|
||||
// 清理沙箱引擎缓存
|
||||
// this.sandboxEngine.cleanup()
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
<template>
|
||||
<div class="window-manager">
|
||||
<!-- 所有已打开的内置应用窗口 -->
|
||||
<teleport
|
||||
v-for="window in builtInWindows"
|
||||
:key="window.id"
|
||||
:to="`#app-container-${window.appId}`"
|
||||
>
|
||||
<component
|
||||
:is="window.component"
|
||||
:key="window.id"
|
||||
v-bind="window.props"
|
||||
@close="closeWindow(window.id)"
|
||||
/>
|
||||
<teleport v-for="window in builtInWindows" :key="window.id" :to="`#app-container-${window.appId}`">
|
||||
<component :is="window.component" :key="window.id" v-bind="window.props" @close="closeWindow(window.id)" />
|
||||
</teleport>
|
||||
</div>
|
||||
</template>
|
||||
@@ -84,7 +75,7 @@ const closeWindow = (windowId: string) => {
|
||||
const window = builtInWindows.value[index]
|
||||
builtInWindows.value.splice(index, 1)
|
||||
console.log(`[WindowManager] 关闭内置应用窗口: ${window.appId} (${windowId})`)
|
||||
|
||||
|
||||
// 通知系统服务关闭窗口
|
||||
if (systemService) {
|
||||
const windowService = systemService.getWindowService()
|
||||
@@ -103,37 +94,39 @@ const removeBuiltInWindow = (windowId: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 监听窗口事件
|
||||
let eventUnsubscriber: (() => void) | null = null
|
||||
// 移除事件监听相关代码
|
||||
// let eventUnsubscriber: (() => void) | null = null
|
||||
|
||||
onMounted(() => {
|
||||
if (systemService) {
|
||||
const eventService = systemService.getEventService()
|
||||
|
||||
// 监听内置应用窗口创建事件
|
||||
const subscriberId = eventService.subscribe('system', 'built-in-window-created', async (message) => {
|
||||
const { windowId, appId } = message.payload
|
||||
await addBuiltInWindow(windowId, appId)
|
||||
})
|
||||
|
||||
// 监听内置应用窗口关闭事件
|
||||
const closeSubscriberId = eventService.subscribe('system', 'built-in-window-closed', (message) => {
|
||||
const { windowId } = message.payload
|
||||
removeBuiltInWindow(windowId)
|
||||
})
|
||||
|
||||
eventUnsubscriber = () => {
|
||||
eventService.unsubscribe(subscriberId)
|
||||
eventService.unsubscribe(closeSubscriberId)
|
||||
}
|
||||
}
|
||||
})
|
||||
// onMounted(() => {
|
||||
// 移除事件服务相关代码
|
||||
// if (systemService) {
|
||||
// const eventService = systemService.getEventService()
|
||||
|
||||
onUnmounted(() => {
|
||||
if (eventUnsubscriber) {
|
||||
eventUnsubscriber()
|
||||
}
|
||||
})
|
||||
// // 监听内置应用窗口创建事件
|
||||
// const subscriberId = eventService.subscribe('system', 'built-in-window-created', async (message) => {
|
||||
// const { windowId, appId } = message.payload
|
||||
// await addBuiltInWindow(windowId, appId)
|
||||
// })
|
||||
|
||||
// // 监听内置应用窗口关闭事件
|
||||
// const closeSubscriberId = eventService.subscribe('system', 'built-in-window-closed', (message) => {
|
||||
// const { windowId } = message.payload
|
||||
// removeBuiltInWindow(windowId)
|
||||
// })
|
||||
|
||||
// eventUnsubscriber = () => {
|
||||
// eventService.unsubscribe(subscriberId)
|
||||
// eventService.unsubscribe(closeSubscriberId)
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
// onUnmounted(() => {
|
||||
// 移除事件服务相关代码
|
||||
// if (eventUnsubscriber) {
|
||||
// eventUnsubscriber()
|
||||
// }
|
||||
// })
|
||||
|
||||
// 暴露给全局使用
|
||||
defineExpose({
|
||||
|
||||
@@ -52,7 +52,6 @@ const systemStatus = ref<SystemStatus>({
|
||||
servicesStatus: {
|
||||
windowService: false,
|
||||
resourceService: false,
|
||||
eventService: false,
|
||||
sandboxEngine: false,
|
||||
lifecycleManager: false
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user