优化
This commit is contained in:
@@ -23,9 +23,10 @@ export class AppRegistry {
|
||||
*/
|
||||
registerApp(registration: AppRegistration): void {
|
||||
// 使用 markRaw 标记组件,避免被设为响应式
|
||||
// 注意:对于异步组件,我们不立即标记为raw,而是在实际加载时处理
|
||||
const safeRegistration = {
|
||||
...registration,
|
||||
component: registration.component ? markRaw(registration.component) : registration.component
|
||||
component: registration.component,
|
||||
}
|
||||
this.apps.set(registration.manifest.id, safeRegistration)
|
||||
console.log(`已注册内置应用: ${registration.manifest.name}`)
|
||||
@@ -49,7 +50,7 @@ export class AppRegistry {
|
||||
* 获取所有内置应用
|
||||
*/
|
||||
getBuiltInApps(): AppRegistration[] {
|
||||
return Array.from(this.apps.values()).filter(app => app.isBuiltIn)
|
||||
return Array.from(this.apps.values()).filter((app) => app.isBuiltIn)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,9 +64,7 @@ export class AppRegistry {
|
||||
* 按类别获取应用
|
||||
*/
|
||||
getAppsByCategory(category: string): AppRegistration[] {
|
||||
return Array.from(this.apps.values()).filter(
|
||||
app => app.manifest.category === category
|
||||
)
|
||||
return Array.from(this.apps.values()).filter((app) => app.manifest.category === category)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,14 +72,12 @@ export class AppRegistry {
|
||||
*/
|
||||
searchApps(query: string): AppRegistration[] {
|
||||
const lowercaseQuery = query.toLowerCase()
|
||||
return Array.from(this.apps.values()).filter(app => {
|
||||
return Array.from(this.apps.values()).filter((app) => {
|
||||
const manifest = app.manifest
|
||||
return (
|
||||
manifest.name.toLowerCase().includes(lowercaseQuery) ||
|
||||
manifest.description.toLowerCase().includes(lowercaseQuery) ||
|
||||
manifest.keywords?.some(keyword =>
|
||||
keyword.toLowerCase().includes(lowercaseQuery)
|
||||
)
|
||||
manifest.keywords?.some((keyword) => keyword.toLowerCase().includes(lowercaseQuery))
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -94,4 +91,4 @@ export class AppRegistry {
|
||||
}
|
||||
|
||||
// 导出单例实例
|
||||
export const appRegistry = AppRegistry.getInstance()
|
||||
export const appRegistry = AppRegistry.getInstance()
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { appRegistry } from './AppRegistry'
|
||||
import { markRaw } from 'vue'
|
||||
import Calculator from './calculator/Calculator.vue'
|
||||
import Notepad from './notepad/Notepad.vue'
|
||||
import Todo from './todo/Todo.vue'
|
||||
|
||||
/**
|
||||
* 注册所有内置应用
|
||||
@@ -25,13 +22,17 @@ export function registerBuiltInApps() {
|
||||
minHeight: 480,
|
||||
resizable: true,
|
||||
minimizable: true,
|
||||
maximizable: false
|
||||
maximizable: false,
|
||||
},
|
||||
category: 'utilities',
|
||||
keywords: ['计算器', '数学', '运算', 'calculator', 'math']
|
||||
keywords: ['计算器', '数学', '运算', 'calculator', 'math'],
|
||||
},
|
||||
component: markRaw(Calculator),
|
||||
isBuiltIn: true
|
||||
// 使用动态导入实现懒加载
|
||||
component: async () => {
|
||||
const { default: Calculator } = await import('./calculator/Calculator.vue')
|
||||
return markRaw(Calculator)
|
||||
},
|
||||
isBuiltIn: true,
|
||||
})
|
||||
|
||||
// 注册记事本应用
|
||||
@@ -49,13 +50,17 @@ export function registerBuiltInApps() {
|
||||
height: 600,
|
||||
minWidth: 400,
|
||||
minHeight: 300,
|
||||
resizable: true
|
||||
resizable: true,
|
||||
},
|
||||
category: 'productivity',
|
||||
keywords: ['记事本', '文本编辑', '笔记', 'notepad', 'text', 'editor']
|
||||
keywords: ['记事本', '文本编辑', '笔记', 'notepad', 'text', 'editor'],
|
||||
},
|
||||
component: markRaw(Notepad),
|
||||
isBuiltIn: true
|
||||
// 使用动态导入实现懒加载
|
||||
component: async () => {
|
||||
const { default: Notepad } = await import('./notepad/Notepad.vue')
|
||||
return markRaw(Notepad)
|
||||
},
|
||||
isBuiltIn: true,
|
||||
})
|
||||
|
||||
// 注册待办事项应用
|
||||
@@ -73,13 +78,17 @@ export function registerBuiltInApps() {
|
||||
height: 700,
|
||||
minWidth: 400,
|
||||
minHeight: 500,
|
||||
resizable: true
|
||||
resizable: true,
|
||||
},
|
||||
category: 'productivity',
|
||||
keywords: ['待办事项', '任务管理', 'todo', 'task', 'productivity']
|
||||
keywords: ['待办事项', '任务管理', 'todo', 'task', 'productivity'],
|
||||
},
|
||||
component: markRaw(Todo),
|
||||
isBuiltIn: true
|
||||
// 使用动态导入实现懒加载
|
||||
component: async () => {
|
||||
const { default: Todo } = await import('./todo/Todo.vue')
|
||||
return markRaw(Todo)
|
||||
},
|
||||
isBuiltIn: true,
|
||||
})
|
||||
|
||||
console.log('内置应用注册完成')
|
||||
@@ -87,4 +96,4 @@ export function registerBuiltInApps() {
|
||||
|
||||
// 导出应用注册中心
|
||||
export { appRegistry } from './AppRegistry'
|
||||
export type { InternalAppManifest, AppRegistration } from './types/AppManifest'
|
||||
export type { InternalAppManifest, AppRegistration } from './types/AppManifest'
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/**
|
||||
* 内置应用清单接口
|
||||
*/
|
||||
/**
|
||||
* 内置应用清单接口
|
||||
*/
|
||||
@@ -88,9 +85,6 @@ export interface InternalAppManifest {
|
||||
keywords?: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用注册信息
|
||||
*/
|
||||
/**
|
||||
* 应用注册信息
|
||||
*/
|
||||
@@ -100,11 +94,11 @@ export interface AppRegistration {
|
||||
*/
|
||||
manifest: InternalAppManifest
|
||||
/**
|
||||
* Vue组件
|
||||
* Vue组件或异步加载函数
|
||||
*/
|
||||
component: any // Vue组件
|
||||
component: any // Vue组件或返回Promise<Vue组件>的函数
|
||||
/**
|
||||
* 是否为内置应用
|
||||
*/
|
||||
isBuiltIn: boolean
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { reactive, ref } from 'vue'
|
||||
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, type ExternalApp } from './ExternalAppDiscovery'
|
||||
import { externalAppDiscovery } from './ExternalAppDiscovery'
|
||||
|
||||
/**
|
||||
* 应用状态枚举
|
||||
@@ -271,12 +271,29 @@ export class ApplicationLifecycleManager {
|
||||
let app = this.installedApps.get(appId)
|
||||
|
||||
// 如果应用未安装,检查是否为外置应用
|
||||
let isExternalApp = false
|
||||
if (!app) {
|
||||
const externalApp = externalAppDiscovery.getApp(appId)
|
||||
if (externalApp) {
|
||||
console.log(`[LifecycleManager] 发现外置应用 ${appId},自动注册`)
|
||||
await this.registerExternalApp(externalApp)
|
||||
app = this.installedApps.get(appId)
|
||||
console.log(`[LifecycleManager] 发现外置应用 ${appId}`)
|
||||
isExternalApp = true
|
||||
|
||||
// 为外部应用创建临时实例
|
||||
const now = new Date()
|
||||
app = {
|
||||
id: externalApp.manifest.id,
|
||||
manifest: externalApp.manifest,
|
||||
state: AppLifecycleState.INSTALLED,
|
||||
processId: '',
|
||||
installedAt: now,
|
||||
errorCount: 0,
|
||||
crashCount: 0,
|
||||
memoryUsage: 0,
|
||||
cpuUsage: 0,
|
||||
version: externalApp.manifest.version,
|
||||
autoStart: false,
|
||||
persistent: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +313,6 @@ export class ApplicationLifecycleManager {
|
||||
|
||||
// 检查是否为内置应用
|
||||
let isBuiltInApp = false
|
||||
let isExternalApp = false
|
||||
|
||||
try {
|
||||
const { AppRegistry } = await import('../apps/AppRegistry')
|
||||
@@ -306,8 +322,9 @@ export class ApplicationLifecycleManager {
|
||||
console.warn('无法导入 AppRegistry')
|
||||
}
|
||||
|
||||
// 检查是否为外置应用
|
||||
if (!isBuiltInApp) {
|
||||
// 检查是否为外置应用(仅当不是内置应用时)
|
||||
// 修复:移除重复的变量声明,使用已声明的isExternalApp变量
|
||||
if (!isBuiltInApp && !isExternalApp) {
|
||||
isExternalApp = externalAppDiscovery.hasApp(appId)
|
||||
}
|
||||
|
||||
@@ -398,9 +415,21 @@ export class ApplicationLifecycleManager {
|
||||
* 停止应用
|
||||
*/
|
||||
async stopApp(appId: string): Promise<boolean> {
|
||||
const app = this.installedApps.get(appId)
|
||||
// 首先从已安装应用中查找
|
||||
let app = this.installedApps.get(appId)
|
||||
|
||||
// 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例)
|
||||
if (!app) {
|
||||
throw new Error(`应用 ${appId} 未安装`)
|
||||
for (const runningApp of this.runningProcesses.values()) {
|
||||
if (runningApp.id === appId) {
|
||||
app = runningApp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!app) {
|
||||
throw new Error(`应用 ${appId} 未安装或未运行`)
|
||||
}
|
||||
|
||||
if (app.state !== AppLifecycleState.RUNNING && app.state !== AppLifecycleState.SUSPENDED) {
|
||||
@@ -449,7 +478,19 @@ export class ApplicationLifecycleManager {
|
||||
* 暂停应用
|
||||
*/
|
||||
async suspendApp(appId: string): Promise<boolean> {
|
||||
const app = this.installedApps.get(appId)
|
||||
// 首先从已安装应用中查找
|
||||
let app = this.installedApps.get(appId)
|
||||
|
||||
// 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例)
|
||||
if (!app) {
|
||||
for (const runningApp of this.runningProcesses.values()) {
|
||||
if (runningApp.id === appId) {
|
||||
app = runningApp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!app || app.state !== AppLifecycleState.RUNNING) {
|
||||
return false
|
||||
}
|
||||
@@ -481,7 +522,19 @@ export class ApplicationLifecycleManager {
|
||||
* 恢复应用
|
||||
*/
|
||||
async resumeApp(appId: string): Promise<boolean> {
|
||||
const app = this.installedApps.get(appId)
|
||||
// 首先从已安装应用中查找
|
||||
let app = this.installedApps.get(appId)
|
||||
|
||||
// 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例)
|
||||
if (!app) {
|
||||
for (const runningApp of this.runningProcesses.values()) {
|
||||
if (runningApp.id === appId) {
|
||||
app = runningApp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!app || app.state !== AppLifecycleState.SUSPENDED) {
|
||||
return false
|
||||
}
|
||||
@@ -545,7 +598,19 @@ export class ApplicationLifecycleManager {
|
||||
* 检查应用是否正在运行
|
||||
*/
|
||||
isAppRunning(appId: string): boolean {
|
||||
const app = this.installedApps.get(appId)
|
||||
// 首先从已安装应用中查找
|
||||
let app = this.installedApps.get(appId)
|
||||
|
||||
// 如果未找到,从运行进程列表中查找(可能是外部应用的临时实例)
|
||||
if (!app) {
|
||||
for (const runningApp of this.runningProcesses.values()) {
|
||||
if (runningApp.id === appId) {
|
||||
app = runningApp
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return app?.state === AppLifecycleState.RUNNING || app?.state === AppLifecycleState.SUSPENDED
|
||||
}
|
||||
|
||||
@@ -786,44 +851,8 @@ export class ApplicationLifecycleManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册外置应用
|
||||
*/
|
||||
private async registerExternalApp(externalApp: ExternalApp): Promise<void> {
|
||||
try {
|
||||
const { manifest } = externalApp
|
||||
const now = new Date()
|
||||
|
||||
const appInstance: AppInstance = {
|
||||
id: manifest.id,
|
||||
manifest,
|
||||
state: AppLifecycleState.INSTALLED,
|
||||
processId: '',
|
||||
installedAt: now,
|
||||
errorCount: 0,
|
||||
crashCount: 0,
|
||||
memoryUsage: 0,
|
||||
cpuUsage: 0,
|
||||
version: manifest.version,
|
||||
autoStart: false,
|
||||
persistent: false,
|
||||
}
|
||||
|
||||
this.installedApps.set(manifest.id, appInstance)
|
||||
|
||||
console.log(`[LifecycleManager] 外置应用 ${manifest.name} (${manifest.id}) 已自动注册`)
|
||||
|
||||
// 发送应用注册事件
|
||||
this.eventService.sendMessage('system', 'app-lifecycle', {
|
||||
type: 'external-app-registered',
|
||||
appId: manifest.id,
|
||||
manifest,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(`[LifecycleManager] 注册外置应用失败:`, error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
// 已移除:外部应用不再需要注册到 installedApps 中
|
||||
// 外部应用在启动时会创建临时实例
|
||||
|
||||
/**
|
||||
* 为外置应用加载代码到沙箱
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { reactive, ref, nextTick } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import type { ResourceService } from './ResourceService'
|
||||
import type { EventCommunicationService } from './EventCommunicationService'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
@@ -73,6 +73,7 @@ export interface SandboxInstance {
|
||||
cpuUsage: number
|
||||
networkRequests: number
|
||||
errors: string[]
|
||||
messageHandler?: (event: MessageEvent) => void
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,6 +321,12 @@ export class ApplicationSandboxEngine {
|
||||
try {
|
||||
this.updateSandboxState(sandbox, SandboxState.DESTROYED)
|
||||
|
||||
// 移除消息事件监听器
|
||||
if (sandbox.messageHandler) {
|
||||
window.removeEventListener('message', sandbox.messageHandler);
|
||||
sandbox.messageHandler = undefined;
|
||||
}
|
||||
|
||||
// 清理DOM元素
|
||||
if (sandbox.iframe) {
|
||||
sandbox.iframe.remove()
|
||||
@@ -621,11 +628,14 @@ export class ApplicationSandboxEngine {
|
||||
// 这些头部主要用于服务器端设置,在客户端我们通过其他方式实现
|
||||
|
||||
// 监听iframe的消息事件
|
||||
window.addEventListener('message', (event) => {
|
||||
const messageHandler = (event: MessageEvent) => {
|
||||
if (event.source === sandbox.iframe!.contentWindow) {
|
||||
this.handleSandboxMessage(sandbox, event.data)
|
||||
}
|
||||
})
|
||||
};
|
||||
window.addEventListener('message', messageHandler);
|
||||
// 存储事件监听器引用,以便在销毁时移除
|
||||
sandbox.messageHandler = messageHandler;
|
||||
|
||||
// 简化安全限制,主要依赖iframe的sandbox属性
|
||||
sandbox.iframe.addEventListener('load', () => {
|
||||
@@ -855,316 +865,316 @@ export class ApplicationSandboxEngine {
|
||||
return this.wrapResponse(this.sendToSystem('window.getSize'));
|
||||
}
|
||||
}
|
||||
|
||||
// 存储SDK实现
|
||||
class StorageSDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
async set(key, value) {
|
||||
return this.wrapResponse(this.sendToSystem('storage.set', { key, value }));
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
return this.wrapResponse(this.sendToSystem('storage.get', { key }));
|
||||
}
|
||||
|
||||
async remove(key) {
|
||||
return this.wrapResponse(this.sendToSystem('storage.remove', { key }));
|
||||
}
|
||||
|
||||
async clear() {
|
||||
return this.wrapResponse(this.sendToSystem('storage.clear'));
|
||||
}
|
||||
|
||||
async keys() {
|
||||
return this.wrapResponse(this.sendToSystem('storage.keys'));
|
||||
}
|
||||
|
||||
async has(key) {
|
||||
return this.wrapResponse(this.sendToSystem('storage.has', { key }));
|
||||
}
|
||||
|
||||
async getStats() {
|
||||
return this.wrapResponse(this.sendToSystem('storage.getStats'));
|
||||
}
|
||||
|
||||
// 存储SDK实现
|
||||
class StorageSDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
// 网络SDK实现
|
||||
class NetworkSDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
async request(url, config) {
|
||||
return this.wrapResponse(this.sendToSystem('network.request', { url, config }));
|
||||
}
|
||||
|
||||
async get(url, config) {
|
||||
return this.request(url, { ...config, method: 'GET' });
|
||||
}
|
||||
|
||||
async post(url, data, config) {
|
||||
return this.request(url, { ...config, method: 'POST', body: data });
|
||||
}
|
||||
|
||||
async put(url, data, config) {
|
||||
return this.request(url, { ...config, method: 'PUT', body: data });
|
||||
}
|
||||
|
||||
async delete(url, config) {
|
||||
return this.request(url, { ...config, method: 'DELETE' });
|
||||
}
|
||||
async set(key, value) {
|
||||
return this.wrapResponse(this.sendToSystem('storage.set', { key, value }));
|
||||
}
|
||||
|
||||
// 事件SDK实现
|
||||
class EventSDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
async get(key) {
|
||||
return this.wrapResponse(this.sendToSystem('storage.get', { key }));
|
||||
}
|
||||
|
||||
async remove(key) {
|
||||
return this.wrapResponse(this.sendToSystem('storage.remove', { key }));
|
||||
}
|
||||
|
||||
async clear() {
|
||||
return this.wrapResponse(this.sendToSystem('storage.clear'));
|
||||
}
|
||||
|
||||
async keys() {
|
||||
return this.wrapResponse(this.sendToSystem('storage.keys'));
|
||||
}
|
||||
|
||||
async has(key) {
|
||||
return this.wrapResponse(this.sendToSystem('storage.has', { key }));
|
||||
}
|
||||
|
||||
async getStats() {
|
||||
return this.wrapResponse(this.sendToSystem('storage.getStats'));
|
||||
}
|
||||
}
|
||||
|
||||
// 网络SDK实现
|
||||
class NetworkSDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
async request(url, config) {
|
||||
return this.wrapResponse(this.sendToSystem('network.request', { url, config }));
|
||||
}
|
||||
|
||||
async get(url, config) {
|
||||
return this.request(url, { ...config, method: 'GET' });
|
||||
}
|
||||
|
||||
async post(url, data, config) {
|
||||
return this.request(url, { ...config, method: 'POST', body: data });
|
||||
}
|
||||
|
||||
async put(url, data, config) {
|
||||
return this.request(url, { ...config, method: 'PUT', body: data });
|
||||
}
|
||||
|
||||
async delete(url, config) {
|
||||
return this.request(url, { ...config, method: 'DELETE' });
|
||||
}
|
||||
}
|
||||
|
||||
// 事件SDK实现
|
||||
class EventSDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
async emit(channel, data) {
|
||||
return this.wrapResponse(this.sendToSystem('events.emit', { channel, data }));
|
||||
}
|
||||
|
||||
async on(channel, callback, config) {
|
||||
const result = await this.wrapResponse(this.sendToSystem('events.on', { channel, config }));
|
||||
|
||||
async emit(channel, data) {
|
||||
return this.wrapResponse(this.sendToSystem('events.emit', { channel, data }));
|
||||
}
|
||||
|
||||
async on(channel, callback, config) {
|
||||
const result = await this.wrapResponse(this.sendToSystem('events.on', { channel, config }));
|
||||
|
||||
if (result.success && result.data) {
|
||||
// 注册事件监听器
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data?.type === 'system:event' && event.data?.subscriptionId === result.data) {
|
||||
try {
|
||||
callback(event.data.message);
|
||||
} catch (error) {
|
||||
console.error('事件回调处理错误:', error);
|
||||
}
|
||||
if (result.success && result.data) {
|
||||
// 注册事件监听器
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data?.type === 'system:event' && event.data?.subscriptionId === result.data) {
|
||||
try {
|
||||
callback(event.data.message);
|
||||
} catch (error) {
|
||||
console.error('事件回调处理错误:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async off(subscriptionId) {
|
||||
return this.wrapResponse(this.sendToSystem('events.off', { subscriptionId }));
|
||||
}
|
||||
|
||||
async broadcast(channel, data) {
|
||||
return this.wrapResponse(this.sendToSystem('events.broadcast', { channel, data }));
|
||||
}
|
||||
|
||||
async sendTo(targetAppId, data) {
|
||||
return this.wrapResponse(this.sendToSystem('events.sendTo', { targetAppId, data }));
|
||||
}
|
||||
}
|
||||
|
||||
// UI SDK实现
|
||||
class UISDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
async showDialog(options) {
|
||||
return this.wrapResponse(this.sendToSystem('ui.showDialog', options));
|
||||
}
|
||||
|
||||
async showNotification(options) {
|
||||
return this.wrapResponse(this.sendToSystem('ui.showNotification', options));
|
||||
}
|
||||
|
||||
async showToast(message, type, duration) {
|
||||
return this.wrapResponse(this.sendToSystem('ui.showToast', { message, type, duration }));
|
||||
}
|
||||
}
|
||||
|
||||
// 系统SDK实现
|
||||
class SystemSDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
async getSystemInfo() {
|
||||
return this.wrapResponse(this.sendToSystem('system.getSystemInfo'));
|
||||
}
|
||||
|
||||
async getAppInfo() {
|
||||
return this.wrapResponse(this.sendToSystem('system.getAppInfo'));
|
||||
}
|
||||
|
||||
async getClipboard() {
|
||||
return this.wrapResponse(this.sendToSystem('system.getClipboard'));
|
||||
}
|
||||
|
||||
async setClipboard(text) {
|
||||
return this.wrapResponse(this.sendToSystem('system.setClipboard', { text }));
|
||||
}
|
||||
|
||||
async getCurrentTime() {
|
||||
const result = await this.wrapResponse(this.sendToSystem('system.getCurrentTime'));
|
||||
if (result.success && result.data) {
|
||||
result.data = new Date(result.data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async generateUUID() {
|
||||
return this.wrapResponse(this.sendToSystem('system.generateUUID'));
|
||||
}
|
||||
}
|
||||
|
||||
// 主SDK实现类
|
||||
class SystemDesktopSDKImpl {
|
||||
constructor() {
|
||||
this.version = '1.0.0';
|
||||
this._appId = '';
|
||||
this._initialized = false;
|
||||
|
||||
// 初始化各个子模块为null
|
||||
this._window = null;
|
||||
this._storage = null;
|
||||
this._network = null;
|
||||
this._events = null;
|
||||
this._ui = null;
|
||||
this._system = null;
|
||||
}
|
||||
|
||||
get appId() {
|
||||
return this._appId;
|
||||
}
|
||||
|
||||
get initialized() {
|
||||
return this._initialized;
|
||||
}
|
||||
|
||||
get window() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] window模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._window;
|
||||
}
|
||||
|
||||
get storage() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] storage模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._storage;
|
||||
}
|
||||
|
||||
get network() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] network模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._network;
|
||||
}
|
||||
|
||||
get events() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] events模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._events;
|
||||
}
|
||||
|
||||
get ui() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] ui模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._ui;
|
||||
}
|
||||
|
||||
get system() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] system模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._system;
|
||||
}
|
||||
|
||||
async init(config) {
|
||||
try {
|
||||
console.log('[SystemSDK] 开始初始化SDK,配置:', config);
|
||||
|
||||
if (this._initialized) {
|
||||
console.warn('[SystemSDK] SDK已初始化');
|
||||
return { success: false, error: 'SDK已初始化' };
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async off(subscriptionId) {
|
||||
return this.wrapResponse(this.sendToSystem('events.off', { subscriptionId }));
|
||||
}
|
||||
|
||||
async broadcast(channel, data) {
|
||||
return this.wrapResponse(this.sendToSystem('events.broadcast', { channel, data }));
|
||||
}
|
||||
|
||||
async sendTo(targetAppId, data) {
|
||||
return this.wrapResponse(this.sendToSystem('events.sendTo', { targetAppId, data }));
|
||||
this._appId = config.appId;
|
||||
|
||||
// 初始化各个子模块
|
||||
this._window = new WindowSDKImpl(this._appId);
|
||||
this._storage = new StorageSDKImpl(this._appId);
|
||||
this._network = new NetworkSDKImpl(this._appId);
|
||||
this._events = new EventSDKImpl(this._appId);
|
||||
this._ui = new UISDKImpl(this._appId);
|
||||
this._system = new SystemSDKImpl(this._appId);
|
||||
|
||||
this._initialized = true;
|
||||
console.log('[SystemSDK] SDK初始化完成,应用ID:', this._appId);
|
||||
|
||||
// 通知父窗口SDK已初始化
|
||||
window.parent.postMessage({
|
||||
type: 'sdk:initialized',
|
||||
appId: this._appId
|
||||
}, '*');
|
||||
|
||||
return { success: true, data: true };
|
||||
} catch (error) {
|
||||
console.error('[SystemSDK] 初始化失败:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : '初始化失败',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// UI SDK实现
|
||||
class UISDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
async showDialog(options) {
|
||||
return this.wrapResponse(this.sendToSystem('ui.showDialog', options));
|
||||
}
|
||||
|
||||
async showNotification(options) {
|
||||
return this.wrapResponse(this.sendToSystem('ui.showNotification', options));
|
||||
}
|
||||
|
||||
async showToast(message, type, duration) {
|
||||
return this.wrapResponse(this.sendToSystem('ui.showToast', { message, type, duration }));
|
||||
}
|
||||
}
|
||||
|
||||
// 系统SDK实现
|
||||
class SystemSDKImpl extends SDKBase {
|
||||
constructor(appId) {
|
||||
super();
|
||||
this._appId = appId;
|
||||
}
|
||||
|
||||
async getSystemInfo() {
|
||||
return this.wrapResponse(this.sendToSystem('system.getSystemInfo'));
|
||||
}
|
||||
|
||||
async getAppInfo() {
|
||||
return this.wrapResponse(this.sendToSystem('system.getAppInfo'));
|
||||
}
|
||||
|
||||
async getClipboard() {
|
||||
return this.wrapResponse(this.sendToSystem('system.getClipboard'));
|
||||
}
|
||||
|
||||
async setClipboard(text) {
|
||||
return this.wrapResponse(this.sendToSystem('system.setClipboard', { text }));
|
||||
}
|
||||
|
||||
async getCurrentTime() {
|
||||
const result = await this.wrapResponse(this.sendToSystem('system.getCurrentTime'));
|
||||
if (result.success && result.data) {
|
||||
result.data = new Date(result.data);
|
||||
async destroy() {
|
||||
try {
|
||||
if (!this._initialized) {
|
||||
return { success: false, error: 'SDK未初始化' };
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async generateUUID() {
|
||||
return this.wrapResponse(this.sendToSystem('system.generateUUID'));
|
||||
}
|
||||
}
|
||||
|
||||
// 主SDK实现类
|
||||
class SystemDesktopSDKImpl {
|
||||
constructor() {
|
||||
this.version = '1.0.0';
|
||||
this._appId = '';
|
||||
|
||||
this._initialized = false;
|
||||
this._appId = '';
|
||||
console.log('[SystemSDK] SDK已销毁');
|
||||
|
||||
// 初始化各个子模块为null
|
||||
this._window = null;
|
||||
this._storage = null;
|
||||
this._network = null;
|
||||
this._events = null;
|
||||
this._ui = null;
|
||||
this._system = null;
|
||||
}
|
||||
|
||||
get appId() {
|
||||
return this._appId;
|
||||
}
|
||||
|
||||
get initialized() {
|
||||
return this._initialized;
|
||||
}
|
||||
|
||||
get window() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] window模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._window;
|
||||
}
|
||||
|
||||
get storage() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] storage模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._storage;
|
||||
}
|
||||
|
||||
get network() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] network模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._network;
|
||||
}
|
||||
|
||||
get events() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] events模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._events;
|
||||
}
|
||||
|
||||
get ui() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] ui模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._ui;
|
||||
}
|
||||
|
||||
get system() {
|
||||
if (!this._initialized) {
|
||||
console.warn('[SystemSDK] system模块未初始化');
|
||||
throw new Error('SDK未初始化');
|
||||
}
|
||||
return this._system;
|
||||
}
|
||||
|
||||
async init(config) {
|
||||
try {
|
||||
console.log('[SystemSDK] 开始初始化SDK,配置:', config);
|
||||
|
||||
if (this._initialized) {
|
||||
console.warn('[SystemSDK] SDK已初始化');
|
||||
return { success: false, error: 'SDK已初始化' };
|
||||
}
|
||||
|
||||
this._appId = config.appId;
|
||||
|
||||
// 初始化各个子模块
|
||||
this._window = new WindowSDKImpl(this._appId);
|
||||
this._storage = new StorageSDKImpl(this._appId);
|
||||
this._network = new NetworkSDKImpl(this._appId);
|
||||
this._events = new EventSDKImpl(this._appId);
|
||||
this._ui = new UISDKImpl(this._appId);
|
||||
this._system = new SystemSDKImpl(this._appId);
|
||||
|
||||
this._initialized = true;
|
||||
console.log('[SystemSDK] SDK初始化完成,应用ID:', this._appId);
|
||||
|
||||
// 通知父窗口SDK已初始化
|
||||
window.parent.postMessage({
|
||||
type: 'sdk:initialized',
|
||||
appId: this._appId
|
||||
}, '*');
|
||||
|
||||
return { success: true, data: true };
|
||||
} catch (error) {
|
||||
console.error('[SystemSDK] 初始化失败:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : '初始化失败',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async destroy() {
|
||||
try {
|
||||
if (!this._initialized) {
|
||||
return { success: false, error: 'SDK未初始化' };
|
||||
}
|
||||
|
||||
this._initialized = false;
|
||||
this._appId = '';
|
||||
console.log('[SystemSDK] SDK已销毁');
|
||||
|
||||
return { success: true, data: true };
|
||||
} catch (error) {
|
||||
console.error('[SystemSDK] 销毁失败:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : '销毁失败',
|
||||
};
|
||||
}
|
||||
return { success: true, data: true };
|
||||
} catch (error) {
|
||||
console.error('[SystemSDK] 销毁失败:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : '销毁失败',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 创建全局SDK实例
|
||||
const SystemSDK = new SystemDesktopSDKImpl();
|
||||
|
||||
// 在window对象上挂载SDK
|
||||
window.SystemSDK = SystemSDK;
|
||||
|
||||
console.log('[SystemSDK] SDK已在iframe中注入并挂载到window对象');
|
||||
|
||||
// 通知系统应用已准备就绪
|
||||
window.parent.postMessage({ type: 'app:ready' }, '*');
|
||||
})();
|
||||
`;
|
||||
|
||||
iframeDoc.head.appendChild(script)
|
||||
}
|
||||
}
|
||||
|
||||
// 创建全局SDK实例
|
||||
const SystemSDK = new SystemDesktopSDKImpl();
|
||||
|
||||
// 在window对象上挂载SDK
|
||||
window.SystemSDK = SystemSDK;
|
||||
|
||||
console.log('[SystemSDK] SDK已在iframe中注入并挂载到window对象');
|
||||
|
||||
// 通知系统应用已准备就绪
|
||||
window.parent.postMessage({ type: 'app:ready' }, '*');
|
||||
})();
|
||||
`;
|
||||
|
||||
iframeDoc.head.appendChild(script)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置性能监控
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { reactive, ref } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import type { IEventBuilder } from '@/events/IEventBuilder'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
@@ -10,7 +10,7 @@ export enum MessageType {
|
||||
APPLICATION = 'application',
|
||||
USER_INTERACTION = 'user_interaction',
|
||||
CROSS_APP = 'cross_app',
|
||||
BROADCAST = 'broadcast'
|
||||
BROADCAST = 'broadcast',
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20,7 +20,7 @@ export enum MessagePriority {
|
||||
LOW = 0,
|
||||
NORMAL = 1,
|
||||
HIGH = 2,
|
||||
CRITICAL = 3
|
||||
CRITICAL = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +31,7 @@ export enum MessageStatus {
|
||||
SENT = 'sent',
|
||||
DELIVERED = 'delivered',
|
||||
FAILED = 'failed',
|
||||
EXPIRED = 'expired'
|
||||
EXPIRED = 'expired',
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ export class EventCommunicationService {
|
||||
totalBroadcasts: 0,
|
||||
failedMessages: 0,
|
||||
activeSubscribers: 0,
|
||||
channelUsage: new Map()
|
||||
channelUsage: new Map(),
|
||||
})
|
||||
|
||||
private processingInterval: number | null = null
|
||||
@@ -126,7 +126,7 @@ export class EventCommunicationService {
|
||||
options: {
|
||||
filter?: (message: EventMessage) => boolean
|
||||
priority?: MessagePriority
|
||||
} = {}
|
||||
} = {},
|
||||
): string {
|
||||
// 检查通道权限
|
||||
if (!this.canAccessChannel(appId, channel)) {
|
||||
@@ -142,7 +142,7 @@ export class EventCommunicationService {
|
||||
filter: options.filter,
|
||||
priority: options.priority || MessagePriority.NORMAL,
|
||||
createdAt: new Date(),
|
||||
active: true
|
||||
active: true,
|
||||
}
|
||||
|
||||
this.subscribers.set(subscriberId, subscriber)
|
||||
@@ -177,7 +177,7 @@ export class EventCommunicationService {
|
||||
type?: MessageType
|
||||
expiresIn?: number // 过期时间(毫秒)
|
||||
maxRetries?: number
|
||||
} = {}
|
||||
} = {},
|
||||
): Promise<string> {
|
||||
// 检查发送者权限
|
||||
if (!this.canAccessChannel(senderId, channel)) {
|
||||
@@ -193,7 +193,7 @@ export class EventCommunicationService {
|
||||
|
||||
const messageId = uuidv4()
|
||||
const now = new Date()
|
||||
|
||||
|
||||
const message: EventMessage = {
|
||||
id: messageId,
|
||||
type: options.type || MessageType.APPLICATION,
|
||||
@@ -206,7 +206,7 @@ export class EventCommunicationService {
|
||||
expiresAt: options.expiresIn ? new Date(now.getTime() + options.expiresIn) : undefined,
|
||||
status: MessageStatus.PENDING,
|
||||
retryCount: 0,
|
||||
maxRetries: options.maxRetries || 3
|
||||
maxRetries: options.maxRetries || 3,
|
||||
}
|
||||
|
||||
// 如果是点对点消息,直接发送
|
||||
@@ -222,14 +222,16 @@ export class EventCommunicationService {
|
||||
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}]`)
|
||||
console.log(
|
||||
`[EventCommunication] 消息 ${messageId} 已发送到频道 ${channel}[发送者: ${senderId}]`,
|
||||
)
|
||||
return messageId
|
||||
}
|
||||
|
||||
@@ -243,11 +245,11 @@ export class EventCommunicationService {
|
||||
options: {
|
||||
priority?: MessagePriority
|
||||
expiresIn?: number
|
||||
} = {}
|
||||
} = {},
|
||||
): Promise<string> {
|
||||
return this.sendMessage(senderId, channel, payload, {
|
||||
...options,
|
||||
type: MessageType.BROADCAST
|
||||
type: MessageType.BROADCAST,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -261,14 +263,14 @@ export class EventCommunicationService {
|
||||
options: {
|
||||
priority?: MessagePriority
|
||||
expiresIn?: number
|
||||
} = {}
|
||||
} = {},
|
||||
): Promise<string> {
|
||||
const channel = 'cross-app'
|
||||
|
||||
|
||||
return this.sendMessage(senderId, channel, payload, {
|
||||
...options,
|
||||
receiverId,
|
||||
type: MessageType.CROSS_APP
|
||||
type: MessageType.CROSS_APP,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -281,20 +283,18 @@ export class EventCommunicationService {
|
||||
channel?: string
|
||||
limit?: number
|
||||
since?: Date
|
||||
} = {}
|
||||
} = {},
|
||||
): EventMessage[] {
|
||||
const history = this.messageHistory.get(appId) || []
|
||||
|
||||
let filtered = history.filter(msg =>
|
||||
msg.senderId === appId || msg.receiverId === appId
|
||||
)
|
||||
|
||||
let filtered = history.filter((msg) => msg.senderId === appId || msg.receiverId === appId)
|
||||
|
||||
if (options.channel) {
|
||||
filtered = filtered.filter(msg => msg.channel === options.channel)
|
||||
filtered = filtered.filter((msg) => msg.channel === options.channel)
|
||||
}
|
||||
|
||||
if (options.since) {
|
||||
filtered = filtered.filter(msg => msg.timestamp >= options.since!)
|
||||
filtered = filtered.filter((msg) => msg.timestamp >= options.since!)
|
||||
}
|
||||
|
||||
if (options.limit) {
|
||||
@@ -308,7 +308,7 @@ export class EventCommunicationService {
|
||||
* 获取应用的订阅列表
|
||||
*/
|
||||
getAppSubscriptions(appId: string): EventSubscriber[] {
|
||||
return Array.from(this.subscribers.values()).filter(sub => sub.appId === appId)
|
||||
return Array.from(this.subscribers.values()).filter((sub) => sub.appId === appId)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -316,24 +316,21 @@ export class EventCommunicationService {
|
||||
*/
|
||||
getChannelSubscriberCount(channel: string): number {
|
||||
return Array.from(this.subscribers.values()).filter(
|
||||
sub => sub.channel === channel && sub.active
|
||||
(sub) => sub.channel === channel && sub.active,
|
||||
).length
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建通信频道
|
||||
*/
|
||||
createChannel(
|
||||
channel: string,
|
||||
config: Omit<CommunicationChannel, 'name'>
|
||||
): boolean {
|
||||
createChannel(channel: string, config: Omit<CommunicationChannel, 'name'>): boolean {
|
||||
if (this.channels.has(channel)) {
|
||||
return false
|
||||
}
|
||||
|
||||
this.channels.set(channel, {
|
||||
name: channel,
|
||||
...config
|
||||
...config,
|
||||
})
|
||||
|
||||
console.log(`创建通信频道: ${channel}`)
|
||||
@@ -349,15 +346,15 @@ export class EventCommunicationService {
|
||||
.filter(([, sub]) => sub.channel === channel)
|
||||
.map(([id]) => id)
|
||||
|
||||
subscribersToRemove.forEach(id => this.unsubscribe(id))
|
||||
subscribersToRemove.forEach((id) => this.unsubscribe(id))
|
||||
|
||||
// 删除频道
|
||||
const result = this.channels.delete(channel)
|
||||
|
||||
|
||||
if (result) {
|
||||
console.log(`删除通信频道: ${channel}`)
|
||||
}
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -376,10 +373,8 @@ export class EventCommunicationService {
|
||||
|
||||
// 清理过期消息
|
||||
for (const [appId, messages] of this.messageQueue.entries()) {
|
||||
const validMessages = messages.filter(msg =>
|
||||
!msg.expiresAt || msg.expiresAt > now
|
||||
)
|
||||
|
||||
const validMessages = messages.filter((msg) => !msg.expiresAt || msg.expiresAt > now)
|
||||
|
||||
if (validMessages.length !== messages.length) {
|
||||
this.messageQueue.set(appId, validMessages)
|
||||
}
|
||||
@@ -388,7 +383,7 @@ export class EventCommunicationService {
|
||||
// 清理消息历史(保留最近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)
|
||||
const recentHistory = history.filter((msg) => msg.timestamp > sevenDaysAgo)
|
||||
this.messageHistory.set(appId, recentHistory)
|
||||
}
|
||||
|
||||
@@ -424,7 +419,7 @@ export class EventCommunicationService {
|
||||
restricted: true,
|
||||
allowedApps: ['system'],
|
||||
maxMessageSize: 1024 * 10, // 10KB
|
||||
messageRetention: 24 * 60 * 60 * 1000 // 24小时
|
||||
messageRetention: 24 * 60 * 60 * 1000, // 24小时
|
||||
})
|
||||
|
||||
// 应用间通信频道
|
||||
@@ -433,7 +428,7 @@ export class EventCommunicationService {
|
||||
restricted: false,
|
||||
allowedApps: [],
|
||||
maxMessageSize: 1024 * 100, // 100KB
|
||||
messageRetention: 7 * 24 * 60 * 60 * 1000 // 7天
|
||||
messageRetention: 7 * 24 * 60 * 60 * 1000, // 7天
|
||||
})
|
||||
|
||||
// 用户交互频道
|
||||
@@ -442,7 +437,7 @@ export class EventCommunicationService {
|
||||
restricted: false,
|
||||
allowedApps: [],
|
||||
maxMessageSize: 1024 * 5, // 5KB
|
||||
messageRetention: 60 * 60 * 1000 // 1小时
|
||||
messageRetention: 60 * 60 * 1000, // 1小时
|
||||
})
|
||||
|
||||
// 广播频道
|
||||
@@ -451,7 +446,7 @@ export class EventCommunicationService {
|
||||
restricted: true,
|
||||
allowedApps: ['system'],
|
||||
maxMessageSize: 1024 * 50, // 50KB
|
||||
messageRetention: 24 * 60 * 60 * 1000 // 24小时
|
||||
messageRetention: 24 * 60 * 60 * 1000, // 24小时
|
||||
})
|
||||
}
|
||||
|
||||
@@ -460,7 +455,7 @@ export class EventCommunicationService {
|
||||
*/
|
||||
private canAccessChannel(appId: string, channel: string): boolean {
|
||||
const channelConfig = this.channels.get(channel)
|
||||
|
||||
|
||||
if (!channelConfig) {
|
||||
// 频道不存在,默认允许
|
||||
return true
|
||||
@@ -483,15 +478,15 @@ export class EventCommunicationService {
|
||||
*/
|
||||
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)
|
||||
const insertIndex = queue.findIndex((msg) => msg.priority < message.priority)
|
||||
if (insertIndex === -1) {
|
||||
queue.push(message)
|
||||
} else {
|
||||
@@ -505,12 +500,14 @@ export class EventCommunicationService {
|
||||
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}]`)
|
||||
console.warn(
|
||||
`[EventCommunication] 没有找到频道 ${message.channel} 的订阅者[消息 ID: ${message.id}]`,
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -525,7 +522,9 @@ export class EventCommunicationService {
|
||||
|
||||
await subscriber.handler(message)
|
||||
this.statistics.totalMessagesReceived++
|
||||
console.log(`[EventCommunication] 消息 ${message.id} 已投递给订阅者 ${subscriber.id}[频道: ${message.channel}]`)
|
||||
console.log(
|
||||
`[EventCommunication] 消息 ${message.id} 已投递给订阅者 ${subscriber.id}[频道: ${message.channel}]`,
|
||||
)
|
||||
} catch (error) {
|
||||
console.error(`向订阅者 ${subscriber.id} 发送消息失败:`, error)
|
||||
throw error
|
||||
@@ -534,12 +533,11 @@ export class EventCommunicationService {
|
||||
|
||||
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++
|
||||
@@ -553,10 +551,10 @@ export class EventCommunicationService {
|
||||
* 获取相关订阅者
|
||||
*/
|
||||
private getRelevantSubscribers(message: EventMessage): EventSubscriber[] {
|
||||
return Array.from(this.subscribers.values()).filter(subscriber => {
|
||||
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
|
||||
@@ -585,7 +583,7 @@ export class EventCommunicationService {
|
||||
|
||||
// 处理优先级最高的消息
|
||||
const message = messages.shift()!
|
||||
|
||||
|
||||
// 检查消息是否过期
|
||||
if (message.expiresAt && message.expiresAt <= new Date()) {
|
||||
message.status = MessageStatus.EXPIRED
|
||||
@@ -601,12 +599,10 @@ export class EventCommunicationService {
|
||||
*/
|
||||
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
|
||||
)
|
||||
|
||||
const validMessages = messages.filter((msg) => !msg.expiresAt || msg.expiresAt > now)
|
||||
|
||||
if (validMessages.length !== messages.length) {
|
||||
this.messageQueue.set(queueKey, validMessages)
|
||||
}
|
||||
@@ -636,7 +632,8 @@ export class EventCommunicationService {
|
||||
* 更新活跃订阅者数量
|
||||
*/
|
||||
private updateActiveSubscribersCount(): void {
|
||||
this.statistics.activeSubscribers = Array.from(this.subscribers.values())
|
||||
.filter(sub => sub.active).length
|
||||
this.statistics.activeSubscribers = Array.from(this.subscribers.values()).filter(
|
||||
(sub) => sub.active,
|
||||
).length
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ref, reactive } from 'vue'
|
||||
import { reactive, ref } from 'vue'
|
||||
import type { IEventBuilder, IEventMap } from '@/events/IEventBuilder'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import type { ResizeDirection, ResizeState } from '@/ui/types/WindowFormTypes'
|
||||
|
||||
@@ -35,7 +35,7 @@ const builtInWindows = ref<BuiltInWindow[]>([])
|
||||
const systemService = inject<SystemServiceIntegration>('systemService')
|
||||
|
||||
// 添加内置应用窗口
|
||||
const addBuiltInWindow = (windowId: string, appId: string) => {
|
||||
const addBuiltInWindow = async (windowId: string, appId: string) => {
|
||||
// 检查应用是否存在
|
||||
const appRegistration = appRegistry.getApp(appId)
|
||||
if (!appRegistration) {
|
||||
@@ -50,11 +50,23 @@ const addBuiltInWindow = (windowId: string, appId: string) => {
|
||||
return
|
||||
}
|
||||
|
||||
// 处理异步组件加载
|
||||
let component = appRegistration.component
|
||||
if (typeof component === 'function') {
|
||||
try {
|
||||
// 如果是函数,调用它来获取组件
|
||||
component = await component()
|
||||
} catch (error) {
|
||||
console.error(`加载应用组件失败: ${appId}`, error)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 添加窗口
|
||||
const window: BuiltInWindow = {
|
||||
id: windowId,
|
||||
appId,
|
||||
component: appRegistration.component,
|
||||
component,
|
||||
props: {
|
||||
windowId,
|
||||
appId
|
||||
@@ -99,9 +111,9 @@ onMounted(() => {
|
||||
const eventService = systemService.getEventService()
|
||||
|
||||
// 监听内置应用窗口创建事件
|
||||
const subscriberId = eventService.subscribe('system', 'built-in-window-created', (message) => {
|
||||
const subscriberId = eventService.subscribe('system', 'built-in-window-created', async (message) => {
|
||||
const { windowId, appId } = message.payload
|
||||
addBuiltInWindow(windowId, appId)
|
||||
await addBuiltInWindow(windowId, appId)
|
||||
})
|
||||
|
||||
// 监听内置应用窗口关闭事件
|
||||
|
||||
@@ -144,7 +144,7 @@ const startApp = async (appId: string) => {
|
||||
|
||||
// 使用主应用的窗口管理器来渲染内置应用
|
||||
if (windowManager?.value) {
|
||||
windowManager.value.addBuiltInWindow(windowInstance.id, appId)
|
||||
await windowManager.value.addBuiltInWindow(windowInstance.id, appId)
|
||||
console.log(`[主应用] 使用窗口管理器渲染内置应用: ${appId}`)
|
||||
} else {
|
||||
console.error('窗口管理器未初始化')
|
||||
|
||||
Reference in New Issue
Block a user