150 lines
3.9 KiB
Vue
150 lines
3.9 KiB
Vue
<template>
|
|
<div class="window-manager">
|
|
<!-- 所有已打开的内置应用窗口 -->
|
|
<teleport
|
|
v-for="window in builtInWindows"
|
|
:key="window.id"
|
|
:to="`#app-container-${window.appId}`"
|
|
>
|
|
<component
|
|
:is="window.component"
|
|
:key="window.id"
|
|
v-bind="window.props"
|
|
@close="closeWindow(window.id)"
|
|
/>
|
|
</teleport>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, inject, onMounted, onUnmounted } from 'vue'
|
|
import type { SystemServiceIntegration } from '@/services/SystemServiceIntegration'
|
|
import { appRegistry } from '@/apps'
|
|
|
|
interface BuiltInWindow {
|
|
id: string
|
|
appId: string
|
|
component: any
|
|
props: Record<string, any>
|
|
}
|
|
|
|
// 存储所有已打开的内置应用窗口
|
|
const builtInWindows = ref<BuiltInWindow[]>([])
|
|
|
|
// 注入系统服务
|
|
const systemService = inject<SystemServiceIntegration>('systemService')
|
|
|
|
// 添加内置应用窗口
|
|
const addBuiltInWindow = async (windowId: string, appId: string) => {
|
|
// 检查应用是否存在
|
|
const appRegistration = appRegistry.getApp(appId)
|
|
if (!appRegistration) {
|
|
console.error(`内置应用 ${appId} 不存在`)
|
|
return
|
|
}
|
|
|
|
// 检查窗口是否已存在
|
|
const existingWindow = builtInWindows.value.find(w => w.id === windowId)
|
|
if (existingWindow) {
|
|
console.warn(`窗口 ${windowId} 已存在`)
|
|
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,
|
|
props: {
|
|
windowId,
|
|
appId
|
|
}
|
|
}
|
|
|
|
builtInWindows.value.push(window)
|
|
console.log(`[WindowManager] 添加内置应用窗口: ${appId} (${windowId})`)
|
|
}
|
|
|
|
// 关闭内置应用窗口
|
|
const closeWindow = (windowId: string) => {
|
|
const index = builtInWindows.value.findIndex(w => w.id === windowId)
|
|
if (index > -1) {
|
|
const window = builtInWindows.value[index]
|
|
builtInWindows.value.splice(index, 1)
|
|
console.log(`[WindowManager] 关闭内置应用窗口: ${window.appId} (${windowId})`)
|
|
|
|
// 通知系统服务关闭窗口
|
|
if (systemService) {
|
|
const windowService = systemService.getWindowService()
|
|
windowService.destroyWindow(windowId)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 移除内置应用窗口(不关闭系统窗口)
|
|
const removeBuiltInWindow = (windowId: string) => {
|
|
const index = builtInWindows.value.findIndex(w => w.id === windowId)
|
|
if (index > -1) {
|
|
const window = builtInWindows.value[index]
|
|
builtInWindows.value.splice(index, 1)
|
|
console.log(`[WindowManager] 移除内置应用窗口: ${window.appId} (${windowId})`)
|
|
}
|
|
}
|
|
|
|
// 监听窗口事件
|
|
let eventUnsubscriber: (() => void) | null = null
|
|
|
|
onMounted(() => {
|
|
if (systemService) {
|
|
const eventService = systemService.getEventService()
|
|
|
|
// 监听内置应用窗口创建事件
|
|
const subscriberId = eventService.subscribe('system', 'built-in-window-created', async (message) => {
|
|
const { windowId, appId } = message.payload
|
|
await addBuiltInWindow(windowId, appId)
|
|
})
|
|
|
|
// 监听内置应用窗口关闭事件
|
|
const closeSubscriberId = eventService.subscribe('system', 'built-in-window-closed', (message) => {
|
|
const { windowId } = message.payload
|
|
removeBuiltInWindow(windowId)
|
|
})
|
|
|
|
eventUnsubscriber = () => {
|
|
eventService.unsubscribe(subscriberId)
|
|
eventService.unsubscribe(closeSubscriberId)
|
|
}
|
|
}
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
if (eventUnsubscriber) {
|
|
eventUnsubscriber()
|
|
}
|
|
})
|
|
|
|
// 暴露给全局使用
|
|
defineExpose({
|
|
addBuiltInWindow,
|
|
removeBuiltInWindow,
|
|
closeWindow
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.window-manager {
|
|
/* 这个组件本身不需要样式,它只是用来管理 teleport */
|
|
}
|
|
</style> |