From b43c6117ecb1ec12f590667dfad7db13263d9d68 Mon Sep 17 00:00:00 2001
From: Delta1035 <51444562+Delta1035@users.noreply.github.com>
Date: Wed, 4 Feb 2026 13:06:01 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BA=94=E7=94=A8?=
=?UTF-8?q?=E8=BF=98=E6=B2=A1=E6=9C=89=E5=AE=89=E8=A3=85=E5=AE=8C=EF=BC=8C?=
=?UTF-8?q?=E6=8C=89=E9=92=AE=E5=B0=B1=E9=87=8D=E6=96=B0=E5=8F=98=E6=88=90?=
=?UTF-8?q?=E5=8F=AF=E5=AE=89=E8=A3=85=E7=8A=B6=E6=80=81=20(#11)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
fix:先用比较简单的方案解决安装之后卸载了还是显示已安装的问题
fix: 在安装成功的ipc信息之后再删除安装队列的任务
删除pnpm workspace
---
electron/main/backend/install-manager.ts | 4 +-
electron/typedefinition.ts | 9 ++-
src/App.vue | 33 +++++++---
src/components/AppDetailModal.vue | 23 ++++---
src/global/downloadStatus.ts | 78 +++++++++++++++++++++++-
src/global/typedefinition.ts | 15 ++++-
6 files changed, 138 insertions(+), 24 deletions(-)
diff --git a/electron/main/backend/install-manager.ts b/electron/main/backend/install-manager.ts
index 7c0eeffe..1c4f6970 100644
--- a/electron/main/backend/install-manager.ts
+++ b/electron/main/backend/install-manager.ts
@@ -4,7 +4,7 @@ import readline from 'node:readline';
import { promisify } from 'node:util';
import pino from 'pino';
-import { InstalledAppInfo } from '../../typedefinition';
+import { ChannelPayload, InstalledAppInfo } from '../../typedefinition';
const logger = pino({ 'name': 'install-manager' });
@@ -333,7 +333,7 @@ ipcMain.on('remove-installed', async (_event, pkgname: string) => {
time: Date.now(),
exitCode: code,
message: JSON.stringify(messageJSONObj)
- });
+ } satisfies ChannelPayload);
});
});
diff --git a/electron/typedefinition.ts b/electron/typedefinition.ts
index 607f5d02..08cf3b2b 100644
--- a/electron/typedefinition.ts
+++ b/electron/typedefinition.ts
@@ -4,4 +4,11 @@ export interface InstalledAppInfo {
arch: string;
flags: string;
raw: string;
-}
\ No newline at end of file
+}
+
+
+export type ChannelPayload = {
+ success: boolean;
+ message: string;
+ [k: string]: unknown;
+};
\ No newline at end of file
diff --git a/src/App.vue b/src/App.vue
index a163300d..77d989c8 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -57,11 +57,10 @@ import InstalledAppsModal from './components/InstalledAppsModal.vue';
import UpdateAppsModal from './components/UpdateAppsModal.vue';
import UninstallConfirmModal from './components/UninstallConfirmModal.vue';
import { APM_STORE_BASE_URL, currentApp, currentAppIsInstalled } from './global/storeConfig';
-import { downloads } from './global/downloadStatus';
+import { downloads, removeDownloadItem, watchDownloadsChange } from './global/downloadStatus';
import { handleInstall, handleRetry, handleUpgrade } from './modeuls/processInstall';
-import type { App, AppJson, DownloadItem, UpdateAppItem, InstalledAppInfo } from './global/typedefinition';
+import type { App, AppJson, DownloadItem, UpdateAppItem, InstalledAppInfo, ChannelPayload } from './global/typedefinition';
import type { Ref } from 'vue';
-
const logger = pino();
// Axios 全局配置
@@ -167,7 +166,7 @@ const openDetail = (app: App) => {
});
};
-const checkAppInstalled = (app: App) => {
+const checkAppInstalled = (app: App) => {
window.ipcRenderer.invoke('check-installed', app.pkgname).then((isInstalled: boolean) => {
currentAppIsInstalled.value = isInstalled;
});
@@ -242,7 +241,7 @@ const refreshUpgradableApps = async () => {
upgradableApps.value = (result.apps || []).map((app: any) => ({
...app,
// Map properties if needed or assume main matches App interface except field names might differ
- // For now assuming result.apps returns objects compatible with App for core fields,
+ // For now assuming result.apps returns objects compatible with App for core fields,
// but let's normalize just in case if main returns different structure.
name: app.name || app.Name || '',
pkgname: app.pkgname || app.Pkgname || '',
@@ -367,10 +366,12 @@ const refreshInstalledApps = async () => {
const requestUninstall = (app: App) => {
let target = null;
target = apps.value.find(a => a.pkgname === app.pkgname) || app;
-
+
if (target) {
uninstallTargetApp.value = target as App;
showUninstallModal.value = true;
+ // TODO: 挪到卸载完成ipc回调里面
+ removeDownloadItem(app.pkgname);
}
};
@@ -396,6 +397,14 @@ const onUninstallSuccess = () => {
}
};
+const installCompleteCallback = () => {
+ if (currentApp.value) {
+ checkAppInstalled(currentApp.value);
+ }
+}
+
+watchDownloadsChange(installCompleteCallback);
+
const uninstallInstalledApp = (app: App) => {
requestUninstall(app);
};
@@ -651,7 +660,7 @@ onMounted(async () => {
}
});
- window.ipcRenderer.on('deep-link-install', (_event: any, pkgname: string) => {
+ window.ipcRenderer.on('deep-link-install', (_event: Electron.IpcRendererEvent, pkgname: string) => {
const tryOpen = () => {
const target = apps.value.find(a => a.pkgname === pkgname);
if (target) {
@@ -673,6 +682,14 @@ onMounted(async () => {
}
});
+ window.ipcRenderer.on('remove-complete', (_event: Electron.IpcRendererEvent, payload: ChannelPayload) => {
+ const pkgname = currentApp.value?.pkgname
+ if(payload.success && pkgname){
+ removeDownloadItem(pkgname);
+ }
+ });
+
+
window.ipcRenderer.send('renderer-ready', { status: true });
logger.info('Renderer process is ready!');
});
@@ -682,4 +699,4 @@ watch(isDarkTheme, (newVal) => {
localStorage.setItem('theme', newVal ? 'dark' : 'light');
syncThemePreference(newVal);
});
-
\ No newline at end of file
+
diff --git a/src/components/AppDetailModal.vue b/src/components/AppDetailModal.vue
index c9642b17..bcebabc0 100644
--- a/src/components/AppDetailModal.vue
+++ b/src/components/AppDetailModal.vue
@@ -25,9 +25,9 @@
class="inline-flex items-center gap-2 rounded-2xl bg-gradient-to-r px-4 py-2 text-sm font-semibold text-white shadow-lg disabled:opacity-40 transition hover:-translate-y-0.5"
:class="installFeedback ? 'from-emerald-500 to-emerald-600' : 'from-brand to-brand-dark'"
@click="handleInstall"
- :disabled="installFeedback">
+ :disabled="installFeedback || isCompleted">
- {{ installFeedback ? '已加入队列' : '安装' }}
+ {{ installBtnText }}