From aa825231ba9de65930f32733c1859b02c28eebc1 Mon Sep 17 00:00:00 2001 From: aerospaceboy <790286734@qq.com> Date: Sun, 18 Oct 2026 12:18:49 +0800 Subject: [PATCH] fix: refresh grading status after review and ignore stale student responses --- frontend/src/App.tsx | 8 +++-- frontend/tests/batches.spec.ts | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 8b358dc..11494a4 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -207,6 +207,7 @@ function Projects({ openScores }: { openScores: (id: number) => void }) { function Scores({ batchId, projectId }: { batchId?: number; projectId?: number }) { const [batches, setBatches] = useState([]), [projects, setProjects] = useState([]), [batch, setBatch] = useState(batchId), [project, setProject] = useState(projectId), [result, setResult] = useState(), [review, setReview] = useState(), [revisions, setRevisions] = useState([]); const [scoreFilter, setScoreFilter] = useState('all'); + const [refreshVersion, setRefreshVersion] = useState(0); const [form] = Form.useForm(); const [sourcesReady, setSourcesReady] = useState(false); useEffect(() => { @@ -216,12 +217,12 @@ function Scores({ batchId, projectId }: { batchId?: number; projectId?: number } setBatches(batchRows); setProjects(projectRows); setSourcesReady(true); }).catch(error => { if (!cancelled) fail(error); }); return () => { cancelled = true; }; - }, []); + }, [refreshVersion]); const selectedBatch = batches.find(item => item.id === batch); const scopedProjects = projectsInBatch(selectedBatch, projects); + useEffect(() => { setScoreFilter('all'); }, [batch, project]); useEffect(() => { setResult(undefined); setReview(undefined); setRevisions([]); - setScoreFilter('all'); if (!sourcesReady || !selectedBatch) return; if (!scopedProjects.some(item => item.id === project)) { setProject(scopedProjects.length === 1 ? scopedProjects[0].id : undefined); @@ -232,7 +233,7 @@ function Scores({ batchId, projectId }: { batchId?: number; projectId?: number } .catch(error => { if (!cancelled) fail(error); }); return () => { cancelled = true; }; }, [batch, project, batches, projects, sourcesReady]); - const refresh = () => batch && project && load(`/projects/${project}/scores?batch_id=${batch}`, setResult); + const refresh = () => setRefreshVersion(value => value + 1); const scoreRows: any[] = result?.rows || []; const count = (status: string) => scoreRows.filter(row => row.status === status).length; const unfinished = (row: any) => !['scored', 'reviewed'].includes(row.status); @@ -245,6 +246,7 @@ function Scores({ batchId, projectId }: { batchId?: number; projectId?: number } options={options(batches, b => `批次 #${b.id} · ${batchStatusLabel(b.status)}`)} onChange={setBatch} />