From 43bd3a9ef857910249a573fc9ab18037cafc82b4 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Thu, 14 May 2026 10:58:47 +0800 Subject: [PATCH] feat(drivers): add upgrade all drivers button Add a batch upgrade command that sequentially updates all drivers with available updates, with per-driver progress tracking in the UI. --- src-tauri/src/commands/agents.rs | 75 +++++++++++++++++++++ src-tauri/src/lib.rs | 1 + src/components/config/DriverStoreDialog.vue | 58 ++++++++++++++-- 3 files changed, 129 insertions(+), 5 deletions(-) diff --git a/src-tauri/src/commands/agents.rs b/src-tauri/src/commands/agents.rs index ad1a07c355..b966fe8869 100644 --- a/src-tauri/src/commands/agents.rs +++ b/src-tauri/src/commands/agents.rs @@ -140,6 +140,81 @@ pub async fn install_agent( Ok(()) } +#[tauri::command] +pub async fn upgrade_all_agents(app: tauri::AppHandle, state: State<'_, Arc>) -> Result { + let am = &state.agent_manager; + let registry = fetch_registry().await?; + let agents = build_agent_list(am, Some(®istry)); + let updatable: Vec<&AgentDriverInfo> = agents.iter().filter(|a| a.update_available).collect(); + let total_drivers = updatable.len() as u32; + if total_drivers == 0 { + return Ok(0); + } + + for (i, agent) in updatable.iter().enumerate() { + let current = (i + 1) as u32; + let db_type = &agent.db_type; + let driver = registry.drivers.get(db_type).ok_or_else(|| format!("Unknown driver type: {db_type}"))?; + let jre_key = &driver.jre; + let needs_jre = am.load_state().java_runtime.mode == JavaRuntimeMode::Managed && !am.is_jre_installed(jre_key); + + if needs_jre { + let jre_info = + registry.resolve_jre(jre_key).ok_or_else(|| format!("No JRE definition for version: {jre_key}"))?; + let platform = AgentManager::current_platform(); + let platform_jre = jre_info + .platforms + .get(platform) + .ok_or_else(|| format!("No JRE {jre_key} available for platform: {platform}"))?; + let jre_archive = am.base_dir().join("jre-download.tar.gz"); + let _ = app.emit( + "agent-install-progress", + serde_json::json!({ + "step": "jre", "downloaded": 0u64, "total": platform_jre.size, + "db_type": db_type, "current": current, "total_drivers": total_drivers, + }), + ); + download_with_progress(&app, "jre", &platform_jre.url, &jre_archive, platform_jre.size).await?; + let _ = app.emit( + "agent-install-progress", + serde_json::json!({ + "step": "jre-extract", "downloaded": 0u64, "total": 0u64, + "db_type": db_type, "current": current, "total_drivers": total_drivers, + }), + ); + extract_archive(&jre_archive, &am.jre_dir(jre_key))?; + std::fs::remove_file(&jre_archive).ok(); + } + + let jar_path = am.driver_jar_path(db_type); + let _ = app.emit( + "agent-install-progress", + serde_json::json!({ + "step": "driver", "downloaded": 0u64, "total": driver.jar.size, + "db_type": db_type, "current": current, "total_drivers": total_drivers, + }), + ); + download_with_progress(&app, "driver", &driver.jar.url, &jar_path, driver.jar.size).await?; + + let mut local_state = am.load_state(); + if let Some(jre_info) = registry.resolve_jre(jre_key) { + local_state.jre_versions.insert(jre_key.clone(), jre_info.version.clone()); + } + local_state.installed_drivers.insert( + db_type.clone(), + InstalledDriver { + version: driver.version.clone(), + installed_at: chrono::Utc::now().to_rfc3339(), + jre: jre_key.clone(), + }, + ); + am.save_state(&local_state)?; + } + + let _ = app.emit("agent-install-progress", serde_json::json!({ "step": "all-done" })); + Ok(total_drivers) +} + #[tauri::command] pub async fn uninstall_agent(state: State<'_, Arc>, db_type: String) -> Result<(), String> { let am = &state.agent_manager; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index b56f20b848..9a0db76560 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -147,6 +147,7 @@ pub fn run() { commands::agents::list_installed_agents, commands::agents::list_installed_agents_local, commands::agents::install_agent, + commands::agents::upgrade_all_agents, commands::agents::uninstall_agent, commands::agents::check_jre_installed, commands::agents::get_agent_java_runtime_config, diff --git a/src/components/config/DriverStoreDialog.vue b/src/components/config/DriverStoreDialog.vue index e14c4dd573..1dd1dc7652 100644 --- a/src/components/config/DriverStoreDialog.vue +++ b/src/components/config/DriverStoreDialog.vue @@ -49,6 +49,10 @@ interface JavaRuntimeConfig { const drivers = ref([]); const installing = ref(null); +const upgradingAll = ref(false); +const upgradingCurrent = ref(""); +const upgradingIndex = ref(0); +const upgradingTotal = ref(0); const reinstallingJre = ref(null); const refreshing = ref(false); const progress = ref(null); @@ -79,7 +83,11 @@ const progressText = computed(() => { const pct = Math.round(((p.downloaded ?? 0) / p.total) * 100); const dl = formatSize(p.downloaded ?? 0); const total = formatSize(p.total); - return `${label} ${dl} / ${total} (${pct}%)`; + const prefix = + upgradingAll.value && upgradingCurrent.value + ? `[${upgradingIndex.value}/${upgradingTotal.value}] ${upgradingCurrent.value} — ` + : ""; + return `${prefix}${label} ${dl} / ${total} (${pct}%)`; }); const progressPercent = computed(() => { @@ -88,6 +96,8 @@ const progressPercent = computed(() => { return Math.round(((p.downloaded ?? 0) / p.total) * 100); }); +const updatableCount = computed(() => drivers.value.filter((d) => d.update_available).length); + async function refreshAgents() { drivers.value = await invoke("list_installed_agents"); } @@ -161,6 +171,24 @@ async function installDriver(dbType: string) { } } +async function upgradeAll() { + upgradingAll.value = true; + progress.value = null; + try { + const count = await invoke("upgrade_all_agents"); + await refreshAgents(); + toast(`${count} 个驱动升级完成`); + } catch (e: any) { + toast(`批量升级失败: ${e}`); + } finally { + upgradingAll.value = false; + upgradingCurrent.value = ""; + upgradingIndex.value = 0; + upgradingTotal.value = 0; + progress.value = null; + } +} + async function uninstallDriver(dbType: string) { const label = drivers.value.find((d) => d.db_type === dbType)?.label ?? dbType; try { @@ -322,10 +350,16 @@ onMounted(async () => { }); unlisten = await listen("agent-install-progress", (event) => { - if (event.payload.step === "done") { + const payload = event.payload as any; + if (payload.step === "done" || payload.step === "all-done") { progress.value = null; } else { - progress.value = event.payload; + progress.value = payload; + } + if (payload.db_type && payload.total_drivers) { + upgradingCurrent.value = drivers.value.find((d) => d.db_type === payload.db_type)?.label ?? payload.db_type; + upgradingIndex.value = payload.current ?? 0; + upgradingTotal.value = payload.total_drivers ?? 0; } }); void loadJdbcDrivers(); @@ -466,6 +500,19 @@ onUnmounted(() => {
加载中...
+
+ {{ updatableCount }} 个驱动可更新 + +
{ v-if="!driver.installed" size="sm" class="h-7 text-xs" - :disabled="installing !== null" + :disabled="installing !== null || upgradingAll" @click="installDriver(driver.db_type)" > @@ -526,7 +573,7 @@ onUnmounted(() => { size="sm" variant="outline" class="h-7 text-xs" - :disabled="installing !== null" + :disabled="installing !== null || upgradingAll" @click="installDriver(driver.db_type)" > {{ installing === driver.db_type ? "更新中..." : "更新" }} @@ -535,6 +582,7 @@ onUnmounted(() => { variant="ghost" size="sm" class="h-7 text-xs text-muted-foreground hover:text-destructive" + :disabled="upgradingAll" @click="uninstallDriver(driver.db_type)" > 卸载