From b6248bec455b681d13416b48550e03ba79b52f18 Mon Sep 17 00:00:00 2001 From: Julian Freeman Date: Tue, 31 Mar 2026 08:37:10 -0400 Subject: [PATCH] fix task bugs --- src/components/SoftwareCard.vue | 18 ++++++----- src/store/software.ts | 54 ++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/components/SoftwareCard.vue b/src/components/SoftwareCard.vue index fe36c3a..1fc80bd 100644 --- a/src/components/SoftwareCard.vue +++ b/src/components/SoftwareCard.vue @@ -149,21 +149,23 @@ const isVersionLower = (current: string | undefined | null, target: string | und if (!current || !target) return false; if (current === target) return false; - // 简易的版本比对逻辑:按点分割比对数字 - const v1 = current.split('.'); - const v2 = target.split('.'); + // 处理常见的版本号格式,如 "v1.2.3" -> "1.2.3" + const cleanV = (v: string) => v.replace(/^v/i, '').split(/[-+]/)[0]; + const v1 = cleanV(current).split('.'); + const v2 = cleanV(target).split('.'); const len = Math.max(v1.length, v2.length); for (let i = 0; i < len; i++) { const n1 = parseInt(v1[i] || '0', 10); const n2 = parseInt(v2[i] || '0', 10); - if (isNaN(n1) || isNaN(n2)) { - // 如果是非数字字符串比对,直接返回字符串比对结果 - if (v1[i] !== v2[i]) return v1[i] < v2[i]; - continue; - } + if (n1 < n2) return true; if (n1 > n2) return false; + + // 如果数字相等但字符串不等(如 1.0b vs 1.0a),进行字符串比对 + if (isNaN(n1) || isNaN(n2)) { + if (v1[i] !== v2[i]) return (v1[i] || '') < (v2[i] || ''); + } } return false; }; diff --git a/src/store/software.ts b/src/store/software.ts index 7e59236..3a4d609 100644 --- a/src/store/software.ts +++ b/src/store/software.ts @@ -24,20 +24,24 @@ export const useSoftwareStore = defineStore('software', { settings: { repo_url: 'https://karlblue.github.io/winget-repo' }, + activeTasks: {} as Record, loading: false, isInitialized: false, initStatus: '正在检查系统环境...', lastFetched: 0 }), getters: { - // ... (mergedEssentials, sortedUpdates, sortedAllSoftware, isBusy getters stay the same) mergedEssentials: (state) => { return state.essentials.map(item => { const installedInfo = state.allSoftware.find(s => s.id.toLowerCase() === item.id.toLowerCase()); const isInstalled = !!installedInfo; const hasUpdate = state.updates.some(s => s.id.toLowerCase() === item.id.toLowerCase()); - let displayStatus = item.status; + // 优先使用 activeTasks 中的实时状态 + const task = state.activeTasks[item.id]; + let displayStatus = task ? task.status : item.status; + let displayProgress = task ? task.progress : item.progress; + let actionLabel = '安装'; // 统一字段:version 始终代表当前安装的版本,recommended_version 代表清单推荐的版本 @@ -57,15 +61,26 @@ export const useSoftwareStore = defineStore('software', { ...item, version: currentVersion, recommended_version: recommendedVersion, - status: displayStatus, + status: displayStatus, + progress: displayProgress, actionLabel }; }); }, - sortedUpdates: (state) => [...state.updates].sort(sortByName), + sortedUpdates: (state) => { + return [...state.updates].map(item => { + const task = state.activeTasks[item.id]; + return { + ...item, + status: task ? task.status : item.status, + progress: task ? task.progress : item.progress + }; + }).sort(sortByName); + }, isBusy: (state) => { - const allItems = [...state.essentials, ...state.updates, ...state.allSoftware]; - return allItems.some(item => item.status === 'pending' || item.status === 'installing'); + return Object.values(state.activeTasks).some(task => + task.status === 'pending' || task.status === 'installing' + ); } }, actions: { @@ -193,23 +208,25 @@ export const useSoftwareStore = defineStore('software', { async install(id: string) { const software = this.findSoftware(id) if (software) { - software.status = 'pending'; + // 使用 activeTasks 记录任务,而不是修改原始对象 + this.activeTasks[id] = { status: 'pending', progress: 0 }; try { await invoke('install_software', { task: { id, - version: software.recommended_version || software.version, + version: software.recommended_version || software.available_version || software.version, use_manifest: software.use_manifest || false, manifest_url: software.manifest_url || null } }) } catch (err) { console.error('Invoke install failed:', err); - software.status = 'error'; + this.activeTasks[id] = { status: 'error', progress: 0 }; } } }, findSoftware(id: string) { + // findSoftware 现在仅用于获取软件的基础元数据(ID, 清单 URL 等) return this.essentials.find(s => s.id === id) || this.updates.find(s => s.id === id) || this.allSoftware.find(s => s.id === id) @@ -220,15 +237,24 @@ export const useSoftwareStore = defineStore('software', { listen('install-status', (event: any) => { const { id, status, progress } = event.payload - const software = this.findSoftware(id) - if (software) { - software.status = status - software.progress = progress - } + + // 直接更新 activeTasks,Getter 会自动响应 + this.activeTasks[id] = { status, progress }; + if (status === 'success') { this.lastFetched = 0; this.selectedEssentialIds = this.selectedEssentialIds.filter(i => i !== id); this.selectedUpdateIds = this.selectedUpdateIds.filter(i => i !== id); + + // 成功后延迟清理任务状态,让用户看到“已完成” + setTimeout(() => { + // 如果在此期间没有开始新任务,则移除 + if (this.activeTasks[id]?.status === 'success') { + delete this.activeTasks[id]; + // 重新拉取数据以刷新已安装/待更新状态 + this.fetchAllData(); + } + }, 3000); } })