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

@@ -4,7 +4,6 @@ import { useState, useMemo, useEffect } from 'react';
import { Plus, Code2, Trash2 } from 'lucide-react';
import { useDevTaskStore } from '@/stores/useDevTaskStore';
import { useTaskCategoryStore } from '@/stores/useTaskCategoryStore';
import { useTaskWorklogStore } from '@/stores/useTaskWorklogStore';
import { useRequirementStore } from '@/stores/useRequirementStore';
import { useMemberStore } from '@/stores/useMemberStore';
import { useAuthStore } from '@/stores/useAuthStore';
@@ -20,12 +19,15 @@ import { useDebouncedValue } from '@/hooks/useDebouncedValue';
import { orderByRequirementForGrouping } from '@/lib/requirement-grouping';
import { buildEffortSummaryMetrics, sumPositiveHours } from '@/lib/effort-summary';
import type { DevTask, DevTaskStatus } from '@/lib/dev-task';
import type { Requirement } from '@/lib/requirement';
interface Props {
versionId: string;
requirementIds: string[];
versionDeadline?: string;
readOnly?: boolean;
versionTasks?: DevTask[];
versionRequirements?: Requirement[];
}
const NO_REQUIREMENT_GROUP_PREFIX = '__no_requirement__';
@@ -38,23 +40,24 @@ function getNoRequirementGroupName(groupKey: string): string {
return groupKey.slice(NO_REQUIREMENT_GROUP_PREFIX.length) || '未命名需求';
}
export function DevTaskTab({ versionId, requirementIds, versionDeadline, readOnly = false }: Props) {
export function DevTaskTab({ versionId, requirementIds, versionDeadline, readOnly = false, versionTasks: scopedVersionTasks, versionRequirements }: Props) {
const { tasks, fetchTasks, deleteTask } = useDevTaskStore();
const { categories, fetchCategories } = useTaskCategoryStore();
const { fetchWorklogs } = useTaskWorklogStore();
const { requirements } = useRequirementStore();
const { members } = useMemberStore();
const user = useAuthStore((s) => s.user);
useEffect(() => { fetchTasks(); }, [fetchTasks]);
useEffect(() => {
if (!scopedVersionTasks) fetchTasks();
}, [fetchTasks, scopedVersionTasks]);
useEffect(() => { fetchCategories(); }, [fetchCategories]);
useEffect(() => { fetchWorklogs(); }, [fetchWorklogs]);
const reqIdSet = useMemo(() => new Set(requirementIds), [requirementIds]);
const versionTasks = useMemo(
const fallbackVersionTasks = useMemo(
() => tasks.filter((t) => t.versionId === versionId || (!t.versionId && reqIdSet.has(t.requirementId))),
[tasks, reqIdSet, versionId],
);
const versionTasks = scopedVersionTasks ?? fallbackVersionTasks;
const [filterAssignee, setFilterAssignee] = useState('');
const [filterStatus, setFilterStatus] = useState('');
@@ -130,7 +133,8 @@ export function DevTaskTab({ versionId, requirementIds, versionDeadline, readOnl
() => Math.max(4, ...categories.map((category) => category.name.length)) + 1,
[categories],
);
const requirementMap = useMemo(() => new Map(requirements.map((r) => [r.id, r])), [requirements]);
const visibleRequirements = versionRequirements ?? requirements;
const requirementMap = useMemo(() => new Map(visibleRequirements.map((r) => [r.id, r])), [visibleRequirements]);
const allTaskIds = useMemo(() => versionTasks.map((t) => t.id), [versionTasks]);
const assignees = useMemo(() => Array.from(new Set(versionTasks.map((t) => t.assigneeId))), [versionTasks]);