From 39e40ff946911c82190c7f0158b5bab9287ac3e4 Mon Sep 17 00:00:00 2001 From: Elysia Date: Sat, 31 Jan 2026 17:48:06 +0800 Subject: [PATCH] feat: enhance application type definitions and improve app management logic --- electron/main/backend/install-manager.ts | 4 +- electron/typedefinition.ts | 7 +++ package.json | 1 + src/App.vue | 76 +++++++++++++++++------- src/components/AppGrid.vue | 2 +- src/components/InstalledAppsModal.vue | 6 +- src/components/UninstallConfirmModal.vue | 2 +- src/components/UpdateAppsModal.vue | 2 +- src/global/typedefinition.ts | 13 ++++ 9 files changed, 86 insertions(+), 27 deletions(-) create mode 100644 electron/typedefinition.ts diff --git a/electron/main/backend/install-manager.ts b/electron/main/backend/install-manager.ts index 60a4fe41..aae163a4 100644 --- a/electron/main/backend/install-manager.ts +++ b/electron/main/backend/install-manager.ts @@ -4,6 +4,8 @@ import readline from 'node:readline'; import { promisify } from 'node:util'; import pino from 'pino'; +import { InstalledAppInfo } from '../../typedefinition'; + const logger = pino({ 'name': 'install-manager' }); type InstallTask = { @@ -66,7 +68,7 @@ const runCommandCapture = async (execCommand: string, execParams: string[]) => { }; const parseInstalledList = (output: string) => { - const apps: Array<{ pkgname: string; version: string; arch: string; flags: string; raw: string }> = []; + const apps: Array = []; const lines = output.split('\n'); for (const line of lines) { const trimmed = line.trim(); diff --git a/electron/typedefinition.ts b/electron/typedefinition.ts new file mode 100644 index 00000000..607f5d02 --- /dev/null +++ b/electron/typedefinition.ts @@ -0,0 +1,7 @@ +export interface InstalledAppInfo { + pkgname: string; + version: string; + arch: string; + flags: string; + raw: string; +} \ No newline at end of file diff --git a/package.json b/package.json index c497b8df..9690babb 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "scripts": { "dev": "vite --mode debug | pino-pretty", "build": "vue-tsc --noEmit && vite build --mode production && electron-builder --config electron-builder.yml", + "build:vite": "vue-tsc --noEmit && vite build --mode production", "build:rpm": "vue-tsc --noEmit && vite build --mode production && electron-builder --config electron-builder.yml --linux rpm", "build:deb": "vue-tsc --noEmit && vite build --mode production && electron-builder --config electron-builder.yml --linux deb", "preview": "vite preview --mode debug" diff --git a/src/App.vue b/src/App.vue index 87b54a35..c37b31f6 100644 --- a/src/App.vue +++ b/src/App.vue @@ -59,7 +59,7 @@ import UninstallConfirmModal from './components/UninstallConfirmModal.vue'; import { APM_STORE_BASE_URL, currentApp, currentAppIsInstalled } from './global/storeConfig'; import { downloads } from './global/downloadStatus'; import { handleInstall, handleRetry, handleUpgrade } from './modeuls/processInstall'; -import type { App, AppJson, DownloadItem } from './global/typedefinition'; +import type { App, AppJson, DownloadItem, UpdateAppItem, InstalledAppInfo } from './global/typedefinition'; import type { Ref } from 'vue'; const logger = pino(); @@ -267,7 +267,7 @@ const toggleAllUpgrades = () => { })); }; -const upgradeSingleApp = (app: App) => { +const upgradeSingleApp = (app: UpdateAppItem) => { if (!app?.pkgname) return; const target = apps.value.find(a => a.pkgname === app.pkgname); if (target) { @@ -275,7 +275,25 @@ const upgradeSingleApp = (app: App) => { } else { // If we can't find it in the list (e.g. category not loaded?), use the info we have // But handleUpgrade expects App. Let's try to construct minimal App - handleUpgrade(app); + let minimalApp: App = { + name: app.pkgname, + pkgname: app.pkgname, + version: app.newVersion || '', + category: 'unknown', + tags: '', + more: '', + filename: '', + torrent_address: '', + author: '', + contributor: '', + website: '', + update: '', + size: '', + img_urls: [], + icons: '', + currentStatus: 'installed' + } + handleUpgrade(minimalApp); } }; @@ -306,14 +324,38 @@ const refreshInstalledApps = async () => { return; } // eslint-disable-next-line @typescript-eslint/no-explicit-any - installedApps.value = (result.apps || []).map((app: any) => ({ - ...app, - // Normalize if Main process returns different casing - name: app.name || app.Name || app.pkgname, - pkgname: app.pkgname || app.Pkgname, - version: app.version || app.Version, - removing: false - })); + installedApps.value = [] + for (const app of result.apps) { + let appInfo = apps.value.find(a => a.pkgname === app.pkgname); + if (appInfo) { + appInfo.flags = app.flags; + appInfo.arch = app.arch; + appInfo.currentStatus = 'installed'; + } else { + // 如果在当前应用列表中找不到该应用,创建一个最小的 App 对象 + appInfo = { + name: app.name || app.pkgname, + pkgname: app.pkgname, + version: app.version, + category: 'unknown', + tags: '', + more: '', + filename: '', + torrent_address: '', + author: '', + contributor: '', + website: '', + update: '', + size: '', + img_urls: [], + icons: '', + currentStatus: 'installed', + arch: app.arch, + flags: app.flags + }; + } + installedApps.value.push(appInfo); + } } catch (error: any) { installedApps.value = []; installedError.value = error?.message || '读取已安装应用失败'; @@ -322,16 +364,9 @@ const refreshInstalledApps = async () => { } }; -const requestUninstall = (app: App | {pkgname: string, [key:string]: any}) => { +const requestUninstall = (app: App) => { let target = null; - if (!('pkgname' in app) && 'Pkgname' in app) { - // @ts-ignore - target = apps.value.find(a => a.pkgname === app.Pkgname); - } else if (!app?.pkgname) { - // try to find by some other way or failed - } else { - target = apps.value.find(a => a.pkgname === app.pkgname) || app; - } + target = apps.value.find(a => a.pkgname === app.pkgname) || app; if (target) { uninstallTargetApp.value = target as App; @@ -553,6 +588,7 @@ const loadApps = async () => { img_urls: typeof appJson.img_urls === 'string' ? JSON.parse(appJson.img_urls) : appJson.img_urls, icons: appJson.icons, category: category, + currentStatus: 'not-installed', }; apps.value.push(normalizedApp); }); diff --git a/src/components/AppGrid.vue b/src/components/AppGrid.vue index 4c4a5f93..d220c1d9 100644 --- a/src/components/AppGrid.vue +++ b/src/components/AppGrid.vue @@ -16,7 +16,7 @@