mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-04-26 09:20:18 +08:00
feat(apm): 在安装和更新应用前检查并提示安装APM
添加APM可用性检查逻辑,在安装或更新APM应用时,若检测到APM未安装,则弹出对话框提示用户安装 安装流程完成后显示成功提示并告知需要重启电脑
This commit is contained in:
@@ -947,6 +947,54 @@ ipcMain.handle("check-apm-available", async () => {
|
|||||||
return await checkApmAvailable();
|
return await checkApmAvailable();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 显示 APM 安装对话框(在点击安装按钮时提前检查)
|
||||||
|
ipcMain.handle("show-apm-install-dialog", async (event) => {
|
||||||
|
const webContents = event.sender;
|
||||||
|
const win = BrowserWindow.fromWebContents(webContents);
|
||||||
|
const superUserCmd = await checkSuperUserCommand();
|
||||||
|
|
||||||
|
const { response } = await dialog.showMessageBox(win ?? undefined, {
|
||||||
|
type: "question",
|
||||||
|
title: "需要安装 APM",
|
||||||
|
message: "此应用需要使用 APM 安装。",
|
||||||
|
detail:
|
||||||
|
"APM 是星火应用商店的软件包兼容工具,此应用使用星火 APM 提供支持,安装APM后方可安装此应用,是否确认安装?",
|
||||||
|
buttons: ["确认", "取消"],
|
||||||
|
defaultId: 0,
|
||||||
|
cancelId: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response !== 0) {
|
||||||
|
return { success: false, cancelled: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
const installApmOk = await runInstallApm(superUserCmd);
|
||||||
|
if (!installApmOk) {
|
||||||
|
await dialog.showMessageBox(win ?? undefined, {
|
||||||
|
type: "error",
|
||||||
|
title: "安装失败",
|
||||||
|
message: "安装 APM 失败",
|
||||||
|
detail: "请检查网络或权限后重试",
|
||||||
|
buttons: ["确定"],
|
||||||
|
defaultId: 0,
|
||||||
|
});
|
||||||
|
return { success: false, cancelled: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安装APM成功,提示用户已安装成功,需要重启后方可展示应用
|
||||||
|
await dialog.showMessageBox(win ?? undefined, {
|
||||||
|
type: "info",
|
||||||
|
title: "APM 安装成功",
|
||||||
|
message: "恭喜您,APM 已成功安装",
|
||||||
|
detail:
|
||||||
|
"恭喜您,APM 已成功安装!\n首次安装APM后,需要重启电脑后方可在启动器展示应用。您可在应用安装完毕后择机重启电脑\n若您需要立即使用应用,可在应用安装后先在应用商店中打开您的应用。",
|
||||||
|
buttons: ["确定"],
|
||||||
|
defaultId: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { success: true, cancelled: false };
|
||||||
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
ipcMain.handle("uninstall-installed", async (_event, payload: any) => {
|
ipcMain.handle("uninstall-installed", async (_event, payload: any) => {
|
||||||
const pkgname = typeof payload === "string" ? payload : payload.pkgname;
|
const pkgname = typeof payload === "string" ? payload : payload.pkgname;
|
||||||
|
|||||||
18
src/App.vue
18
src/App.vue
@@ -834,11 +834,11 @@ const toggleAllUpgrades = () => {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const upgradeSingleApp = (app: UpdateAppItem) => {
|
const upgradeSingleApp = async (app: UpdateAppItem) => {
|
||||||
if (!app?.pkgname) return;
|
if (!app?.pkgname) return;
|
||||||
const target = apps.value.find((a) => a.pkgname === app.pkgname);
|
const target = apps.value.find((a) => a.pkgname === app.pkgname);
|
||||||
if (target) {
|
if (target) {
|
||||||
handleUpgrade(target);
|
await handleUpgrade(target);
|
||||||
} else {
|
} else {
|
||||||
// If we can't find it in the list (e.g. category not loaded?), use the info we have
|
// 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
|
// But handleUpgrade expects App. Let's try to construct minimal App
|
||||||
@@ -861,15 +861,15 @@ const upgradeSingleApp = (app: UpdateAppItem) => {
|
|||||||
origin: "apm", // Default to APM if unknown, or try to guess
|
origin: "apm", // Default to APM if unknown, or try to guess
|
||||||
currentStatus: "installed",
|
currentStatus: "installed",
|
||||||
};
|
};
|
||||||
handleUpgrade(minimalApp);
|
await handleUpgrade(minimalApp);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const upgradeSelectedApps = () => {
|
const upgradeSelectedApps = async () => {
|
||||||
const selectedApps = upgradableApps.value.filter((app) => app.selected);
|
const selectedApps = upgradableApps.value.filter((app) => app.selected);
|
||||||
selectedApps.forEach((app) => {
|
for (const app of selectedApps) {
|
||||||
upgradeSingleApp(app);
|
await upgradeSingleApp(app);
|
||||||
});
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const openInstalledModal = () => {
|
const openInstalledModal = () => {
|
||||||
@@ -945,8 +945,8 @@ const onDetailRemove = (app: App) => {
|
|||||||
requestUninstall(app);
|
requestUninstall(app);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDetailInstall = (app: App) => {
|
const onDetailInstall = async (app: App) => {
|
||||||
handleInstall(app);
|
await handleInstall(app);
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeUninstallModal = () => {
|
const closeUninstallModal = () => {
|
||||||
|
|||||||
@@ -21,10 +21,25 @@ import axios from "axios";
|
|||||||
let downloadIdCounter = 0;
|
let downloadIdCounter = 0;
|
||||||
const logger = pino({ name: "processInstall.ts" });
|
const logger = pino({ name: "processInstall.ts" });
|
||||||
|
|
||||||
export const handleInstall = (appObj?: App) => {
|
export const handleInstall = async (appObj?: App) => {
|
||||||
const targetApp = appObj || currentApp.value;
|
const targetApp = appObj || currentApp.value;
|
||||||
if (!targetApp?.pkgname) return;
|
if (!targetApp?.pkgname) return;
|
||||||
|
|
||||||
|
// APM 应用:在创建下载任务前检查 APM 是否可用
|
||||||
|
if (targetApp.origin === "apm") {
|
||||||
|
const hasApm = await window.ipcRenderer.invoke("check-apm-available");
|
||||||
|
if (!hasApm) {
|
||||||
|
// 发送事件到主进程显示 APM 安装对话框
|
||||||
|
const { success, cancelled } = await window.ipcRenderer.invoke(
|
||||||
|
"show-apm-install-dialog",
|
||||||
|
);
|
||||||
|
if (!success || cancelled) {
|
||||||
|
// 用户取消或未安装成功,不继续安装应用
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
downloads.value.find(
|
downloads.value.find(
|
||||||
(d) => d.pkgname === targetApp.pkgname && d.origin === targetApp.origin,
|
(d) => d.pkgname === targetApp.pkgname && d.origin === targetApp.origin,
|
||||||
@@ -98,9 +113,24 @@ export const handleRetry = (download_: DownloadItem) => {
|
|||||||
window.ipcRenderer.send("queue-install", JSON.stringify(download_));
|
window.ipcRenderer.send("queue-install", JSON.stringify(download_));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleUpgrade = (app: App) => {
|
export const handleUpgrade = async (app: App) => {
|
||||||
if (!app.pkgname) return;
|
if (!app.pkgname) return;
|
||||||
|
|
||||||
|
// APM 应用:在创建下载任务前检查 APM 是否可用
|
||||||
|
if (app.origin === "apm") {
|
||||||
|
const hasApm = await window.ipcRenderer.invoke("check-apm-available");
|
||||||
|
if (!hasApm) {
|
||||||
|
// 发送事件到主进程显示 APM 安装对话框
|
||||||
|
const { success, cancelled } = await window.ipcRenderer.invoke(
|
||||||
|
"show-apm-install-dialog",
|
||||||
|
);
|
||||||
|
if (!success || cancelled) {
|
||||||
|
// 用户取消或未安装成功,不继续更新应用
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
downloads.value.find(
|
downloads.value.find(
|
||||||
(d) => d.pkgname === app.pkgname && d.origin === app.origin,
|
(d) => d.pkgname === app.pkgname && d.origin === app.origin,
|
||||||
|
|||||||
Reference in New Issue
Block a user