selection states preserve

This commit is contained in:
Julian Freeman
2026-03-14 19:04:06 -04:00
parent 34ad167ad2
commit cdee6b47c7
3 changed files with 65 additions and 96 deletions

View File

@@ -9,12 +9,14 @@ export const useSoftwareStore = defineStore('software', {
essentials: [] as any[],
updates: [] as any[],
allSoftware: [] as any[],
selectedEssentialIds: [] as string[],
selectedUpdateIds: [] as string[],
loading: false,
lastFetched: 0 // 记录上次完整同步的时间戳
lastFetched: 0
}),
getters: {
mergedEssentials: (state) => {
const items = state.essentials.map(item => {
return state.essentials.map(item => {
const isInstalled = state.allSoftware.some(s => s.id.toLowerCase() === item.id.toLowerCase());
const hasUpdate = state.updates.some(s => s.id.toLowerCase() === item.id.toLowerCase());
@@ -30,18 +32,45 @@ export const useSoftwareStore = defineStore('software', {
}
}
return {
...item,
status: displayStatus,
actionLabel
};
return { ...item, status: displayStatus, actionLabel };
});
return items; // Essentials 通常保持自定义顺序
},
sortedUpdates: (state) => [...state.updates].sort(sortByName),
sortedAllSoftware: (state) => [...state.allSoftware].sort(sortByName)
},
actions: {
// 通用的勾选切换逻辑
toggleSelection(id: string, type: 'essential' | 'update') {
const list = type === 'essential' ? this.selectedEssentialIds : this.selectedUpdateIds;
const index = list.indexOf(id);
if (index === -1) {
list.push(id);
} else {
list.splice(index, 1);
}
},
selectAll(type: 'essential' | 'update') {
if (type === 'essential') {
const selectable = this.mergedEssentials.filter(s => s.status !== 'installed');
this.selectedEssentialIds = selectable.map(s => s.id);
} else {
this.selectedUpdateIds = this.updates.map(s => s.id);
}
},
deselectAll(type: 'essential' | 'update') {
if (type === 'essential') this.selectedEssentialIds = [];
else this.selectedUpdateIds = [];
},
invertSelection(type: 'essential' | 'update') {
if (type === 'essential') {
const selectable = this.mergedEssentials.filter(s => s.status !== 'installed').map(s => s.id);
this.selectedEssentialIds = selectable.filter(id => !this.selectedEssentialIds.includes(id));
} else {
const selectable = this.updates.map(s => s.id);
this.selectedUpdateIds = selectable.filter(id => !this.selectedUpdateIds.includes(id));
}
},
async fetchEssentials() {
this.essentials = await invoke('get_essentials')
},
@@ -50,6 +79,8 @@ export const useSoftwareStore = defineStore('software', {
try {
const res = await invoke('get_updates')
this.updates = res as any[]
// 刷新数据后,如果没选过,默认全选
if (this.selectedUpdateIds.length === 0) this.selectAll('update');
} finally {
this.loading = false
}
@@ -63,16 +94,13 @@ export const useSoftwareStore = defineStore('software', {
this.loading = false
}
},
// 智能同步:如果数据较新,则直接返回
async syncDataIfNeeded(force = false) {
const now = Date.now();
const CACHE_TIMEOUT = 5 * 60 * 1000; // 5 分钟缓存
const CACHE_TIMEOUT = 5 * 60 * 1000;
if (!force && this.allSoftware.length > 0 && (now - this.lastFetched < CACHE_TIMEOUT)) {
if (this.essentials.length === 0) await this.fetchEssentials();
return;
}
await this.fetchAllData();
},
async fetchAllData() {
@@ -87,6 +115,8 @@ export const useSoftwareStore = defineStore('software', {
this.allSoftware = all as any[];
this.updates = updates as any[];
this.lastFetched = Date.now();
// 如果没选过,默认全选
if (this.selectedEssentialIds.length === 0) this.selectAll('essential');
} finally {
this.loading = false;
}
@@ -112,9 +142,11 @@ export const useSoftwareStore = defineStore('software', {
software.status = status
software.progress = progress
}
if (status === 'success') {
this.lastFetched = 0;
// 安装成功后从选择列表中移除
this.selectedEssentialIds = this.selectedEssentialIds.filter(i => i !== id);
this.selectedUpdateIds = this.selectedUpdateIds.filter(i => i !== id);
}
})
}