This commit is contained in:
2025-09-24 16:43:10 +08:00
parent 12f46e6f8e
commit 9dbc054483
130 changed files with 16474 additions and 4660 deletions

View File

@@ -1,23 +1,275 @@
<template>
<div class="desktop-icons-container" :style="gridStyle">
<AppIcon
v-for="(appIcon, i) in appIconsRef"
:key="i"
:iconInfo="appIcon"
:gridTemplate="gridTemplate"
@dblclick="runApp(appIcon)"
/>
<AppIcon v-for="(appIcon, i) in appIconsRef" :key="i" :iconInfo="appIcon" :gridTemplate="gridTemplate"
@dblclick="runApp(appIcon)" />
<!-- 系统状态显示 -->
<div v-if="showSystemStatus" class="system-status-overlay">
<div class="status-panel">
<h3>系统状态</h3>
<div class="status-item">
<span>运行状态:</span>
<span :class="{ 'status-ok': systemStatus.running, 'status-error': !systemStatus.running }">
{{ systemStatus.running ? '正常' : '错误' }}
</span>
</div>
<div class="status-item">
<span>活跃应用:</span>
<span>{{ systemStatus.performance.activeApps }}</span>
</div>
<div class="status-item">
<span>活跃窗体:</span>
<span>{{ systemStatus.performance.activeWindows }}</span>
</div>
<div class="status-item">
<span>内存使用:</span>
<span>{{ Math.round(systemStatus.performance.memoryUsage) }}MB</span>
</div>
<button @click="showSystemStatus = false" class="close-btn">关闭</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { inject, ref, onMounted, onUnmounted } from 'vue'
import AppIcon from '@/ui/desktop-container/AppIcon.vue'
import type { IDesktopAppIcon } from '@/ui/types/IDesktopAppIcon.ts'
import { useDesktopContainerInit } from '@/ui/desktop-container/useDesktopContainerInit.ts'
import { useDynamicAppIcons, getAppIdFromIcon } from '@/ui/desktop-container/useDynamicAppIcons.ts'
import type { SystemServiceIntegration } from '@/services/SystemServiceIntegration'
import type { SystemStatus } from '@/services/SystemServiceIntegration'
import { appRegistry } from '@/apps'
import { externalAppDiscovery } from '@/services/ExternalAppDiscovery'
const { appIconsRef, gridStyle, gridTemplate } = useDesktopContainerInit('.desktop-icons-container')
const { getAppIconsWithPositions, saveIconPositions, refreshApps } = useDynamicAppIcons()
const runApp = (appIcon: IDesktopAppIcon) => {}
// 使用动态应用图标替换静态列表
const updateAppIcons = () => {
const dynamicIcons = getAppIconsWithPositions()
appIconsRef.value = dynamicIcons
}
// 初始加载应用图标
updateAppIcons()
// 注入系统服务和窗口管理器
const systemService = inject<SystemServiceIntegration>('systemService')
const windowManager = inject<any>('windowManager')
const showSystemStatus = ref(false)
const systemStatus = ref<SystemStatus>({
initialized: false,
running: false,
servicesStatus: {
windowService: false,
resourceService: false,
eventService: false,
sandboxEngine: false,
lifecycleManager: false
},
performance: {
memoryUsage: 0,
cpuUsage: 0,
activeApps: 0,
activeWindows: 0
},
uptime: 0
})
let statusUpdateInterval: number | null = null
// 更新系统状态
const updateSystemStatus = async () => {
if (!systemService) return
try {
const status = await systemService.getSystemStatus()
systemStatus.value = status
} catch (error) {
console.error('获取系统状态失败:', error)
}
}
// 运行应用
const runApp = async (appIcon: IDesktopAppIcon) => {
if (!systemService) {
console.error('系统服务未初始化')
return
}
try {
if (appIcon.name === '系统状态') {
showSystemStatus.value = true
updateSystemStatus()
} else {
const appId = getAppIdFromIcon(appIcon)
await startApp(appId)
}
} catch (error) {
console.error('启动应用失败:', error)
}
}
// 启动应用(支持内置和外部应用)
const startApp = async (appId: string) => {
if (!systemService) return
try {
const lifecycleManager = systemService.getLifecycleManager()
// 检查是否为内置应用
if (appRegistry.hasApp(appId)) {
// 内置应用:使用主应用的窗口管理器
const appRegistration = appRegistry.getApp(appId)!
// 检查是否已在运行
if (lifecycleManager.isAppRunning(appId)) {
console.log(`应用 ${appRegistration.manifest.name} 已在运行`)
return
}
// 创建窗口
const windowService = systemService.getWindowService()
const windowConfig = {
title: appRegistration.manifest.name,
width: appRegistration.manifest.window.width,
height: appRegistration.manifest.window.height,
minWidth: appRegistration.manifest.window.minWidth,
minHeight: appRegistration.manifest.window.minHeight,
resizable: appRegistration.manifest.window.resizable !== false
}
const windowInstance = await windowService.createWindow(appId, windowConfig)
// 使用主应用的窗口管理器来渲染内置应用
if (windowManager?.value) {
windowManager.value.addBuiltInWindow(windowInstance.id, appId)
console.log(`[主应用] 使用窗口管理器渲染内置应用: ${appId}`)
} else {
console.error('窗口管理器未初始化')
}
} else if (externalAppDiscovery.hasApp(appId)) {
// 外置应用直接使用ApplicationLifecycleManager
console.log(`启动外置应用: ${appId}`)
if (!lifecycleManager.isAppRunning(appId)) {
await lifecycleManager.startApp(appId)
console.log(`外置应用 ${appId} 启动成功`)
} else {
console.log(`外置应用 ${appId} 已在运行`)
}
} else {
console.error(`未知的应用: ${appId}`)
}
} catch (error) {
console.error('启动应用失败:', error)
}
}
// 手动刷新应用列表(通过右键菜单调用)
const manualRefreshApps = async () => {
try {
await refreshApps()
updateAppIcons()
console.log('[DesktopContainer] 应用列表已手动刷新')
} catch (error) {
console.error('[DesktopContainer] 手动刷新应用列表失败:', error)
}
}
// 暴露手动刷新方法给父组件使用
defineExpose({
manualRefreshApps
})
// 初始化和清理
onMounted(async () => {
// 开始系统状态更新
statusUpdateInterval = setInterval(updateSystemStatus, 5000)
updateSystemStatus()
// 不再设置自动刷新定时器,只在需要时手动刷新
})
onUnmounted(() => {
if (statusUpdateInterval) {
clearInterval(statusUpdateInterval)
statusUpdateInterval = null
}
})
</script>
<style scoped></style>
<style scoped>
.desktop-icons-container {
position: relative;
width: 100%;
height: 100%;
}
.system-status-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.status-panel {
background: white;
border-radius: 8px;
padding: 24px;
min-width: 300px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
.status-panel h3 {
margin: 0 0 16px 0;
color: #333;
text-align: center;
}
.status-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;
}
.status-item:last-of-type {
border-bottom: none;
}
.status-ok {
color: #28a745;
font-weight: 500;
}
.status-error {
color: #dc3545;
font-weight: 500;
}
.close-btn {
width: 100%;
padding: 8px 16px;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 16px;
transition: background 0.2s;
}
.close-btn:hover {
background: #0056b3;
}
</style>