fix(data): 增加全局保存失败保护
This commit is contained in:
@@ -3,6 +3,7 @@ import { create } from 'zustand';
|
||||
import type { OvertimeRecord } from '@/lib/overtime';
|
||||
import type { DictItem } from '@/lib/requirement';
|
||||
import { calcDuration } from '@/lib/overtime';
|
||||
import { scheduleSaveWithOptimisticRollback } from '@/lib/optimistic-persistence';
|
||||
import { loadServerData, saveServerData, SERVER_DATA_CACHE_MS } from '@/lib/server-data';
|
||||
|
||||
const PRESET_REASONS: DictItem[] = [
|
||||
@@ -36,10 +37,6 @@ interface OvertimeState {
|
||||
deleteReason: (id: string) => void;
|
||||
}
|
||||
|
||||
function saveStored(data: { records: OvertimeRecord[]; reasons: DictItem[] }) {
|
||||
saveServerData('overtime', data).catch(() => {});
|
||||
}
|
||||
|
||||
async function loadStored(): Promise<{ records: OvertimeRecord[]; reasons: DictItem[] } | null> {
|
||||
try {
|
||||
return await loadServerData<{ records: OvertimeRecord[]; reasons: DictItem[] }>('overtime');
|
||||
@@ -62,6 +59,7 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
|
||||
},
|
||||
|
||||
createRecord: (data) => {
|
||||
const previous = get().records;
|
||||
const duration = calcDuration(data.startTime, data.endTime);
|
||||
const record: OvertimeRecord = {
|
||||
...data,
|
||||
@@ -69,13 +67,19 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
|
||||
duration,
|
||||
createdAt: new Date().toISOString().slice(0, 10),
|
||||
};
|
||||
const records = [...get().records, record];
|
||||
const records = [...previous, record];
|
||||
set({ records, loaded: true });
|
||||
saveStored({ records, reasons: get().reasons });
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveServerData('overtime', { records, reasons: get().reasons }),
|
||||
expected: records,
|
||||
getCurrent: () => get().records,
|
||||
rollback: () => set({ records: previous, loaded: true }),
|
||||
});
|
||||
},
|
||||
|
||||
updateRecord: (id, data) => {
|
||||
const records = get().records.map((r) => {
|
||||
const previous = get().records;
|
||||
const records = previous.map((r) => {
|
||||
if (r.id !== id) return r;
|
||||
const updated = { ...r, ...data };
|
||||
if (data.startTime || data.endTime) {
|
||||
@@ -84,31 +88,60 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
|
||||
return updated;
|
||||
});
|
||||
set({ records, loaded: true });
|
||||
saveStored({ records, reasons: get().reasons });
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveServerData('overtime', { records, reasons: get().reasons }),
|
||||
expected: records,
|
||||
getCurrent: () => get().records,
|
||||
rollback: () => set({ records: previous, loaded: true }),
|
||||
});
|
||||
},
|
||||
|
||||
deleteRecord: (id) => {
|
||||
const records = get().records.filter((r) => r.id !== id);
|
||||
const previous = get().records;
|
||||
const records = previous.filter((r) => r.id !== id);
|
||||
set({ records, loaded: true });
|
||||
saveStored({ records, reasons: get().reasons });
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveServerData('overtime', { records, reasons: get().reasons }),
|
||||
expected: records,
|
||||
getCurrent: () => get().records,
|
||||
rollback: () => set({ records: previous, loaded: true }),
|
||||
});
|
||||
},
|
||||
|
||||
addReason: (name) => {
|
||||
const previous = get().reasons;
|
||||
const item: DictItem = { id: `reason-${Date.now()}`, name, createdAt: new Date().toISOString().slice(0, 10) };
|
||||
const reasons = [...get().reasons, item];
|
||||
const reasons = [...previous, item];
|
||||
set({ reasons, loaded: true });
|
||||
saveStored({ records: get().records, reasons });
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveServerData('overtime', { records: get().records, reasons }),
|
||||
expected: reasons,
|
||||
getCurrent: () => get().reasons,
|
||||
rollback: () => set({ reasons: previous, loaded: true }),
|
||||
});
|
||||
},
|
||||
|
||||
updateReason: (id, name) => {
|
||||
const reasons = get().reasons.map((r) => r.id === id ? { ...r, name } : r);
|
||||
const previous = get().reasons;
|
||||
const reasons = previous.map((r) => r.id === id ? { ...r, name } : r);
|
||||
set({ reasons, loaded: true });
|
||||
saveStored({ records: get().records, reasons });
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveServerData('overtime', { records: get().records, reasons }),
|
||||
expected: reasons,
|
||||
getCurrent: () => get().reasons,
|
||||
rollback: () => set({ reasons: previous, loaded: true }),
|
||||
});
|
||||
},
|
||||
|
||||
deleteReason: (id) => {
|
||||
const reasons = get().reasons.filter((r) => r.id !== id);
|
||||
const previous = get().reasons;
|
||||
const reasons = previous.filter((r) => r.id !== id);
|
||||
set({ reasons, loaded: true });
|
||||
saveStored({ records: get().records, reasons });
|
||||
scheduleSaveWithOptimisticRollback({
|
||||
save: () => saveServerData('overtime', { records: get().records, reasons }),
|
||||
expected: reasons,
|
||||
getCurrent: () => get().reasons,
|
||||
rollback: () => set({ reasons: previous, loaded: true }),
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user