fix task bugs

This commit is contained in:
Julian Freeman
2026-03-31 08:37:10 -04:00
parent 50489bb9d4
commit b6248bec45
2 changed files with 50 additions and 22 deletions

View File

@@ -149,21 +149,23 @@ const isVersionLower = (current: string | undefined | null, target: string | und
if (!current || !target) return false; if (!current || !target) return false;
if (current === target) return false; if (current === target) return false;
// 简易的版本比对逻辑:按点分割比对数字 // 处理常见的版本号格式,如 "v1.2.3" -> "1.2.3"
const v1 = current.split('.'); const cleanV = (v: string) => v.replace(/^v/i, '').split(/[-+]/)[0];
const v2 = target.split('.'); const v1 = cleanV(current).split('.');
const v2 = cleanV(target).split('.');
const len = Math.max(v1.length, v2.length); const len = Math.max(v1.length, v2.length);
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
const n1 = parseInt(v1[i] || '0', 10); const n1 = parseInt(v1[i] || '0', 10);
const n2 = parseInt(v2[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 true;
if (n1 > n2) return false; 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; return false;
}; };

View File

@@ -24,20 +24,24 @@ export const useSoftwareStore = defineStore('software', {
settings: { settings: {
repo_url: 'https://karlblue.github.io/winget-repo' repo_url: 'https://karlblue.github.io/winget-repo'
}, },
activeTasks: {} as Record<string, { status: string, progress: number }>,
loading: false, loading: false,
isInitialized: false, isInitialized: false,
initStatus: '正在检查系统环境...', initStatus: '正在检查系统环境...',
lastFetched: 0 lastFetched: 0
}), }),
getters: { getters: {
// ... (mergedEssentials, sortedUpdates, sortedAllSoftware, isBusy getters stay the same)
mergedEssentials: (state) => { mergedEssentials: (state) => {
return state.essentials.map(item => { return state.essentials.map(item => {
const installedInfo = state.allSoftware.find(s => s.id.toLowerCase() === item.id.toLowerCase()); const installedInfo = state.allSoftware.find(s => s.id.toLowerCase() === item.id.toLowerCase());
const isInstalled = !!installedInfo; const isInstalled = !!installedInfo;
const hasUpdate = state.updates.some(s => s.id.toLowerCase() === item.id.toLowerCase()); 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 = '安装'; let actionLabel = '安装';
// 统一字段version 始终代表当前安装的版本recommended_version 代表清单推荐的版本 // 统一字段version 始终代表当前安装的版本recommended_version 代表清单推荐的版本
@@ -58,14 +62,25 @@ export const useSoftwareStore = defineStore('software', {
version: currentVersion, version: currentVersion,
recommended_version: recommendedVersion, recommended_version: recommendedVersion,
status: displayStatus, status: displayStatus,
progress: displayProgress,
actionLabel 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) => { isBusy: (state) => {
const allItems = [...state.essentials, ...state.updates, ...state.allSoftware]; return Object.values(state.activeTasks).some(task =>
return allItems.some(item => item.status === 'pending' || item.status === 'installing'); task.status === 'pending' || task.status === 'installing'
);
} }
}, },
actions: { actions: {
@@ -193,23 +208,25 @@ export const useSoftwareStore = defineStore('software', {
async install(id: string) { async install(id: string) {
const software = this.findSoftware(id) const software = this.findSoftware(id)
if (software) { if (software) {
software.status = 'pending'; // 使用 activeTasks 记录任务,而不是修改原始对象
this.activeTasks[id] = { status: 'pending', progress: 0 };
try { try {
await invoke('install_software', { await invoke('install_software', {
task: { task: {
id, id,
version: software.recommended_version || software.version, version: software.recommended_version || software.available_version || software.version,
use_manifest: software.use_manifest || false, use_manifest: software.use_manifest || false,
manifest_url: software.manifest_url || null manifest_url: software.manifest_url || null
} }
}) })
} catch (err) { } catch (err) {
console.error('Invoke install failed:', err); console.error('Invoke install failed:', err);
software.status = 'error'; this.activeTasks[id] = { status: 'error', progress: 0 };
} }
} }
}, },
findSoftware(id: string) { findSoftware(id: string) {
// findSoftware 现在仅用于获取软件的基础元数据ID, 清单 URL 等)
return this.essentials.find(s => s.id === id) || return this.essentials.find(s => s.id === id) ||
this.updates.find(s => s.id === id) || this.updates.find(s => s.id === id) ||
this.allSoftware.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) => { listen('install-status', (event: any) => {
const { id, status, progress } = event.payload const { id, status, progress } = event.payload
const software = this.findSoftware(id)
if (software) { // 直接更新 activeTasksGetter 会自动响应
software.status = status this.activeTasks[id] = { status, progress };
software.progress = progress
}
if (status === 'success') { if (status === 'success') {
this.lastFetched = 0; this.lastFetched = 0;
this.selectedEssentialIds = this.selectedEssentialIds.filter(i => i !== id); this.selectedEssentialIds = this.selectedEssentialIds.filter(i => i !== id);
this.selectedUpdateIds = this.selectedUpdateIds.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);
} }
}) })