This commit is contained in:
2025-09-28 14:32:07 +08:00
parent f1ba609254
commit a56197a349
6 changed files with 284 additions and 101 deletions

View File

@@ -2,5 +2,17 @@
"$schema": "https://json.schemastore.org/prettierrc", "$schema": "https://json.schemastore.org/prettierrc",
"semi": false, "semi": false,
"singleQuote": true, "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
} }

134
PRETTIER_CONFIG_GUIDE.md Normal file
View File

@@ -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 文件中单文件组件的脚本和样式标签内是否缩进

View File

@@ -1,5 +1,5 @@
import type { AppRegistration } from './types/AppManifest' import type { AppRegistration } from './types/AppManifest'
import { reactive, markRaw } from 'vue' import { reactive } from 'vue'
/** /**
* 应用注册中心 * 应用注册中心

View File

@@ -16,7 +16,7 @@ registerBuiltInApps()
const systemService = new SystemServiceIntegration({ const systemService = new SystemServiceIntegration({
debug: import.meta.env.DEV, debug: import.meta.env.DEV,
enablePerformanceMonitoring: true, enablePerformanceMonitoring: true,
enableSecurityAudit: true enableSecurityAudit: true,
}) })
// 创建应用实例 // 创建应用实例
@@ -30,7 +30,8 @@ app.use(naiveUi)
app.provide('systemService', systemService) app.provide('systemService', systemService)
// 初始化系统服务然后挂载应用 // 初始化系统服务然后挂载应用
systemService.initialize() systemService
.initialize()
.then(() => { .then(() => {
app.mount('#app') app.mount('#app')
console.log('桌面系统启动完成') console.log('桌面系统启动完成')

View File

@@ -1,7 +1,10 @@
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl' import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl'
import type { IEventBuilder } from '@/events/IEventBuilder' import type { IEventBuilder } from '@/events/IEventBuilder'
import type { EventCommunicationEvents, WindowFormDataUpdateParams } from './EventCommunicationService' import type {
EventCommunicationEvents,
WindowFormDataUpdateParams,
} from './EventCommunicationService'
import type { ResourceType } from './ResourceService' import type { ResourceType } from './ResourceService'
// 导入所有服务 // 导入所有服务
@@ -11,7 +14,6 @@ import { EventCommunicationService } from './EventCommunicationService'
import { ApplicationSandboxEngine } from './ApplicationSandboxEngine' import { ApplicationSandboxEngine } from './ApplicationSandboxEngine'
import { ApplicationLifecycleManager } from './ApplicationLifecycleManager' import { ApplicationLifecycleManager } from './ApplicationLifecycleManager'
import { externalAppDiscovery } from './ExternalAppDiscovery' import { externalAppDiscovery } from './ExternalAppDiscovery'
import type { TWindowFormState } from '@/ui/types/WindowFormTypes'
/** /**
* 系统服务配置接口 * 系统服务配置接口
@@ -408,19 +410,16 @@ export class SystemServiceIntegration {
}) })
// 监听窗体数据更新事件 // 监听窗体数据更新事件
this.eventBus.addEventListener( this.eventBus.addEventListener('onWindowFormDataUpdate', (data: WindowFormDataUpdateParams) => {
'onWindowFormDataUpdate', console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data)
(data: WindowFormDataUpdateParams) => { // 只有在有订阅者时才发送消息
console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data) if (this.eventService.getChannelSubscriberCount('window-form-data-update') > 0) {
// 只有在有订阅者时才发送消息 this.eventService.sendMessage('system', 'window-form-data-update', data)
if (this.eventService.getChannelSubscriberCount('window-form-data-update') > 0) { console.log(`[SystemIntegration] 已发送 window-form-data-update 消息到事件通信服务`)
this.eventService.sendMessage('system', 'window-form-data-update', data) } else {
console.log(`[SystemIntegration] 发送 window-form-data-update 消息到事件通信服务`) console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-data-update 消息`)
} else { }
console.log(`[SystemIntegration] 无订阅者,跳过发送 window-form-data-update 消息`) })
}
},
)
// 监听窗体调整尺寸开始事件 // 监听窗体调整尺寸开始事件
this.eventBus.addEventListener('onWindowFormResizeStart', (windowId: string) => { this.eventBus.addEventListener('onWindowFormResizeStart', (windowId: string) => {

View File

@@ -288,7 +288,7 @@ export class WindowService {
width: '100vw', width: '100vw',
height: 'calc(100vh - 40px)', // 减去任务栏高度 height: 'calc(100vh - 40px)', // 减去任务栏高度
display: 'block', display: 'block',
transform: 'none' // 确保移除transform transform: 'none', // 确保移除transform
}) })
} }
@@ -331,12 +331,12 @@ export class WindowService {
height: originalHeight ? `${originalHeight}px` : `${window.config.height}px`, height: originalHeight ? `${originalHeight}px` : `${window.config.height}px`,
left: originalX ? `${originalX}px` : '0px', left: originalX ? `${originalX}px` : '0px',
top: originalY ? `${originalY}px` : '0px', top: originalY ? `${originalY}px` : '0px',
transform: 'none' // 确保移除transform transform: 'none', // 确保移除transform
}) })
// 更新配置中的位置 // 更新配置中的位置
if (originalX) window.config.x = parseFloat(originalX); if (originalX) window.config.x = parseFloat(originalX)
if (originalY) window.config.y = parseFloat(originalY); if (originalY) window.config.y = parseFloat(originalY)
} }
} }
@@ -381,7 +381,11 @@ export class WindowService {
// 检查尺寸限制 // 检查尺寸限制
const finalWidth = this.clampDimension(width, window.config.minWidth, window.config.maxWidth) 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.width = finalWidth
window.config.height = finalHeight window.config.height = finalHeight
@@ -465,15 +469,15 @@ export class WindowService {
windowElement.id = `window-${id}` windowElement.id = `window-${id}`
// 计算初始位置 // 计算初始位置
let left = config.x; let left = config.x
let top = config.y; let top = config.y
// 如果没有指定位置,则居中显示 // 如果没有指定位置,则居中显示
if (left === undefined || top === undefined) { if (left === undefined || top === undefined) {
const centerX = Math.max(0, (window.innerWidth - config.width) / 2); const centerX = Math.max(0, (window.innerWidth - config.width) / 2)
const centerY = Math.max(0, (window.innerHeight - config.height) / 2); const centerY = Math.max(0, (window.innerHeight - config.height) / 2)
left = left !== undefined ? left : centerX; left = left !== undefined ? left : centerX
top = top !== undefined ? top : centerY; top = top !== undefined ? top : centerY
} }
// 设置基本样式 // 设置基本样式
@@ -489,11 +493,11 @@ export class WindowService {
borderRadius: '8px', borderRadius: '8px',
boxShadow: '0 4px 20px rgba(0,0,0,0.15)', boxShadow: '0 4px 20px rgba(0,0,0,0.15)',
overflow: 'hidden', overflow: 'hidden',
}); })
// 保存初始位置到配置中 // 保存初始位置到配置中
windowInstance.config.x = left; windowInstance.config.x = left
windowInstance.config.y = top; windowInstance.config.y = top
// 创建窗体标题栏 // 创建窗体标题栏
const titleBar = this.createTitleBar(windowInstance) const titleBar = this.createTitleBar(windowInstance)
@@ -676,13 +680,13 @@ export class WindowService {
titleBar.addEventListener('mousedown', (e) => { titleBar.addEventListener('mousedown', (e) => {
// 检查是否正在调整尺寸,如果是则不处理拖拽 // 检查是否正在调整尺寸,如果是则不处理拖拽
if (windowInstance.resizeState?.isResizing) { if (windowInstance.resizeState?.isResizing) {
return; return
} }
// 检查是否点击在调整尺寸手柄上,如果是则不处理拖拽 // 检查是否点击在调整尺寸手柄上,如果是则不处理拖拽
const target = e.target as HTMLElement; const target = e.target as HTMLElement
if (target.classList.contains('resize-handle')) { if (target.classList.contains('resize-handle')) {
return; return
} }
if (!windowInstance.element) return if (!windowInstance.element) return
@@ -694,13 +698,16 @@ export class WindowService {
const rect = windowInstance.element.getBoundingClientRect() const rect = windowInstance.element.getBoundingClientRect()
// 如果使用了transform需要转换为实际坐标 // 如果使用了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值 // 移除transform并设置实际的left/top值
windowInstance.element.style.transform = 'none'; windowInstance.element.style.transform = 'none'
windowInstance.config.x = rect.left; windowInstance.config.x = rect.left
windowInstance.config.y = rect.top; windowInstance.config.y = rect.top
windowInstance.element.style.left = `${rect.left}px`; windowInstance.element.style.left = `${rect.left}px`
windowInstance.element.style.top = `${rect.top}px`; windowInstance.element.style.top = `${rect.top}px`
} }
startLeft = rect.left startLeft = rect.left
@@ -716,7 +723,7 @@ export class WindowService {
document.addEventListener('mousemove', (e) => { document.addEventListener('mousemove', (e) => {
// 检查是否正在调整尺寸,如果是则不处理拖拽 // 检查是否正在调整尺寸,如果是则不处理拖拽
if (windowInstance.resizeState?.isResizing) { if (windowInstance.resizeState?.isResizing) {
return; return
} }
if (!isDragging || !windowInstance.element) return if (!isDragging || !windowInstance.element) return
@@ -758,14 +765,14 @@ export class WindowService {
startWidth: 0, startWidth: 0,
startHeight: 0, startHeight: 0,
startXPosition: 0, startXPosition: 0,
startYPosition: 0 startYPosition: 0,
} }
// 创建8个调整尺寸的手柄 // 创建8个调整尺寸的手柄
const resizeHandles = this.createResizeHandles(windowElement) const resizeHandles = this.createResizeHandles(windowElement)
// 添加鼠标事件监听器 // 添加鼠标事件监听器
resizeHandles.forEach(handle => { resizeHandles.forEach((handle) => {
this.addResizeHandleEvents(handle, windowElement, windowInstance) this.addResizeHandleEvents(handle, windowElement, windowInstance)
}) })
@@ -787,12 +794,17 @@ export class WindowService {
private createResizeHandles(windowElement: HTMLElement): HTMLElement[] { private createResizeHandles(windowElement: HTMLElement): HTMLElement[] {
const handles: HTMLElement[] = [] const handles: HTMLElement[] = []
const directions: ResizeDirection[] = [ const directions: ResizeDirection[] = [
'topLeft', 'top', 'topRight', 'topLeft',
'right', 'bottomRight', 'bottom', 'top',
'bottomLeft', 'left' 'topRight',
'right',
'bottomRight',
'bottom',
'bottomLeft',
'left',
] ]
directions.forEach(direction => { directions.forEach((direction) => {
const handle = document.createElement('div') const handle = document.createElement('div')
handle.className = `resize-handle resize-handle-${direction}` handle.className = `resize-handle resize-handle-${direction}`
@@ -872,9 +884,12 @@ export class WindowService {
private addResizeHandleEvents( private addResizeHandleEvents(
handle: HTMLElement, handle: HTMLElement,
windowElement: HTMLElement, windowElement: HTMLElement,
windowInstance: WindowInstance windowInstance: WindowInstance,
): void { ): 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) => { handle.addEventListener('mousedown', (e) => {
if (!windowInstance.resizeState) return if (!windowInstance.resizeState) return
@@ -884,15 +899,18 @@ export class WindowService {
// 确保窗体位置是最新的 // 确保窗体位置是最新的
if (windowInstance.element) { if (windowInstance.element) {
const rect = windowInstance.element.getBoundingClientRect(); const rect = windowInstance.element.getBoundingClientRect()
// 如果使用了transform需要转换为实际坐标 // 如果使用了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值 // 移除transform并设置实际的left/top值
windowInstance.element.style.transform = 'none'; windowInstance.element.style.transform = 'none'
windowInstance.config.x = rect.left; windowInstance.config.x = rect.left
windowInstance.config.y = rect.top; windowInstance.config.y = rect.top
windowInstance.element.style.left = `${rect.left}px`; windowInstance.element.style.left = `${rect.left}px`
windowInstance.element.style.top = `${rect.top}px`; windowInstance.element.style.top = `${rect.top}px`
} }
} }
@@ -923,7 +941,7 @@ export class WindowService {
private updateCursorForResize( private updateCursorForResize(
e: MouseEvent, e: MouseEvent,
windowElement: HTMLElement, windowElement: HTMLElement,
windowInstance: WindowInstance windowInstance: WindowInstance,
): void { ): void {
if (!windowInstance.resizeState) return if (!windowInstance.resizeState) return
@@ -942,22 +960,40 @@ export class WindowService {
direction = 'topRight' direction = 'topRight'
} else if (x >= 0 && x < edgeSize && y > rect.height - edgeSize && y <= rect.height) { } else if (x >= 0 && x < edgeSize && y > rect.height - edgeSize && y <= rect.height) {
direction = 'bottomLeft' 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' direction = 'bottomRight'
} }
// 然后检查边缘区域 // 然后检查边缘区域
else if (x >= 0 && x < edgeSize && y >= edgeSize && y <= rect.height - edgeSize) { else if (x >= 0 && x < edgeSize && y >= edgeSize && y <= rect.height - edgeSize) {
direction = 'left' 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' direction = 'right'
} else if (y >= 0 && y < edgeSize && x >= edgeSize && x <= rect.width - edgeSize) { } else if (y >= 0 && y < edgeSize && x >= edgeSize && x <= rect.width - edgeSize) {
direction = 'top' 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' 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 { private handleResizeMouseMove(e: MouseEvent): void {
// 找到正在调整尺寸的窗体 // 找到正在调整尺寸的窗体
const resizingWindow = Array.from(this.windows.values()).find( const resizingWindow = Array.from(this.windows.values()).find(
window => window.resizeState?.isResizing (window) => window.resizeState?.isResizing,
) )
// 如果没有正在调整尺寸的窗体,直接返回 // 如果没有正在调整尺寸的窗体,直接返回
if (!resizingWindow || !resizingWindow.resizeState || !resizingWindow.element) return if (!resizingWindow || !resizingWindow.resizeState || !resizingWindow.element) return
const { const { direction, startX, startY, startWidth, startHeight, startXPosition, startYPosition } =
direction, resizingWindow.resizeState
startX,
startY,
startWidth,
startHeight,
startXPosition,
startYPosition
} = resizingWindow.resizeState
const deltaX = e.clientX - startX const deltaX = e.clientX - startX
const deltaY = e.clientY - startY const deltaY = e.clientY - startY
@@ -1044,8 +1073,16 @@ export class WindowService {
} }
// 应用尺寸限制 // 应用尺寸限制
newWidth = this.clampDimension(newWidth, resizingWindow.config.minWidth, resizingWindow.config.maxWidth) newWidth = this.clampDimension(
newHeight = this.clampDimension(newHeight, resizingWindow.config.minHeight, resizingWindow.config.maxHeight) newWidth,
resizingWindow.config.minWidth,
resizingWindow.config.maxWidth,
)
newHeight = this.clampDimension(
newHeight,
resizingWindow.config.minHeight,
resizingWindow.config.maxHeight,
)
// 应用新尺寸和位置 // 应用新尺寸和位置
resizingWindow.config.width = newWidth resizingWindow.config.width = newWidth
@@ -1074,7 +1111,7 @@ export class WindowService {
private handleResizeMouseUp(): void { private handleResizeMouseUp(): void {
// 找到正在调整尺寸的窗体 // 找到正在调整尺寸的窗体
const resizingWindow = Array.from(this.windows.values()).find( const resizingWindow = Array.from(this.windows.values()).find(
window => window.resizeState?.isResizing (window) => window.resizeState?.isResizing,
) )
if (!resizingWindow || !resizingWindow.resizeState || !resizingWindow.element) return if (!resizingWindow || !resizingWindow.resizeState || !resizingWindow.element) return
@@ -1114,7 +1151,7 @@ export class WindowService {
width: window.config.width, width: window.config.width,
height: window.config.height, height: window.config.height,
x: window.config.x !== undefined ? window.config.x : rect.left, 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,
} }
// 发送事件到事件总线 // 发送事件到事件总线