From a56197a3492e29c0e8b42c71567cb53487ae70d0 Mon Sep 17 00:00:00 2001 From: Azure <983547216@qq.com> Date: Sun, 28 Sep 2025 14:32:07 +0800 Subject: [PATCH] 1 --- .prettierrc.json | 14 +- PRETTIER_CONFIG_GUIDE.md | 134 +++++++++++++++ src/apps/AppRegistry.ts | 2 +- src/main.ts | 5 +- src/services/SystemServiceIntegration.ts | 29 ++-- src/services/WindowService.ts | 201 ++++++++++++++--------- 6 files changed, 284 insertions(+), 101 deletions(-) create mode 100644 PRETTIER_CONFIG_GUIDE.md diff --git a/.prettierrc.json b/.prettierrc.json index 29a2402..2bdca84 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -2,5 +2,17 @@ "$schema": "https://json.schemastore.org/prettierrc", "semi": false, "singleQuote": true, - "printWidth": 100 + "printWidth": 100, + "useTabs": false, + "tabWidth": 2, + "bracketSpacing": true, + "bracketSameLine": false, + "jsxSingleQuote": false, + "trailingComma": "es5", + "arrowParens": "always", + "endOfLine": "lf", + "quoteProps": "as-needed", + "htmlWhitespaceSensitivity": "css", + "vueIndentScriptAndStyle": false, + "singleAttributePerLine": false } diff --git a/PRETTIER_CONFIG_GUIDE.md b/PRETTIER_CONFIG_GUIDE.md new file mode 100644 index 0000000..bdb37c2 --- /dev/null +++ b/PRETTIER_CONFIG_GUIDE.md @@ -0,0 +1,134 @@ +# Prettier 常用配置项详解 + +## 基础格式化选项 + +### semi (boolean) + +- **默认值**: true +- **说明**: 在语句末尾打印分号 +- **示例**: + - true: `console.log('hello');` + - false: `console.log('hello')` + +### singleQuote (boolean) + +- **默认值**: false +- **说明**: 使用单引号而不是双引号 +- **示例**: + - true: `const str = 'hello';` + - false: `const str = "hello";` + +### printWidth (number) + +- **默认值**: 80 +- **说明**: 指定每行代码的最大字符数,超过这个长度会自动换行 + +### useTabs (boolean) + +- **默认值**: false +- **说明**: 使用制表符(tab)缩进而不是空格 + +### tabWidth (number) + +- **默认值**: 2 +- **说明**: 指定每个缩进级别的空格数 + +## 对象和数组格式化 + +### bracketSpacing (boolean) + +- **默认值**: true +- **说明**: 在对象字面量中的括号之间打印空格 +- **示例**: + - true: `{ foo: bar }` + - false: `{foo: bar}` + +### bracketSameLine (boolean) + +- **默认值**: false +- **说明**: 将多行 HTML 元素的 > 放在最后一行的末尾,而不是单独放在下一行 + +### trailingComma (string) + +- **默认值**: "es5" +- **可选值**: "none" | "es5" | "all" +- **说明**: 在多行对象或数组的最后一个元素后是否添加逗号 +- **示例**: + + ```javascript + // "none" + { + foo: 'bar' + } + + // "es5" + { + foo: 'bar', + } + + // "all" + { + foo: 'bar', + baz: 'qux', + } + ``` + +## JSX 特定选项 + +### jsxSingleQuote (boolean) + +- **默认值**: false +- **说明**: 在 JSX 中使用单引号而不是双引号 + +### singleAttributePerLine (boolean) + +- **默认值**: false +- **说明**: 是否强制每个 JSX 属性独占一行 + +## 函数和箭头函数 + +### arrowParens (string) + +- **默认值**: "always" +- **可选值**: "always" | "avoid" +- **说明**: 在箭头函数参数周围始终包含括号 +- **示例**: + + ```javascript + // "always" + const fn = (x) => x + + // "avoid" + const fn = (x) => x + const fn2 = (x, y) => x + y + ``` + +## 其他格式化选项 + +### endOfLine (string) + +- **默认值**: "lf" +- **可选值**: "auto" | "lf" | "crlf" | "cr" +- **说明**: 指定换行符风格 + - "lf": \n (Linux/macOS) + - "crlf": \r\n (Windows) + +### quoteProps (string) + +- **默认值**: "as-needed" +- **可选值**: "as-needed" | "consistent" | "preserve" +- **说明**: 对象属性引用方式 + - "as-needed": 仅在需要时才引用属性 + - "consistent": 如果至少有一个属性需要引用,则引用所有属性 + - "preserve": 保持原样 + +### htmlWhitespaceSensitivity (string) + +- **默认值**: "css" +- **可选值**: "css" | "strict" | "ignore" +- **说明**: 指定 HTML、Vue、Angular 文件中全局空白敏感度 + +### vueIndentScriptAndStyle (boolean) + +- **默认值**: false +- **说明**: Vue 文件中单文件组件的脚本和样式标签内是否缩进 diff --git a/src/apps/AppRegistry.ts b/src/apps/AppRegistry.ts index 16182a3..d4aff60 100644 --- a/src/apps/AppRegistry.ts +++ b/src/apps/AppRegistry.ts @@ -1,5 +1,5 @@ import type { AppRegistration } from './types/AppManifest' -import { reactive, markRaw } from 'vue' +import { reactive } from 'vue' /** * 应用注册中心 diff --git a/src/main.ts b/src/main.ts index ad0d341..24e3d9e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -16,7 +16,7 @@ registerBuiltInApps() const systemService = new SystemServiceIntegration({ debug: import.meta.env.DEV, enablePerformanceMonitoring: true, - enableSecurityAudit: true + enableSecurityAudit: true, }) // 创建应用实例 @@ -30,7 +30,8 @@ app.use(naiveUi) app.provide('systemService', systemService) // 初始化系统服务然后挂载应用 -systemService.initialize() +systemService + .initialize() .then(() => { app.mount('#app') console.log('桌面系统启动完成') diff --git a/src/services/SystemServiceIntegration.ts b/src/services/SystemServiceIntegration.ts index 5469aaf..f2dc729 100644 --- a/src/services/SystemServiceIntegration.ts +++ b/src/services/SystemServiceIntegration.ts @@ -1,7 +1,10 @@ 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 { + EventCommunicationEvents, + WindowFormDataUpdateParams, +} from './EventCommunicationService' import type { ResourceType } from './ResourceService' // 导入所有服务 @@ -11,7 +14,6 @@ import { EventCommunicationService } from './EventCommunicationService' import { ApplicationSandboxEngine } from './ApplicationSandboxEngine' import { ApplicationLifecycleManager } from './ApplicationLifecycleManager' import { externalAppDiscovery } from './ExternalAppDiscovery' -import type { TWindowFormState } from '@/ui/types/WindowFormTypes' /** * 系统服务配置接口 @@ -408,19 +410,16 @@ export class SystemServiceIntegration { }) // 监听窗体数据更新事件 - this.eventBus.addEventListener( - 'onWindowFormDataUpdate', - (data: WindowFormDataUpdateParams) => { - console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data) - // 只有在有订阅者时才发送消息 - if (this.eventService.getChannelSubscriberCount('window-form-data-update') > 0) { - this.eventService.sendMessage('system', 'window-form-data-update', data) - console.log(`[SystemIntegration] 已发送 window-form-data-update 消息到事件通信服务`) - } else { - console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-data-update 消息`) - } - }, - ) + this.eventBus.addEventListener('onWindowFormDataUpdate', (data: WindowFormDataUpdateParams) => { + console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data) + // 只有在有订阅者时才发送消息 + if (this.eventService.getChannelSubscriberCount('window-form-data-update') > 0) { + this.eventService.sendMessage('system', 'window-form-data-update', data) + console.log(`[SystemIntegration] 已发送 window-form-data-update 消息到事件通信服务`) + } else { + console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-data-update 消息`) + } + }) // 监听窗体调整尺寸开始事件 this.eventBus.addEventListener('onWindowFormResizeStart', (windowId: string) => { diff --git a/src/services/WindowService.ts b/src/services/WindowService.ts index c05794d..cfab658 100644 --- a/src/services/WindowService.ts +++ b/src/services/WindowService.ts @@ -288,12 +288,12 @@ export class WindowService { width: '100vw', height: 'calc(100vh - 40px)', // 减去任务栏高度 display: 'block', - transform: 'none' // 确保移除transform + transform: 'none', // 确保移除transform }) } this.setActiveWindow(windowId) - + // 发送窗体数据更新事件 this.notifyWindowFormDataUpdate(windowId) @@ -331,17 +331,17 @@ export class WindowService { height: originalHeight ? `${originalHeight}px` : `${window.config.height}px`, left: originalX ? `${originalX}px` : '0px', top: originalY ? `${originalY}px` : '0px', - transform: 'none' // 确保移除transform + transform: 'none', // 确保移除transform }) - + // 更新配置中的位置 - if (originalX) window.config.x = parseFloat(originalX); - if (originalY) window.config.y = parseFloat(originalY); + if (originalX) window.config.x = parseFloat(originalX) + if (originalY) window.config.y = parseFloat(originalY) } } this.setActiveWindow(windowId) - + // 发送窗体数据更新事件 this.notifyWindowFormDataUpdate(windowId) @@ -381,7 +381,11 @@ export class WindowService { // 检查尺寸限制 const finalWidth = this.clampDimension(width, window.config.minWidth, window.config.maxWidth) - const finalHeight = this.clampDimension(height, window.config.minHeight, window.config.maxHeight) + const finalHeight = this.clampDimension( + height, + window.config.minHeight, + window.config.maxHeight, + ) window.config.width = finalWidth window.config.height = finalHeight @@ -393,7 +397,7 @@ export class WindowService { } this.eventBus.notifyEvent('onResize', windowId, finalWidth, finalHeight) - + // 发送窗体数据更新事件 this.notifyWindowFormDataUpdate(windowId) @@ -436,7 +440,7 @@ export class WindowService { } this.eventBus.notifyEvent('onFocus', windowId) - + // 发送窗体数据更新事件 this.notifyWindowFormDataUpdate(windowId) @@ -465,15 +469,15 @@ export class WindowService { windowElement.id = `window-${id}` // 计算初始位置 - let left = config.x; - let top = config.y; - + let left = config.x + let top = config.y + // 如果没有指定位置,则居中显示 if (left === undefined || top === undefined) { - const centerX = Math.max(0, (window.innerWidth - config.width) / 2); - const centerY = Math.max(0, (window.innerHeight - config.height) / 2); - left = left !== undefined ? left : centerX; - top = top !== undefined ? top : centerY; + const centerX = Math.max(0, (window.innerWidth - config.width) / 2) + const centerY = Math.max(0, (window.innerHeight - config.height) / 2) + left = left !== undefined ? left : centerX + top = top !== undefined ? top : centerY } // 设置基本样式 @@ -489,11 +493,11 @@ export class WindowService { borderRadius: '8px', boxShadow: '0 4px 20px rgba(0,0,0,0.15)', overflow: 'hidden', - }); + }) // 保存初始位置到配置中 - windowInstance.config.x = left; - windowInstance.config.y = top; + windowInstance.config.x = left + windowInstance.config.y = top // 创建窗体标题栏 const titleBar = this.createTitleBar(windowInstance) @@ -519,7 +523,7 @@ export class WindowService { background: #fff; ` contentArea.appendChild(appContainer) - + console.log(`[WindowService] 为内置应用 ${appId} 创建了普通容器`) } else { // 外部应用:创建 iframe 容器 @@ -532,10 +536,10 @@ export class WindowService { ` iframe.sandbox = 'allow-scripts allow-forms allow-popups' // 移除allow-same-origin以提高安全性 contentArea.appendChild(iframe) - + // 保存 iframe 引用(仅对外部应用) windowInstance.iframe = iframe - + console.log(`[WindowService] 为外部应用 ${appId} 创建了 iframe 容器`) } @@ -676,13 +680,13 @@ export class WindowService { titleBar.addEventListener('mousedown', (e) => { // 检查是否正在调整尺寸,如果是则不处理拖拽 if (windowInstance.resizeState?.isResizing) { - return; + return } // 检查是否点击在调整尺寸手柄上,如果是则不处理拖拽 - const target = e.target as HTMLElement; + const target = e.target as HTMLElement if (target.classList.contains('resize-handle')) { - return; + return } if (!windowInstance.element) return @@ -692,17 +696,20 @@ export class WindowService { startY = e.clientY const rect = windowInstance.element.getBoundingClientRect() - + // 如果使用了transform,需要转换为实际坐标 - if (windowInstance.element.style.transform && windowInstance.element.style.transform.includes('translate')) { + if ( + windowInstance.element.style.transform && + windowInstance.element.style.transform.includes('translate') + ) { // 移除transform并设置实际的left/top值 - windowInstance.element.style.transform = 'none'; - windowInstance.config.x = rect.left; - windowInstance.config.y = rect.top; - windowInstance.element.style.left = `${rect.left}px`; - windowInstance.element.style.top = `${rect.top}px`; + windowInstance.element.style.transform = 'none' + windowInstance.config.x = rect.left + windowInstance.config.y = rect.top + windowInstance.element.style.left = `${rect.left}px` + windowInstance.element.style.top = `${rect.top}px` } - + startLeft = rect.left startTop = rect.top @@ -716,7 +723,7 @@ export class WindowService { document.addEventListener('mousemove', (e) => { // 检查是否正在调整尺寸,如果是则不处理拖拽 if (windowInstance.resizeState?.isResizing) { - return; + return } if (!isDragging || !windowInstance.element) return @@ -735,7 +742,7 @@ export class WindowService { windowInstance.config.y = newTop this.eventBus.notifyEvent('onMove', windowInstance.id, newLeft, newTop) - + // 发送窗体数据更新事件 this.notifyWindowFormDataUpdate(windowInstance.id) }) @@ -758,14 +765,14 @@ export class WindowService { startWidth: 0, startHeight: 0, startXPosition: 0, - startYPosition: 0 + startYPosition: 0, } // 创建8个调整尺寸的手柄 const resizeHandles = this.createResizeHandles(windowElement) - + // 添加鼠标事件监听器 - resizeHandles.forEach(handle => { + resizeHandles.forEach((handle) => { this.addResizeHandleEvents(handle, windowElement, windowInstance) }) @@ -787,19 +794,24 @@ export class WindowService { private createResizeHandles(windowElement: HTMLElement): HTMLElement[] { const handles: HTMLElement[] = [] const directions: ResizeDirection[] = [ - 'topLeft', 'top', 'topRight', - 'right', 'bottomRight', 'bottom', - 'bottomLeft', 'left' + 'topLeft', + 'top', + 'topRight', + 'right', + 'bottomRight', + 'bottom', + 'bottomLeft', + 'left', ] - directions.forEach(direction => { + directions.forEach((direction) => { const handle = document.createElement('div') handle.className = `resize-handle resize-handle-${direction}` - + // 设置手柄样式 handle.style.position = 'absolute' handle.style.zIndex = '1001' - + // 根据方向设置位置和光标 switch (direction) { case 'topLeft': @@ -872,9 +884,12 @@ export class WindowService { private addResizeHandleEvents( handle: HTMLElement, windowElement: HTMLElement, - windowInstance: WindowInstance + windowInstance: WindowInstance, ): void { - const direction = handle.className.split(' ').find(cls => cls.startsWith('resize-handle-'))?.split('-')[2] as ResizeDirection + const direction = handle.className + .split(' ') + .find((cls) => cls.startsWith('resize-handle-')) + ?.split('-')[2] as ResizeDirection handle.addEventListener('mousedown', (e) => { if (!windowInstance.resizeState) return @@ -884,15 +899,18 @@ export class WindowService { // 确保窗体位置是最新的 if (windowInstance.element) { - const rect = windowInstance.element.getBoundingClientRect(); + const rect = windowInstance.element.getBoundingClientRect() // 如果使用了transform,需要转换为实际坐标 - if (windowInstance.element.style.transform && windowInstance.element.style.transform.includes('translate')) { + if ( + windowInstance.element.style.transform && + windowInstance.element.style.transform.includes('translate') + ) { // 移除transform并设置实际的left/top值 - windowInstance.element.style.transform = 'none'; - windowInstance.config.x = rect.left; - windowInstance.config.y = rect.top; - windowInstance.element.style.left = `${rect.left}px`; - windowInstance.element.style.top = `${rect.top}px`; + windowInstance.element.style.transform = 'none' + windowInstance.config.x = rect.left + windowInstance.config.y = rect.top + windowInstance.element.style.left = `${rect.left}px` + windowInstance.element.style.top = `${rect.top}px` } } @@ -923,7 +941,7 @@ export class WindowService { private updateCursorForResize( e: MouseEvent, windowElement: HTMLElement, - windowInstance: WindowInstance + windowInstance: WindowInstance, ): void { if (!windowInstance.resizeState) return @@ -942,22 +960,40 @@ export class WindowService { direction = 'topRight' } else if (x >= 0 && x < edgeSize && y > rect.height - edgeSize && y <= rect.height) { direction = 'bottomLeft' - } else if (x > rect.width - edgeSize && x <= rect.width && y > rect.height - edgeSize && y <= rect.height) { + } else if ( + x > rect.width - edgeSize && + x <= rect.width && + y > rect.height - edgeSize && + y <= rect.height + ) { direction = 'bottomRight' - } + } // 然后检查边缘区域 else if (x >= 0 && x < edgeSize && y >= edgeSize && y <= rect.height - edgeSize) { direction = 'left' - } else if (x > rect.width - edgeSize && x <= rect.width && y >= edgeSize && y <= rect.height - edgeSize) { + } else if ( + x > rect.width - edgeSize && + x <= rect.width && + y >= edgeSize && + y <= rect.height - edgeSize + ) { direction = 'right' } else if (y >= 0 && y < edgeSize && x >= edgeSize && x <= rect.width - edgeSize) { direction = 'top' - } else if (y > rect.height - edgeSize && y <= rect.height && x >= edgeSize && x <= rect.width - edgeSize) { + } else if ( + y > rect.height - edgeSize && + y <= rect.height && + x >= edgeSize && + x <= rect.width - edgeSize + ) { direction = 'bottom' } // 更新光标样式 - windowElement.style.cursor = direction === 'none' ? 'default' : `${direction.replace(/([A-Z])/g, '-$1').toLowerCase()}-resize` + windowElement.style.cursor = + direction === 'none' + ? 'default' + : `${direction.replace(/([A-Z])/g, '-$1').toLowerCase()}-resize` } /** @@ -981,21 +1017,14 @@ export class WindowService { private handleResizeMouseMove(e: MouseEvent): void { // 找到正在调整尺寸的窗体 const resizingWindow = Array.from(this.windows.values()).find( - window => window.resizeState?.isResizing + (window) => window.resizeState?.isResizing, ) // 如果没有正在调整尺寸的窗体,直接返回 if (!resizingWindow || !resizingWindow.resizeState || !resizingWindow.element) return - const { - direction, - startX, - startY, - startWidth, - startHeight, - startXPosition, - startYPosition - } = resizingWindow.resizeState + const { direction, startX, startY, startWidth, startHeight, startXPosition, startYPosition } = + resizingWindow.resizeState const deltaX = e.clientX - startX const deltaY = e.clientY - startY @@ -1044,8 +1073,16 @@ export class WindowService { } // 应用尺寸限制 - newWidth = this.clampDimension(newWidth, resizingWindow.config.minWidth, resizingWindow.config.maxWidth) - newHeight = this.clampDimension(newHeight, resizingWindow.config.minHeight, resizingWindow.config.maxHeight) + newWidth = this.clampDimension( + newWidth, + resizingWindow.config.minWidth, + resizingWindow.config.maxWidth, + ) + newHeight = this.clampDimension( + newHeight, + resizingWindow.config.minHeight, + resizingWindow.config.maxHeight, + ) // 应用新尺寸和位置 resizingWindow.config.width = newWidth @@ -1063,7 +1100,7 @@ export class WindowService { // 触发调整尺寸事件 this.eventBus.notifyEvent('onResizing', resizingWindow.id, newWidth, newHeight) - + // 发送窗体数据更新事件 this.notifyWindowFormDataUpdate(resizingWindow.id) } @@ -1074,7 +1111,7 @@ export class WindowService { private handleResizeMouseUp(): void { // 找到正在调整尺寸的窗体 const resizingWindow = Array.from(this.windows.values()).find( - window => window.resizeState?.isResizing + (window) => window.resizeState?.isResizing, ) if (!resizingWindow || !resizingWindow.resizeState || !resizingWindow.element) return @@ -1087,7 +1124,7 @@ export class WindowService { // 触发调整尺寸结束事件 this.eventBus.notifyEvent('onResizeEnd', resizingWindow.id) - + // 发送窗体数据更新事件 this.notifyWindowFormDataUpdate(resizingWindow.id) } @@ -1114,7 +1151,7 @@ export class WindowService { width: window.config.width, height: window.config.height, x: window.config.x !== undefined ? window.config.x : rect.left, - y: window.config.y !== undefined ? window.config.y : rect.top + y: window.config.y !== undefined ? window.config.y : rect.top, } // 发送事件到事件总线 @@ -1129,7 +1166,7 @@ export class WindowService { try { const { AppRegistry } = await import('../apps/AppRegistry') const appRegistry = AppRegistry.getInstance() - + // 如果是内置应用,直接返回,不需要等待 if (appRegistry.hasApp(windowInstance.appId)) { console.log(`[WindowService] 内置应用 ${windowInstance.appId} 无需等待加载`) @@ -1138,7 +1175,7 @@ export class WindowService { } catch (error) { console.warn('无法导入 AppRegistry,使用传统加载方式') } - + // 对于外部应用,保持原有的加载逻辑 return new Promise((resolve) => { console.log(`[WindowService] 开始加载外部应用 ${windowInstance.appId}`) @@ -1174,18 +1211,18 @@ export class WindowService { if (!window) return const oldState = window.state - + // 只有状态真正发生变化时才触发事件 if (oldState === newState) return - + window.state = newState window.updatedAt = new Date() // 所有状态变化都应该触发事件,这是正常的系统行为 console.log(`[WindowService] 窗体状态变化: ${windowId} ${oldState} -> ${newState}`) this.eventBus.notifyEvent('onStateChange', windowId, newState, oldState) - + // 发送窗体数据更新事件 this.notifyWindowFormDataUpdate(windowId) } -} \ No newline at end of file +}