2025-09-24 16:43:10 +08:00
|
|
|
|
import type { AppRegistration } from './types/AppManifest'
|
|
|
|
|
|
import { reactive, markRaw } from 'vue'
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 应用注册中心
|
|
|
|
|
|
* 管理所有内置应用的注册和获取
|
|
|
|
|
|
*/
|
|
|
|
|
|
export class AppRegistry {
|
|
|
|
|
|
private static instance: AppRegistry | null = null
|
|
|
|
|
|
private apps = reactive(new Map<string, AppRegistration>())
|
|
|
|
|
|
|
|
|
|
|
|
private constructor() {}
|
|
|
|
|
|
|
|
|
|
|
|
static getInstance(): AppRegistry {
|
|
|
|
|
|
if (!AppRegistry.instance) {
|
|
|
|
|
|
AppRegistry.instance = new AppRegistry()
|
|
|
|
|
|
}
|
|
|
|
|
|
return AppRegistry.instance
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 注册内置应用
|
|
|
|
|
|
*/
|
|
|
|
|
|
registerApp(registration: AppRegistration): void {
|
|
|
|
|
|
// 使用 markRaw 标记组件,避免被设为响应式
|
2025-09-25 15:31:11 +08:00
|
|
|
|
// 注意:对于异步组件,我们不立即标记为raw,而是在实际加载时处理
|
2025-09-24 16:43:10 +08:00
|
|
|
|
const safeRegistration = {
|
|
|
|
|
|
...registration,
|
2025-09-25 15:31:11 +08:00
|
|
|
|
component: registration.component,
|
2025-09-24 16:43:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
this.apps.set(registration.manifest.id, safeRegistration)
|
|
|
|
|
|
console.log(`已注册内置应用: ${registration.manifest.name}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取应用
|
|
|
|
|
|
*/
|
|
|
|
|
|
getApp(appId: string): AppRegistration | undefined {
|
|
|
|
|
|
return this.apps.get(appId)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取所有应用
|
|
|
|
|
|
*/
|
|
|
|
|
|
getAllApps(): AppRegistration[] {
|
|
|
|
|
|
return Array.from(this.apps.values())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取所有内置应用
|
|
|
|
|
|
*/
|
|
|
|
|
|
getBuiltInApps(): AppRegistration[] {
|
2025-09-25 15:31:11 +08:00
|
|
|
|
return Array.from(this.apps.values()).filter((app) => app.isBuiltIn)
|
2025-09-24 16:43:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 检查应用是否存在
|
|
|
|
|
|
*/
|
|
|
|
|
|
hasApp(appId: string): boolean {
|
|
|
|
|
|
return this.apps.has(appId)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 按类别获取应用
|
|
|
|
|
|
*/
|
|
|
|
|
|
getAppsByCategory(category: string): AppRegistration[] {
|
2025-09-25 15:31:11 +08:00
|
|
|
|
return Array.from(this.apps.values()).filter((app) => app.manifest.category === category)
|
2025-09-24 16:43:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 搜索应用
|
|
|
|
|
|
*/
|
|
|
|
|
|
searchApps(query: string): AppRegistration[] {
|
|
|
|
|
|
const lowercaseQuery = query.toLowerCase()
|
2025-09-25 15:31:11 +08:00
|
|
|
|
return Array.from(this.apps.values()).filter((app) => {
|
2025-09-24 16:43:10 +08:00
|
|
|
|
const manifest = app.manifest
|
|
|
|
|
|
return (
|
|
|
|
|
|
manifest.name.toLowerCase().includes(lowercaseQuery) ||
|
|
|
|
|
|
manifest.description.toLowerCase().includes(lowercaseQuery) ||
|
2025-09-25 15:31:11 +08:00
|
|
|
|
manifest.keywords?.some((keyword) => keyword.toLowerCase().includes(lowercaseQuery))
|
2025-09-24 16:43:10 +08:00
|
|
|
|
)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 清空所有应用
|
|
|
|
|
|
*/
|
|
|
|
|
|
clear(): void {
|
|
|
|
|
|
this.apps.clear()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 导出单例实例
|
2025-09-25 15:31:11 +08:00
|
|
|
|
export const appRegistry = AppRegistry.getInstance()
|