diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md index b24e1e4..a4b037d 100644 --- a/PROJECT_SUMMARY.md +++ b/PROJECT_SUMMARY.md @@ -1,185 +1,220 @@ -# Vue Desktop - 系统与业务解耦架构 +# Vue Desktop -基于设计文档实现的高性能类Windows桌面前端系统,实现了系统框架与业务应用的完全解耦。 +一个基于 Vue 3 + TypeScript + Vite 的现代化桌面环境模拟器 -## 🎯 项目概述 +## 🎯 项目目标 -本项目成功实现了设计文档中描述的**系统与业务解耦架构**,构建了一个完整的桌面环境模拟系统,包含: +构建一个轻量级、模块化的桌面环境,支持: -- ✅ **完全隔离**:系统与应用在运行时完全隔离,应用无法直接访问系统资源 -- ✅ **标准化接口**:通过统一的SDK提供标准化的系统服务接口 -- ✅ **性能优先**:采用微前端沙箱、虚拟化渲染等技术确保高性能 -- ✅ **框架无关**:支持任意前端框架开发的第三方应用 -- ✅ **安全可控**:严格的权限控制和安全沙箱机制 +- 内置应用(计算器、记事本、待办事项等) +- 外置应用加载(通过 iframe 沙箱) +- 窗口管理(创建、移动、缩放、最小化等) +- 资源管理(存储、权限控制) +- 应用生命周期管理 +- 安全沙箱机制 ## 🏗️ 架构实现 ### 核心服务层 + - **[WindowService](./src/services/WindowService.ts)** - 窗体管理服务,支持完整的窗体生命周期 - **[ResourceService](./src/services/ResourceService.ts)** - 资源管理服务,提供权限控制和资源访问 -- **[EventCommunicationService](./src/services/EventCommunicationService.ts)** - 事件通信服务,支持跨应用消息传递 - **[ApplicationSandboxEngine](./src/services/ApplicationSandboxEngine.ts)** - 应用沙箱引擎,多层安全隔离 - **[ApplicationLifecycleManager](./src/services/ApplicationLifecycleManager.ts)** - 应用生命周期管理 - **[SystemServiceIntegration](./src/services/SystemServiceIntegration.ts)** - 系统服务集成层 ### SDK接口层 -- **[SDK类型定义](./src/sdk/types.ts)** - 完整的TypeScript接口定义 -- **[SDK实现](./src/sdk/index.ts)** - 统一的SDK实现,提供标准化API -### 应用层 -- **内置应用**:计算器、记事本、系统状态监控 -- **第三方应用**:[待办事项应用](./public/apps/todo/index.html)示例 +- **[SystemSDK](./src/sdk/index.ts)** - 统一SDK接口,为应用提供系统能力访问 -## 🚀 快速开始 +### 事件系统 -### 环境要求 -- Node.js >= 20.19.0 -- pnpm +- **[IEventBuilder](./src/events/IEventBuilder.ts)** - 事件总线接口 +- **[EventBuilderImpl](./src/events/impl/EventBuilderImpl.ts)** - 事件总线实现 -### 安装与运行 -```bash -# 安装依赖 -pnpm install +### 应用管理 -# 启动开发服务器 -pnpm dev - -# 构建生产版本 -pnpm build -``` - -### 访问应用 -- 开发环境:http://localhost:5174/ -- 生产环境:部署后的域名 - -## 🎮 使用说明 - -### 桌面交互 -1. **双击图标**启动应用 -2. **拖拽图标**重新排列桌面布局 -3. **右键菜单**访问系统功能(计划中) - -### 内置应用 -- **🧮 计算器**:基础的数学计算功能 -- **📝 记事本**:文本编辑和文件保存 -- **⚙️ 系统状态**:实时系统性能监控 -- **✓ 待办事项**:完整的任务管理应用 - -### 窗体操作 -- **最小化/最大化/还原**:标准窗体控制 -- **拖拽移动**:通过标题栏拖拽窗体 -- **调整大小**:支持窗体尺寸调整(计划中) - -## 🔧 技术特性 - -### 系统架构特性 -- **微前端架构**:每个应用运行在独立的沙箱中 -- **事件驱动**:基于发布订阅模式的事件通信 -- **权限控制**:细粒度的资源访问权限管理 -- **性能监控**:实时的系统和应用性能监控 -- **错误隔离**:应用错误不会影响系统稳定性 - -### 开发特性 -- **TypeScript**:完整的类型安全保障 -- **Vue 3**:现代化的响应式框架 -- **Vite**:快速的构建工具 -- **UnoCSS**:原子化CSS框架 -- **Naive UI**:优雅的UI组件库 +- **[AppRegistry](./src/apps/AppRegistry.ts)** - 应用注册中心 +- **[ExternalAppDiscovery](./src/services/ExternalAppDiscovery.ts)** - 外置应用发现服务 ## 📁 项目结构 ``` -vue-desktop/ -├── src/ -│ ├── services/ # 核心服务层 -│ │ ├── WindowService.ts -│ │ ├── ResourceService.ts -│ │ ├── EventCommunicationService.ts -│ │ ├── ApplicationSandboxEngine.ts +. +├── public\apps +│ ├── music-player +│ │ ├── README.md +│ │ ├── app.js +│ │ ├── index.html +│ │ ├── manifest.json +│ │ └── style.css +│ └── README.md +├── src +│ ├── apps +│ │ ├── calculator +│ │ │ └── Calculator.vue +│ │ ├── components +│ │ │ └── BuiltInApp.vue +│ │ ├── notepad +│ │ │ └── Notepad.vue +│ │ ├── todo +│ │ │ └── Todo.vue +│ │ ├── types +│ │ │ └── AppManifest.ts +│ │ ├── AppRegistry.ts +│ │ └── index.ts +│ ├── common +│ │ ├── hooks +│ │ │ ├── useClickFocus.ts +│ │ │ └── useObservableVue.ts +│ │ ├── naive-ui +│ │ │ ├── components.ts +│ │ │ ├── discrete-api.ts +│ │ │ └── theme.ts +│ │ └── types +│ │ ├── IDestroyable.ts +│ │ └── IVersion.ts +│ ├── css +│ │ └── basic.css +│ ├── events +│ │ ├── impl +│ │ │ └── EventBuilderImpl.ts +│ │ └── IEventBuilder.ts +│ ├── sdk +│ │ ├── index.ts +│ │ └── types.ts +│ ├── services │ │ ├── ApplicationLifecycleManager.ts -│ │ └── SystemServiceIntegration.ts -│ ├── sdk/ # SDK接口层 -│ │ ├── types.ts # 类型定义 -│ │ └── index.ts # SDK实现 -│ ├── ui/ # 用户界面 -│ │ ├── desktop-container/ +│ │ ├── ApplicationSandboxEngine.ts +│ │ ├── ExternalAppDiscovery.ts +│ │ ├── ResourceService.ts +│ │ ├── SystemServiceIntegration.ts +│ │ └── WindowService.ts +│ ├── stores +│ │ └── counter.ts +│ ├── ui +│ │ ├── components +│ │ │ ├── AppRenderer.vue +│ │ │ └── WindowManager.vue +│ │ ├── desktop-container +│ │ │ ├── AppIcon.vue +│ │ │ ├── DesktopContainer.vue +│ │ │ ├── useDesktopContainerInit.ts +│ │ │ └── useDynamicAppIcons.ts +│ │ ├── types +│ │ │ ├── IDesktopAppIcon.ts +│ │ │ ├── IGridTemplateParams.ts +│ │ │ └── WindowFormTypes.ts │ │ └── App.vue -│ ├── events/ # 事件系统 -│ ├── stores/ # 状态管理 -│ └── main.ts # 应用入口 -├── public/ -│ └── apps/ # 第三方应用 -│ └── todo/ # 待办事项应用 -└── README.md +│ └── main.ts +├── PRETTIER_CONFIG_GUIDE.md +├── PROJECT_SUMMARY.md +├── README.md +├── env.d.ts +├── index.html +├── package.json +├── pnpm-lock.yaml +├── tsconfig.app.json +├── tsconfig.json +├── tsconfig.node.json +├── uno.config.ts +└── vite.config.ts ``` -## 🔒 安全机制 +## 🚀 快速开始 -### 沙箱隔离 -- **iframe隔离**:每个应用运行在独立的iframe中 -- **CSP策略**:严格的内容安全策略 -- **权限控制**:基于白名单的权限管理 -- **API代理**:所有系统调用通过SDK代理 +### 环境要求 -### 权限模型 -- **存储权限**:应用独立的存储空间 -- **网络权限**:基于域名白名单的网络访问 -- **通知权限**:用户确认的通知功能 -- **剪贴板权限**:受控的剪贴板访问 +- Node.js >= 16.0.0 +- pnpm >= 7.0.0 -## 📊 性能优化 +### 安装依赖 -### 渲染优化 -- **虚拟化布局**:高效的图标网格布局 -- **按需加载**:应用按需动态加载 -- **内存管理**:智能的内存回收机制 -- **性能监控**:实时的性能指标收集 +```bash +pnpm install +``` -### 系统优化 -- **事件节流**:防止事件风暴 -- **资源缓存**:智能的资源缓存策略 -- **自动清理**:定期的系统资源清理 -- **错误恢复**:优雅的错误处理和恢复 +### 开发模式 -## 🔮 未来规划 +```bash +pnpm dev +``` -### 短期计划 -- [ ] 窗体拖拽和调整大小功能 -- [ ] 右键菜单和快捷方式 -- [ ] 更多内置应用(文件管理器、浏览器等) -- [ ] 应用商店和在线安装 +### 构建生产版本 -### 长期计划 -- [ ] 多桌面和工作区 -- [ ] 插件系统和扩展机制 -- [ ] 云同步和备份 -- [ ] 移动端适配 +```bash +pnpm build +``` -## 🤝 贡献指南 +### 预览生产构建 -欢迎贡献代码、报告bug或提出功能建议! +```bash +pnpm preview +``` -### 开发流程 -1. Fork项目 -2. 创建功能分支 (`git checkout -b feature/AmazingFeature`) -3. 提交更改 (`git commit -m 'Add some AmazingFeature'`) -4. 推送到分支 (`git push origin feature/AmazingFeature`) -5. 创建Pull Request +## 🛠️ 开发指南 -### 代码规范 -- 使用TypeScript进行类型安全 -- 遵循Vue 3组合式API最佳实践 -- 使用ESLint和Prettier保持代码风格一致 -- 为新功能编写测试用例 +### 添加内置应用 -## 📄 许可证 +1. 在 `src/apps/` 目录下创建应用文件夹 +2. 创建 Vue 组件文件(如 `MyApp.vue`) +3. 在 `src/apps/AppRegistry.ts` 中注册应用 -本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。 +### 添加外置应用 -## 🙏 致谢 +1. 在 `public/apps/` 目录下创建应用文件夹 +2. 添加 `manifest.json` 应用清单文件 +3. 添加应用的 HTML/CSS/JS 文件 +4. 系统会自动发现并加载该应用 -感谢所有参与项目开发和测试的贡献者,以及提供技术支持的开源社区。 +### 系统服务使用 ---- +通过依赖注入获取系统服务: -**Vue Desktop** - 让Web应用拥有桌面应用的体验 🚀 \ No newline at end of file +```typescript +import type { SystemServiceIntegration } from '@/services/SystemServiceIntegration' +const systemService = inject('systemService') +``` + +可用服务: + +- `getWindowService()` - 窗体服务 +- `getResourceService()` - 资源服务 +- `getSandboxEngine()` - 沙箱引擎 +- `getLifecycleManager()` - 生命周期管理器 + +## 📖 技术文档 + +### 窗体系统 + +窗体系统支持完整的生命周期管理,包括创建、移动、缩放、最小化、最大化等操作。 + +### 资源管理 + +资源服务提供安全的存储访问和权限控制机制。 + +### 沙箱安全 + +应用沙箱引擎提供多层安全隔离,防止恶意代码访问系统资源。 + +### 应用生命周期 + +应用生命周期管理器负责应用的安装、启动、停止、卸载等操作。 + +## 🧪 测试 + +### 单元测试 + +```bash +pnpm test +``` + +### 端到端测试 + +```bash +pnpm test:e2e +``` + +## 📦 部署 + +构建产物可直接部署到任何静态文件服务器上。 diff --git a/src/apps/calculator/Calculator.vue b/src/apps/calculator/Calculator.vue index c569f74..b010a79 100644 --- a/src/apps/calculator/Calculator.vue +++ b/src/apps/calculator/Calculator.vue @@ -2,40 +2,34 @@
- +
- +
- + - + - + - + @@ -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; } diff --git a/src/apps/components/BuiltInApp.vue b/src/apps/components/BuiltInApp.vue index c09056c..7228688 100644 --- a/src/apps/components/BuiltInApp.vue +++ b/src/apps/components/BuiltInApp.vue @@ -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) { diff --git a/src/events/IEventBuilder.ts b/src/events/IEventBuilder.ts index 9e290b7..cdc0af6 100644 --- a/src/events/IEventBuilder.ts +++ b/src/events/IEventBuilder.ts @@ -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 extends IDestroyable { immediate?: boolean immediateArgs?: Parameters once?: boolean - }, + } ): void /** @@ -46,5 +84,8 @@ export interface IEventBuilder extends IDestroyable { * @param args 参数 * @returns void */ - notifyEvent(eventName: E, ...args: Parameters): void -} \ No newline at end of file + notifyEvent( + eventName: E, + ...args: Parameters + ): void +} diff --git a/src/services/ApplicationLifecycleManager.ts b/src/services/ApplicationLifecycleManager.ts index e7dc306..54446c8 100644 --- a/src/services/ApplicationLifecycleManager.ts +++ b/src/services/ApplicationLifecycleManager.ts @@ -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 { - 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: `` - }) - - // 提供系统服务(使用当前实例所在的系统服务) - 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 + // }) } } diff --git a/src/services/ApplicationSandboxEngine.ts b/src/services/ApplicationSandboxEngine.ts index 6322557..37758f3 100644 --- a/src/services/ApplicationSandboxEngine.ts +++ b/src/services/ApplicationSandboxEngine.ts @@ -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()) 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 + // }) } } diff --git a/src/services/EventCommunicationService.ts b/src/services/EventCommunicationService.ts deleted file mode 100644 index 4f7a69c..0000000 --- a/src/services/EventCommunicationService.ts +++ /dev/null @@ -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 - /** 消息过滤器 */ - 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 -} - -/** - * 窗体数据更新参数 - */ -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()) - private messageQueue = reactive(new Map()) // 按应用分组的消息队列 - private messageHistory = reactive(new Map()) // 消息历史记录 - private channels = reactive(new Map()) - private statistics = reactive({ - 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 - - constructor(eventBus: IEventBuilder) { - this.eventBus = eventBus - this.initializeDefaultChannels() - this.startMessageProcessing() - } - - /** - * 订阅事件频道 - */ - subscribe( - appId: string, - channel: string, - handler: (message: EventMessage) => void | Promise, - 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 { - 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 { - return this.sendMessage(senderId, channel, payload, { - ...options, - type: MessageType.BROADCAST - }) - } - - /** - * 发送跨应用消息 - */ - async sendCrossAppMessage( - senderId: string, - receiverId: string, - payload: any, - options: { - priority?: MessagePriority - expiresIn?: number - } = {} - ): Promise { - 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): 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 { - 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 - } -} diff --git a/src/services/SystemServiceIntegration.ts b/src/services/SystemServiceIntegration.ts index 8c475eb..db5b825 100644 --- a/src/services/SystemServiceIntegration.ts +++ b/src/services/SystemServiceIntegration.ts @@ -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 + private eventBus: IEventBuilder 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() + this.eventBus = new EventBuilderImpl() this.setupGlobalErrorHandling() } @@ -104,7 +96,7 @@ export class SystemServiceIntegration { /** * 初始化系统服务 */ - async initialize(): Promise { + private async initialize(): Promise { 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 { + private async shutdown(): Promise { 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 { - 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() diff --git a/src/ui/components/WindowManager.vue b/src/ui/components/WindowManager.vue index 23d3c8e..d826645 100644 --- a/src/ui/components/WindowManager.vue +++ b/src/ui/components/WindowManager.vue @@ -1,17 +1,8 @@ @@ -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({ diff --git a/src/ui/desktop-container/DesktopContainer.vue b/src/ui/desktop-container/DesktopContainer.vue index efbb3b3..041ae6a 100644 --- a/src/ui/desktop-container/DesktopContainer.vue +++ b/src/ui/desktop-container/DesktopContainer.vue @@ -52,7 +52,6 @@ const systemStatus = ref({ servicesStatus: { windowService: false, resourceService: false, - eventService: false, sandboxEngine: false, lifecycleManager: false },