optimize status fetch

This commit is contained in:
Julian Freeman
2026-04-04 17:20:06 -04:00
parent 66b6ac4738
commit fd8241fd43
3 changed files with 52 additions and 4 deletions

View File

@@ -177,6 +177,11 @@ async fn install_software(
state.install_tx.send(task).await.map_err(|e| e.to_string())
}
#[tauri::command]
async fn get_software_info(app: AppHandle, id: String) -> Option<Software> {
tokio::task::spawn_blocking(move || winget::get_software_info(&app, &id)).await.unwrap_or(None)
}
#[tauri::command]
fn get_logs_history() -> Vec<LogPayload> {
vec![]
@@ -541,6 +546,7 @@ pub fn run() {
get_essentials,
get_installed_software,
get_updates,
get_software_info,
install_software,
get_logs_history
])

View File

@@ -260,6 +260,27 @@ pub fn list_updates(handle: &AppHandle) -> Vec<Software> {
execute_powershell(handle, &log_id, "Fetch Updates", script)
}
pub fn get_software_info(handle: &AppHandle, id: &str) -> Option<Software> {
let log_id = format!("get-info-{}", chrono::Local::now().timestamp_millis());
let script = format!(r#"
$OutputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$ErrorActionPreference = 'SilentlyContinue'
Import-Module Microsoft.WinGet.Client -ErrorAction SilentlyContinue
$pkg = Get-WinGetPackage -Id "{}" -ErrorAction SilentlyContinue
if ($pkg) {{
[PSCustomObject]@{{
Name = [string]$pkg.Name;
Id = [string]$pkg.Id;
InstalledVersion = [string]$pkg.InstalledVersion;
AvailableVersions = @()
}} | ConvertTo-Json -Compress
}}
"#, id);
let res = execute_powershell(handle, &log_id, "Fetch Single Software Info", &script);
res.into_iter().next()
}
fn execute_powershell(handle: &AppHandle, log_id: &str, cmd_title: &str, script: &str) -> Vec<Software> {
emit_log(handle, log_id, cmd_title, "Fetching data from Winget...", "info");

View File

@@ -280,7 +280,7 @@ export const useSoftwareStore = defineStore('software', {
if ((window as any).__tauri_listener_init) return;
(window as any).__tauri_listener_init = true;
listen('install-status', (event: any) => {
listen('install-status', async (event: any) => {
const { id, status, progress } = event.payload
const task = this.activeTasks[id];
@@ -290,17 +290,38 @@ export const useSoftwareStore = defineStore('software', {
// 当任务达到终态(成功或失败)时。注意:'configuring' 不是终态。
if (status === 'success' || status === 'error') {
if (status === 'success') {
this.lastFetched = 0;
// 立即更新勾选状态,提升响应感
// 立即进行局部刷新
try {
const latestInfo = await invoke('get_software_info', { id }) as any;
if (latestInfo) {
const index = this.allSoftware.findIndex(s => s.id.toLowerCase() === id.toLowerCase());
if (index !== -1) {
this.allSoftware[index] = { ...this.allSoftware[index], ...latestInfo };
} else {
this.allSoftware.push(latestInfo);
}
}
} catch (err) {
console.error('Partial refresh failed:', err);
}
// 立即更新勾选状态
this.selectedEssentialIds = this.selectedEssentialIds.filter(i => i !== id);
this.selectedUpdateIds = this.selectedUpdateIds.filter(i => i !== id);
// 保持绿色“已完成”状态 3 秒,然后自动回归真实状态
setTimeout(() => {
if (this.activeTasks[id]?.status === 'success') {
delete this.activeTasks[id];
}
}, 3000);
}
// 检查是否属于正在进行的批量任务
const index = this.batchQueue.indexOf(id);
if (index !== -1) {
this.batchQueue.splice(index, 1);
// 如果这是批量任务中的最后一个,则触发延迟刷新
// 只有批量任务全部结束后,才执行一次全量刷新作为保障
if (this.batchQueue.length === 0) {
this.scheduleDataRefresh();
}