diff --git a/apps/jingrow/frontend/src/views/dev/AppMarketplace.vue b/apps/jingrow/frontend/src/views/dev/AppMarketplace.vue index a01cf6d..1710049 100644 --- a/apps/jingrow/frontend/src/views/dev/AppMarketplace.vue +++ b/apps/jingrow/frontend/src/views/dev/AppMarketplace.vue @@ -94,7 +94,18 @@ {{ t('View Details') }} - + + {{ t('Update') }} + + {{ t('Install') }} @@ -171,6 +182,9 @@ const installMessage = ref('') const installStatus = ref<'success' | 'error' | 'info'>('info') const showProgressModal = ref(false) +// 已安装应用集合 +const installedAppNames = ref>(new Set()) + // 排序选项 const sortOptions = computed(() => [ { label: t('Latest'), value: 'creation desc' }, @@ -300,6 +314,9 @@ async function performInstall(app: any) { installMessage.value = t('应用安装成功!') message.success(t('应用安装成功')) + // 刷新已安装应用列表 + loadInstalledApps() + setTimeout(() => { showProgressModal.value = false }, 2000) @@ -341,8 +358,41 @@ function truncateText(text: string, maxLength: number): string { return text.substring(0, maxLength) + '...' } +// 加载已安装应用列表 +async function loadInstalledApps() { + try { + const cached = sessionStorage.getItem('installed_apps_names') + if (cached) { + const data = JSON.parse(cached) + if (Date.now() - data.timestamp < 30 * 60 * 1000) { + installedAppNames.value = new Set(data.apps || []) + return + } + } + + const response = await axios.get('/jingrow/installed-app-names') + if (response.data.success) { + const apps = response.data.apps || [] + installedAppNames.value = new Set(apps) + sessionStorage.setItem('installed_apps_names', JSON.stringify({ + apps, + timestamp: Date.now() + })) + } + } catch (error) { + console.error('Load installed apps error:', error) + } +} + +// 检查应用是否已安装 +function isAppInstalled(appName: string): boolean { + if (!appName) return false + return installedAppNames.value.has(appName.toLowerCase()) +} + onMounted(() => { loadApps() + loadInstalledApps() }) // 监听搜索和排序变化 diff --git a/apps/jingrow/jingrow/api/local_app_installer.py b/apps/jingrow/jingrow/api/local_app_installer.py index f5d11a2..53dae00 100644 --- a/apps/jingrow/jingrow/api/local_app_installer.py +++ b/apps/jingrow/jingrow/api/local_app_installer.py @@ -220,6 +220,37 @@ async def check_app_exists(app_name: str): return {'exists': False, 'installed': False, 'error': str(e)} +@router.get("/jingrow/installed-app-names") +async def get_installed_app_names(): + """获取所有已安装的应用名称列表""" + try: + from jingrow.utils.jingrow_api import get_single_pagetype, get_record_list + + installed = set() + + # 从 Local Installed Apps 获取应用列表 + result = get_single_pagetype("Local Installed Apps") + if result.get('success'): + config = result.get('config', {}) + local_installed_apps = config.get('local_installed_apps', []) + for app in local_installed_apps: + app_name = app.get('app_name', '') + if app_name: + installed.add(app_name.lower()) + + # 从 Package PageType 获取扩展包列表 + package_result = get_record_list("Package", fields=["name"], limit=1000) + if package_result.get('success') and package_result.get('data'): + for pkg in package_result.get('data', []): + pkg_name = pkg.get('name', '') + if pkg_name: + installed.add(pkg_name.lower()) + + return {'success': True, 'apps': list(installed)} + except Exception as e: + return {'success': False, 'error': str(e), 'apps': []} + + @router.get("/jingrow/local-apps") async def get_local_apps(request: Request): """扫描本地未安装的App"""