import type { SystemDesktopSDK, SDKConfig, APIResponse, WindowSDK, StorageSDK, NetworkSDK, EventSDK, UISDK, SystemSDK, WindowState, WindowEvents, StorageEvents, NetworkRequestConfig, NetworkResponse, EventMessage, EventSubscriptionConfig, DialogOptions, NotificationOptions, FilePickerOptions, SystemInfo, AppInfo, PermissionStatus, } from './types' /** * SDK基础类 */ abstract class SDKBase { protected appId: string = '' protected initialized: boolean = false /** * 发送消息到系统 */ protected sendToSystem(type: string, data?: any): Promise { return new Promise((resolve, reject) => { const requestId = Date.now().toString() + Math.random().toString(36).substr(2, 9) const handler = (event: MessageEvent) => { if (event.data?.type === 'system:response' && event.data?.requestId === requestId) { window.removeEventListener('message', handler) if (event.data.success) { resolve(event.data.data) } else { reject(new Error(event.data.error || '系统调用失败')) } } } window.addEventListener('message', handler) // 发送消息到父窗口(系统) window.parent.postMessage( { type: 'sdk:call', requestId, method: type, data, appId: this.appId, }, '*', ) // 设置超时 setTimeout(() => { window.removeEventListener('message', handler) reject(new Error('系统调用超时')) }, 10000) }) } /** * 包装API响应 */ protected wrapResponse(promise: Promise): Promise> { return promise .then((data) => ({ success: true, data })) .catch((error) => ({ success: false, error: error.message || '未知错误', code: error.code || -1, })) } } /** * 窗体SDK实现 */ class WindowSDKImpl extends SDKBase implements WindowSDK { private eventListeners = new Map>() constructor(appId: string) { super() this.appId = appId this.setupEventListeners() } async setTitle(title: string): Promise> { return this.wrapResponse(this.sendToSystem('window.setTitle', { title })) } async resize(width: number, height: number): Promise> { return this.wrapResponse(this.sendToSystem('window.resize', { width, height })) } async move(x: number, y: number): Promise> { return this.wrapResponse(this.sendToSystem('window.move', { x, y })) } async minimize(): Promise> { return this.wrapResponse(this.sendToSystem('window.minimize')) } async maximize(): Promise> { return this.wrapResponse(this.sendToSystem('window.maximize')) } async restore(): Promise> { return this.wrapResponse(this.sendToSystem('window.restore')) } async fullscreen(): Promise> { return this.wrapResponse(this.sendToSystem('window.fullscreen')) } async close(): Promise> { return this.wrapResponse(this.sendToSystem('window.close')) } async getState(): Promise> { return this.wrapResponse(this.sendToSystem('window.getState')) } async getSize(): Promise> { return this.wrapResponse(this.sendToSystem('window.getSize')) } async getPosition(): Promise> { return this.wrapResponse(this.sendToSystem('window.getPosition')) } on(event: K, callback: WindowEvents[K]): void { if (!this.eventListeners.has(event)) { this.eventListeners.set(event, new Set()) } this.eventListeners.get(event)!.add(callback) } off(event: K, callback?: WindowEvents[K]): void { if (callback) { this.eventListeners.get(event)?.delete(callback) } else { this.eventListeners.delete(event) } } private setupEventListeners(): void { window.addEventListener('message', (event) => { if (event.data?.type?.startsWith('system:window:')) { const eventType = event.data.type.replace('system:window:', '') as keyof WindowEvents const listeners = this.eventListeners.get(eventType) if (listeners) { listeners.forEach((callback) => { try { callback(...(event.data.args || [])) } catch (error) { console.error('窗体事件处理错误:', error) } }) } } }) } } /** * 存储SDK实现 */ class StorageSDKImpl extends SDKBase implements StorageSDK { private eventListeners = new Map>() constructor(appId: string) { super() this.appId = appId this.setupEventListeners() } async set(key: string, value: any): Promise> { return this.wrapResponse(this.sendToSystem('storage.set', { key, value })) } async get(key: string): Promise> { return this.wrapResponse(this.sendToSystem('storage.getWindowForm', { key })) } async remove(key: string): Promise> { return this.wrapResponse(this.sendToSystem('storage.removeWindowForm', { key })) } async clear(): Promise> { return this.wrapResponse(this.sendToSystem('storage.clear')) } async keys(): Promise> { return this.wrapResponse(this.sendToSystem('storage.keys')) } async has(key: string): Promise> { return this.wrapResponse(this.sendToSystem('storage.has', { key })) } async getStats(): Promise> { return this.wrapResponse(this.sendToSystem('storage.getStats')) } on(event: K, callback: StorageEvents[K]): void { if (!this.eventListeners.has(event)) { this.eventListeners.set(event, new Set()) } this.eventListeners.get(event)!.add(callback) } off(event: K, callback?: StorageEvents[K]): void { if (callback) { this.eventListeners.get(event)?.delete(callback) } else { this.eventListeners.delete(event) } } private setupEventListeners(): void { window.addEventListener('message', (event) => { if (event.data?.type?.startsWith('system:storage:')) { const eventType = event.data.type.replace('system:storage:', '') as keyof StorageEvents const listeners = this.eventListeners.get(eventType) if (listeners) { listeners.forEach((callback) => { try { callback(...(event.data.args || [])) } catch (error) { console.error('存储事件处理错误:', error) } }) } } }) } } /** * 网络SDK实现 */ class NetworkSDKImpl extends SDKBase implements NetworkSDK { constructor(appId: string) { super() this.appId = appId } async request( url: string, config?: NetworkRequestConfig, ): Promise>> { return this.wrapResponse(this.sendToSystem('network.request', { url, config })) } async get( url: string, config?: Omit, ): Promise>> { return this.request(url, { ...config, method: 'GET' }) } async post( url: string, data?: any, config?: Omit, ): Promise>> { return this.request(url, { ...config, method: 'POST', body: data }) } async put( url: string, data?: any, config?: Omit, ): Promise>> { return this.request(url, { ...config, method: 'PUT', body: data }) } async delete( url: string, config?: Omit, ): Promise>> { return this.request(url, { ...config, method: 'DELETE' }) } async upload( url: string, file: File | Blob, onProgress?: (loaded: number, total: number) => void, ): Promise> { return this.wrapResponse( this.sendToSystem('network.upload', { url, file, hasProgressCallback: !!onProgress }), ) } async download( url: string, filename?: string, onProgress?: (loaded: number, total: number) => void, ): Promise> { return this.wrapResponse( this.sendToSystem('network.download', { url, filename, hasProgressCallback: !!onProgress }), ) } async isOnline(): Promise> { return this.wrapResponse(this.sendToSystem('network.isOnline')) } async getStats(): Promise< APIResponse<{ requestCount: number; failureCount: number; averageTime: number }> > { return this.wrapResponse(this.sendToSystem('network.getStats')) } } /** * 事件SDK实现 */ class EventSDKImpl extends SDKBase implements EventSDK { private subscriptions = new Map() constructor(appId: string) { super() this.appId = appId this.setupEventListeners() } async emit(channel: string, data: T): Promise> { return this.wrapResponse(this.sendToSystem('events.emit', { channel, data })) } async on( channel: string, callback: (message: EventMessage) => void, config?: EventSubscriptionConfig, ): Promise> { const result = await this.wrapResponse(this.sendToSystem('events.on', { channel, config })) if (result.success && result.data) { this.subscriptions.set(result.data, callback) } return result } async off(subscriptionId: string): Promise> { const result = await this.wrapResponse(this.sendToSystem('events.off', { subscriptionId })) if (result.success) { this.subscriptions.delete(subscriptionId) } return result } async broadcast(channel: string, data: T): Promise> { return this.wrapResponse(this.sendToSystem('events.broadcast', { channel, data })) } async sendTo(targetAppId: string, data: T): Promise> { return this.wrapResponse(this.sendToSystem('events.sendTo', { targetAppId, data })) } async getSubscriberCount(channel: string): Promise> { return this.wrapResponse(this.sendToSystem('events.getSubscriberCount', { channel })) } async getChannels(): Promise> { return this.wrapResponse(this.sendToSystem('events.getChannels')) } private setupEventListeners(): void { window.addEventListener('message', (event) => { if (event.data?.type === 'system:event' && event.data?.subscriptionId) { const callback = this.subscriptions.get(event.data.subscriptionId) if (callback) { try { callback(event.data.message) } catch (error) { console.error('事件回调处理错误:', error) } } } }) } } /** * UI SDK实现 */ class UISDKImpl extends SDKBase implements UISDK { constructor(appId: string) { super() this.appId = appId } async showDialog( options: DialogOptions, ): Promise> { return this.wrapResponse(this.sendToSystem('ui.showDialog', options)) } async showNotification(options: NotificationOptions): Promise> { return this.wrapResponse(this.sendToSystem('ui.showNotification', options)) } async showFilePicker(options?: FilePickerOptions): Promise> { return this.wrapResponse(this.sendToSystem('ui.showFilePicker', options)) } async showSaveDialog(defaultName?: string, accept?: string): Promise> { return this.wrapResponse(this.sendToSystem('ui.showSaveDialog', { defaultName, accept })) } async showToast( message: string, type?: 'info' | 'success' | 'warning' | 'error', duration?: number, ): Promise> { return this.wrapResponse(this.sendToSystem('ui.showToast', { message, type, duration })) } async showLoading(message?: string): Promise> { return this.wrapResponse(this.sendToSystem('ui.showLoading', { message })) } async hideLoading(id: string): Promise> { return this.wrapResponse(this.sendToSystem('ui.hideLoading', { id })) } async showProgress(options: { title?: string message?: string progress: number }): Promise> { return this.wrapResponse(this.sendToSystem('ui.showProgress', options)) } async updateProgress( id: string, progress: number, message?: string, ): Promise> { return this.wrapResponse(this.sendToSystem('ui.updateProgress', { id, progress, message })) } async hideProgress(id: string): Promise> { return this.wrapResponse(this.sendToSystem('ui.hideProgress', { id })) } } /** * 系统SDK实现 */ class SystemSDKImpl extends SDKBase implements SystemSDK { constructor(appId: string) { super() this.appId = appId } async getSystemInfo(): Promise> { return this.wrapResponse(this.sendToSystem('system.getSystemInfo')) } async getAppInfo(): Promise> { return this.wrapResponse(this.sendToSystem('system.getAppInfo')) } async requestPermission( permission: string, reason?: string, ): Promise> { return this.wrapResponse(this.sendToSystem('system.requestPermission', { permission, reason })) } async checkPermission(permission: string): Promise> { return this.wrapResponse(this.sendToSystem('system.checkPermission', { permission })) } async getClipboard(): Promise> { return this.wrapResponse(this.sendToSystem('system.getClipboard')) } async setClipboard(text: string): Promise> { return this.wrapResponse(this.sendToSystem('system.setClipboard', { text })) } async openExternal(url: string): Promise> { return this.wrapResponse(this.sendToSystem('system.openExternal', { url })) } async getCurrentTime(): Promise> { const result = await this.wrapResponse(this.sendToSystem('system.getCurrentTime')) if (result.success && result.data) { result.data = new Date(result.data) } return result } async generateUUID(): Promise> { return this.wrapResponse(this.sendToSystem('system.generateUUID')) } async exit(): Promise> { return this.wrapResponse(this.sendToSystem('system.exit')) } } /** * 主SDK实现类 */ class SystemDesktopSDKImpl implements SystemDesktopSDK { readonly version: string = '1.0.0' private _appId: string = '' private _initialized: boolean = false private _window!: WindowSDK private _storage!: StorageSDK private _network!: NetworkSDK private _events!: EventSDK private _ui!: UISDK private _system!: SystemSDK get appId(): string { return this._appId } get initialized(): boolean { return this._initialized } get window(): WindowSDK { this.checkInitialized() return this._window } get storage(): StorageSDK { this.checkInitialized() return this._storage } get network(): NetworkSDK { this.checkInitialized() return this._network } get events(): EventSDK { this.checkInitialized() return this._events } get ui(): UISDK { this.checkInitialized() return this._ui } get system(): SystemSDK { this.checkInitialized() return this._system } async init(config: SDKConfig): Promise> { try { if (this._initialized) { 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) // 向系统注册应用 const response = await this.sendToSystem('sdk.init', config) if (response.success) { this._initialized = true console.log(`SDK已初始化,应用ID: ${this._appId}`) } return response } catch (error) { return { success: false, error: error instanceof Error ? error.message : '初始化失败', } } } async destroy(): Promise> { try { if (!this._initialized) { return { success: false, error: 'SDK未初始化' } } const response = await this.sendToSystem('sdk.destroy', { appId: this._appId }) if (response.success) { this._initialized = false this._appId = '' console.log('SDK已销毁') } return response } catch (error) { return { success: false, error: error instanceof Error ? error.message : '销毁失败', } } } async getStatus(): Promise< APIResponse<{ initialized: boolean; connected: boolean; permissions: string[] }> > { try { const response = await this.sendToSystem('sdk.getStatus', { appId: this._appId }) return { success: true, data: { initialized: this._initialized, connected: response.data.connected || false, permissions: response.data.permissions || [], }, } } catch (error) { return { success: false, error: error instanceof Error ? error.message : '获取状态失败', } } } private checkInitialized(): void { if (!this._initialized) { throw new Error('SDK未初始化,请先调用init()方法') } } private sendToSystem( type: string, data?: any, ): Promise<{ success: boolean; data?: T; error?: string }> { return new Promise((resolve, reject) => { const requestId = Date.now().toString() + Math.random().toString(36).substr(2, 9) const handler = (event: MessageEvent) => { if (event.data?.type === 'system:response' && event.data?.requestId === requestId) { window.removeEventListener('message', handler) resolve(event.data) } } window.addEventListener('message', handler) window.parent.postMessage( { type: 'sdk:call', requestId, method: type, data, appId: this._appId, }, '*', ) setTimeout(() => { window.removeEventListener('message', handler) reject(new Error('系统调用超时')) }, 10000) }) } } // 创建全局SDK实例 const SystemSDK = new SystemDesktopSDKImpl() // 导出SDK实例 export default SystemSDK // 在window对象上挂载SDK if (typeof window !== 'undefined') { window.SystemSDK = SystemSDK }