// 本地存档:通关记录、最佳成绩、自制关卡 const KEY = 'iwbtc_fan_v1'; const blank = () => ({ cleared: {}, customs: [], audio: true }); export const Save = { data: blank(), load() { try { const s = localStorage.getItem(KEY); if (s) this.data = Object.assign(blank(), JSON.parse(s)); } catch (e) { this.data = blank(); } return this.data; }, flush() { try { localStorage.setItem(KEY, JSON.stringify(this.data)); } catch (e) { } }, get(id) { return this.data.cleared[id] || null; }, isCleared(id) { return !!this.data.cleared[id]; }, /** 记录通关,返回是否刷新纪录 */ clear(id, deaths, ms, apples) { const old = this.data.cleared[id]; const rec = { deaths, time: ms, apples: apples || 0, at: Date.now() }; let better = false; if (!old) { this.data.cleared[id] = rec; better = true; } else { const nd = Math.min(old.deaths, deaths); const nt = Math.min(old.time, ms); better = deaths < old.deaths || ms < old.time; this.data.cleared[id] = { ...old, deaths: nd, time: nt, apples: Math.max(old.apples || 0, apples || 0) }; } this.flush(); return better; }, wipe() { this.data = blank(); this.flush(); }, customs() { return this.data.customs || []; }, addCustom(lv) { this.data.customs = this.data.customs || []; this.data.customs.push(lv); this.flush(); return lv; }, removeCustom(id) { this.data.customs = (this.data.customs || []).filter(l => l.id !== id); this.flush(); }, setAudio(on) { this.data.audio = on; this.flush(); }, };