perf(web): 优化大数据量页面切换与聚合性能
This commit is contained in:
@@ -3,7 +3,7 @@ import { create } from 'zustand';
|
||||
import type { OvertimeRecord } from '@/lib/overtime';
|
||||
import type { DictItem } from '@/lib/requirement';
|
||||
import { calcDuration } from '@/lib/overtime';
|
||||
import { loadServerData, saveServerData } from '@/lib/server-data';
|
||||
import { loadServerData, saveServerData, SERVER_DATA_CACHE_MS } from '@/lib/server-data';
|
||||
|
||||
const PRESET_REASONS: DictItem[] = [
|
||||
{ id: 'reason-1', name: '需求变更', createdAt: '2024-01-01' },
|
||||
@@ -20,12 +20,14 @@ const PRESET_REASONS: DictItem[] = [
|
||||
];
|
||||
|
||||
const MOCK_RECORDS: OvertimeRecord[] = [];
|
||||
let lastOvertimeFetchAt = 0;
|
||||
|
||||
interface OvertimeState {
|
||||
records: OvertimeRecord[];
|
||||
reasons: DictItem[];
|
||||
loading: boolean;
|
||||
fetchRecords: () => Promise<void>;
|
||||
loaded: boolean;
|
||||
fetchRecords: (options?: { force?: boolean }) => Promise<void>;
|
||||
createRecord: (data: Omit<OvertimeRecord, 'id' | 'duration' | 'createdAt'>) => void;
|
||||
updateRecord: (id: string, data: Partial<OvertimeRecord>) => void;
|
||||
deleteRecord: (id: string) => void;
|
||||
@@ -49,10 +51,14 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
|
||||
records: MOCK_RECORDS,
|
||||
reasons: PRESET_REASONS,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
|
||||
fetchRecords: async () => {
|
||||
fetchRecords: async (options) => {
|
||||
if (!options?.force && get().loaded && Date.now() - lastOvertimeFetchAt < SERVER_DATA_CACHE_MS) return;
|
||||
const cached = await loadStored();
|
||||
if (cached) set({ records: cached.records, reasons: cached.reasons });
|
||||
if (!options?.force && get().loaded && Date.now() - lastOvertimeFetchAt < SERVER_DATA_CACHE_MS) return;
|
||||
lastOvertimeFetchAt = Date.now();
|
||||
set({ records: cached?.records ?? MOCK_RECORDS, reasons: cached?.reasons ?? PRESET_REASONS, loaded: true });
|
||||
},
|
||||
|
||||
createRecord: (data) => {
|
||||
@@ -64,7 +70,7 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
|
||||
createdAt: new Date().toISOString().slice(0, 10),
|
||||
};
|
||||
const records = [...get().records, record];
|
||||
set({ records });
|
||||
set({ records, loaded: true });
|
||||
saveStored({ records, reasons: get().reasons });
|
||||
},
|
||||
|
||||
@@ -77,32 +83,32 @@ export const useOvertimeStore = create<OvertimeState>((set, get) => ({
|
||||
}
|
||||
return updated;
|
||||
});
|
||||
set({ records });
|
||||
set({ records, loaded: true });
|
||||
saveStored({ records, reasons: get().reasons });
|
||||
},
|
||||
|
||||
deleteRecord: (id) => {
|
||||
const records = get().records.filter((r) => r.id !== id);
|
||||
set({ records });
|
||||
set({ records, loaded: true });
|
||||
saveStored({ records, reasons: get().reasons });
|
||||
},
|
||||
|
||||
addReason: (name) => {
|
||||
const item: DictItem = { id: `reason-${Date.now()}`, name, createdAt: new Date().toISOString().slice(0, 10) };
|
||||
const reasons = [...get().reasons, item];
|
||||
set({ reasons });
|
||||
set({ reasons, loaded: true });
|
||||
saveStored({ records: get().records, reasons });
|
||||
},
|
||||
|
||||
updateReason: (id, name) => {
|
||||
const reasons = get().reasons.map((r) => r.id === id ? { ...r, name } : r);
|
||||
set({ reasons });
|
||||
set({ reasons, loaded: true });
|
||||
saveStored({ records: get().records, reasons });
|
||||
},
|
||||
|
||||
deleteReason: (id) => {
|
||||
const reasons = get().reasons.filter((r) => r.id !== id);
|
||||
set({ reasons });
|
||||
set({ reasons, loaded: true });
|
||||
saveStored({ records: get().records, reasons });
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user