perf(web): 优化大数据量页面切换与聚合性能

This commit is contained in:
Script Generator
2026-07-03 09:43:36 +08:00
parent 554ab520d1
commit a509bb4922
32 changed files with 1087 additions and 360 deletions

View File

@@ -3,7 +3,7 @@
import { create } from 'zustand';
import type { Requirement, RequirementStatus, Effort, DictItem, SourceType, SourceTarget } from '@/lib/requirement';
import type { Priority } from '@/lib/derive';
import { loadServerData, saveServerData } from '@/lib/server-data';
import { loadServerData, saveServerData, SERVER_DATA_CACHE_MS } from '@/lib/server-data';
interface RequirementState {
requirements: Requirement[];
@@ -11,7 +11,8 @@ interface RequirementState {
types: DictItem[];
platforms: DictItem[];
loading: boolean;
fetchRequirements: () => Promise<void>;
loaded: boolean;
fetchRequirements: (options?: { force?: boolean }) => Promise<void>;
createRequirement: (data: Omit<Requirement, 'id' | 'code' | 'createdAt'>) => void;
updateRequirement: (id: string, data: Partial<Requirement>) => void;
deleteRequirement: (id: string) => void;
@@ -52,6 +53,7 @@ const PRESET_PLATFORMS: DictItem[] = [
// --- Mock requirements ---
const MOCK_REQUIREMENTS: Requirement[] = [];
let lastRequirementsFetchAt = 0;
// --- Server persistence helpers ---
@@ -75,11 +77,17 @@ export const useRequirementStore = create<RequirementState>((set, get) => {
types: PRESET_TYPES,
platforms: PRESET_PLATFORMS,
loading: false,
loaded: false,
fetchRequirements: async () => {
fetchRequirements: async (options) => {
if (!options?.force && get().loaded && Date.now() - lastRequirementsFetchAt < SERVER_DATA_CACHE_MS) return;
const cached = await loadStored();
if (!options?.force && get().loaded && Date.now() - lastRequirementsFetchAt < SERVER_DATA_CACHE_MS) return;
lastRequirementsFetchAt = Date.now();
if (cached) {
set({ requirements: cached.requirements, sourceTargets: cached.sourceTargets, types: cached.types, platforms: cached.platforms });
set({ requirements: cached.requirements, sourceTargets: cached.sourceTargets, types: cached.types, platforms: cached.platforms, loaded: true });
} else {
set({ loaded: true });
}
},
@@ -94,21 +102,21 @@ export const useRequirementStore = create<RequirementState>((set, get) => {
createdAt: new Date().toISOString(),
};
const updated = [...requirements, newReq];
set({ requirements: updated });
set({ requirements: updated, loaded: true });
saveStored({ requirements: updated, sourceTargets, types, platforms });
},
updateRequirement: (id, data) => {
const { requirements, sourceTargets, types, platforms } = get();
const updated = requirements.map((r) => (r.id === id ? { ...r, ...data } : r));
set({ requirements: updated });
set({ requirements: updated, loaded: true });
saveStored({ requirements: updated, sourceTargets, types, platforms });
},
deleteRequirement: (id) => {
const { requirements, sourceTargets, types, platforms } = get();
const updated = requirements.filter((r) => r.id !== id);
set({ requirements: updated });
set({ requirements: updated, loaded: true });
saveStored({ requirements: updated, sourceTargets, types, platforms });
},
@@ -117,21 +125,21 @@ export const useRequirementStore = create<RequirementState>((set, get) => {
const { requirements, sourceTargets, types, platforms } = get();
const item: SourceTarget = { id: `st-${Date.now()}`, name, sourceType, createdAt: new Date().toISOString().slice(0, 10) };
const updated = [...sourceTargets, item];
set({ sourceTargets: updated });
set({ sourceTargets: updated, loaded: true });
saveStored({ requirements, sourceTargets: updated, types, platforms });
},
updateSourceTarget: (id, name) => {
const { requirements, sourceTargets, types, platforms } = get();
const updated = sourceTargets.map((s) => (s.id === id ? { ...s, name } : s));
set({ sourceTargets: updated });
set({ sourceTargets: updated, loaded: true });
saveStored({ requirements, sourceTargets: updated, types, platforms });
},
deleteSourceTarget: (id) => {
const { requirements, sourceTargets, types, platforms } = get();
const updated = sourceTargets.filter((s) => s.id !== id);
set({ sourceTargets: updated });
set({ sourceTargets: updated, loaded: true });
saveStored({ requirements, sourceTargets: updated, types, platforms });
},
@@ -140,21 +148,21 @@ export const useRequirementStore = create<RequirementState>((set, get) => {
const { requirements, sourceTargets, types, platforms } = get();
const item: DictItem = { id: `type-${Date.now()}`, name, createdAt: new Date().toISOString().slice(0, 10) };
const updated = [...types, item];
set({ types: updated });
set({ types: updated, loaded: true });
saveStored({ requirements, sourceTargets, types: updated, platforms });
},
updateType: (id, name) => {
const { requirements, sourceTargets, types, platforms } = get();
const updated = types.map((t) => (t.id === id ? { ...t, name } : t));
set({ types: updated });
set({ types: updated, loaded: true });
saveStored({ requirements, sourceTargets, types: updated, platforms });
},
deleteType: (id) => {
const { requirements, sourceTargets, types, platforms } = get();
const updated = types.filter((t) => t.id !== id);
set({ types: updated });
set({ types: updated, loaded: true });
saveStored({ requirements, sourceTargets, types: updated, platforms });
},
@@ -163,21 +171,21 @@ export const useRequirementStore = create<RequirementState>((set, get) => {
const { requirements, sourceTargets, types, platforms } = get();
const item: DictItem = { id: `platform-${Date.now()}`, name, createdAt: new Date().toISOString().slice(0, 10) };
const updated = [...platforms, item];
set({ platforms: updated });
set({ platforms: updated, loaded: true });
saveStored({ requirements, sourceTargets, types, platforms: updated });
},
updatePlatform: (id, name) => {
const { requirements, sourceTargets, types, platforms } = get();
const updated = platforms.map((p) => (p.id === id ? { ...p, name } : p));
set({ platforms: updated });
set({ platforms: updated, loaded: true });
saveStored({ requirements, sourceTargets, types, platforms: updated });
},
deletePlatform: (id) => {
const { requirements, sourceTargets, types, platforms } = get();
const updated = platforms.filter((p) => p.id !== id);
set({ platforms: updated });
set({ platforms: updated, loaded: true });
saveStored({ requirements, sourceTargets, types, platforms: updated });
},
};