diff --git a/app/performance-survey/[[...path]]/page.tsx b/app/performance-survey/[[...path]]/page.tsx index 7bc8cbeb..b8d784a5 100644 --- a/app/performance-survey/[[...path]]/page.tsx +++ b/app/performance-survey/[[...path]]/page.tsx @@ -4505,7 +4505,11 @@ function VisualCaseSurvey({
{showUploadProgress ? '案例提交' : '评分完成度'} - {showUploadProgress ? `${workItems.length}/${requiredCount}` : `${completedScores}/${requiredCount}`} + + {showUploadProgress + ? `${workItems.length}/${requiredCount}` + : `${completedScores}/${requiredCount} · ${formatNullableScore(scoreProgress.totalScore)} 分`} +
{ questions, assignmentId: 'assignment-current', workItems: [ - { id: 'work-1', scores: [{ assignmentId: 'assignment-current' }] }, + { id: 'work-1', scores: [{ assignmentId: 'assignment-current', totalScore: 27 }] }, { id: 'work-2', scores: [] }, { id: 'work-3', scores: [] }, ], @@ -63,6 +63,7 @@ describe('performance survey response progress', () => { expect(result).toEqual({ completedCount: 2, persistedCount: 1, + totalScore: 64, persistedWorkItemIds: ['work-1'], draftCompletedWorkItemIds: ['work-2'], unscoredWorkItemIds: ['work-2', 'work-3'], @@ -79,7 +80,31 @@ describe('performance survey response progress', () => { })).toMatchObject({ completedCount: 0, persistedCount: 0, + totalScore: 0, unscoredWorkItemIds: ['work-1'], }) }) + + it('视觉案例分数优先读取当前评分人的已保存总分且不重复累计本地草稿', () => { + expect(calculatePerformanceSurveyWorkItemProgress({ + questions, + assignmentId: 'assignment-current', + workItems: [ + { + id: 'work-1', + scores: [ + { assignmentId: 'assignment-other', totalScore: 30 }, + { assignmentId: 'assignment-current', totalScore: 24 }, + ], + }, + ], + scoreDrafts: { + 'work-1': { scores: { q1: 10, q2: 10, q3: 10 } }, + }, + })).toMatchObject({ + completedCount: 1, + persistedCount: 1, + totalScore: 24, + }) + }) }) diff --git a/lib/performance-survey-response-progress.ts b/lib/performance-survey-response-progress.ts index 15acb510..5122328f 100644 --- a/lib/performance-survey-response-progress.ts +++ b/lib/performance-survey-response-progress.ts @@ -4,7 +4,11 @@ type PerformanceSurveyProgressQuestion = { type PerformanceSurveyProgressWorkItem = { id: string - scores?: Array<{ assignmentId?: string | null }> | null + scores?: Array<{ + assignmentId?: string | null + totalScore?: unknown + scores?: Record | null + }> | null } export function calculatePerformanceSurveyResponseProgress(input: { @@ -41,9 +45,15 @@ export function calculatePerformanceSurveyWorkItemProgress(input: { assignmentId?: string | null }) { const assignmentId = String(input.assignmentId || '') - const persistedWorkItemIds = input.workItems - .filter((item) => assignmentId && item.scores?.some((score) => score.assignmentId === assignmentId)) - .map((item) => item.id) + const persistedScores = input.workItems + .map((item) => ({ + workItemId: item.id, + score: assignmentId + ? item.scores?.find((candidate) => candidate.assignmentId === assignmentId) + : undefined, + })) + .filter((item) => Boolean(item.score)) + const persistedWorkItemIds = persistedScores.map((item) => item.workItemId) const persistedIdSet = new Set(persistedWorkItemIds) const draftCompletedWorkItemIds = input.workItems .filter((item) => { @@ -55,10 +65,28 @@ export function calculatePerformanceSurveyWorkItemProgress(input: { }) }) .map((item) => item.id) + const persistedTotalScore = persistedScores.reduce((sum, item) => { + const totalScore = Number(item.score?.totalScore) + if (Number.isFinite(totalScore)) return sum + totalScore + return sum + input.questions.reduce((scoreSum, question) => { + const value = Number(item.score?.scores?.[question.id]) + return Number.isFinite(value) ? scoreSum + value : scoreSum + }, 0) + }, 0) + const draftTotalScore = input.workItems.reduce((sum, item) => { + if (persistedIdSet.has(item.id)) return sum + return sum + input.questions.reduce((scoreSum, question) => { + const rawValue = input.scoreDrafts?.[item.id]?.scores?.[question.id] + if (rawValue === null || rawValue === undefined || rawValue === '') return scoreSum + const value = Number(rawValue) + return Number.isFinite(value) ? scoreSum + value : scoreSum + }, 0) + }, 0) return { completedCount: persistedWorkItemIds.length + draftCompletedWorkItemIds.length, persistedCount: persistedWorkItemIds.length, + totalScore: persistedTotalScore + draftTotalScore, persistedWorkItemIds, draftCompletedWorkItemIds, unscoredWorkItemIds: input.workItems