fix: 显示视觉案例评分进度分数

This commit is contained in:
chenpei 2026-07-20 13:01:10 +08:00
parent 156a370f5a
commit 10e6b525f8
3 changed files with 63 additions and 6 deletions

View File

@ -4505,7 +4505,11 @@ function VisualCaseSurvey({
<div className="mt-3 rounded-2xl bg-[#f6f8fb] px-3.5 py-2.5"> <div className="mt-3 rounded-2xl bg-[#f6f8fb] px-3.5 py-2.5">
<div className="flex items-center justify-between text-[12px] font-semibold text-[#667085]"> <div className="flex items-center justify-between text-[12px] font-semibold text-[#667085]">
<span>{showUploadProgress ? '案例提交' : '评分完成度'}</span> <span>{showUploadProgress ? '案例提交' : '评分完成度'}</span>
<span className="text-[#101828]">{showUploadProgress ? `${workItems.length}/${requiredCount}` : `${completedScores}/${requiredCount}`}</span> <span className="text-[#101828]">
{showUploadProgress
? `${workItems.length}/${requiredCount}`
: `${completedScores}/${requiredCount} · ${formatNullableScore(scoreProgress.totalScore)} 分`}
</span>
</div> </div>
<div className="mt-2 h-1.5 overflow-hidden rounded-full bg-[#e5edf6]"> <div className="mt-2 h-1.5 overflow-hidden rounded-full bg-[#e5edf6]">
<div <div

View File

@ -50,7 +50,7 @@ describe('performance survey response progress', () => {
questions, questions,
assignmentId: 'assignment-current', assignmentId: 'assignment-current',
workItems: [ workItems: [
{ id: 'work-1', scores: [{ assignmentId: 'assignment-current' }] }, { id: 'work-1', scores: [{ assignmentId: 'assignment-current', totalScore: 27 }] },
{ id: 'work-2', scores: [] }, { id: 'work-2', scores: [] },
{ id: 'work-3', scores: [] }, { id: 'work-3', scores: [] },
], ],
@ -63,6 +63,7 @@ describe('performance survey response progress', () => {
expect(result).toEqual({ expect(result).toEqual({
completedCount: 2, completedCount: 2,
persistedCount: 1, persistedCount: 1,
totalScore: 64,
persistedWorkItemIds: ['work-1'], persistedWorkItemIds: ['work-1'],
draftCompletedWorkItemIds: ['work-2'], draftCompletedWorkItemIds: ['work-2'],
unscoredWorkItemIds: ['work-2', 'work-3'], unscoredWorkItemIds: ['work-2', 'work-3'],
@ -79,7 +80,31 @@ describe('performance survey response progress', () => {
})).toMatchObject({ })).toMatchObject({
completedCount: 0, completedCount: 0,
persistedCount: 0, persistedCount: 0,
totalScore: 0,
unscoredWorkItemIds: ['work-1'], 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,
})
})
}) })

View File

@ -4,7 +4,11 @@ type PerformanceSurveyProgressQuestion = {
type PerformanceSurveyProgressWorkItem = { type PerformanceSurveyProgressWorkItem = {
id: string id: string
scores?: Array<{ assignmentId?: string | null }> | null scores?: Array<{
assignmentId?: string | null
totalScore?: unknown
scores?: Record<string, unknown> | null
}> | null
} }
export function calculatePerformanceSurveyResponseProgress(input: { export function calculatePerformanceSurveyResponseProgress(input: {
@ -41,9 +45,15 @@ export function calculatePerformanceSurveyWorkItemProgress(input: {
assignmentId?: string | null assignmentId?: string | null
}) { }) {
const assignmentId = String(input.assignmentId || '') const assignmentId = String(input.assignmentId || '')
const persistedWorkItemIds = input.workItems const persistedScores = input.workItems
.filter((item) => assignmentId && item.scores?.some((score) => score.assignmentId === assignmentId)) .map((item) => ({
.map((item) => item.id) 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 persistedIdSet = new Set(persistedWorkItemIds)
const draftCompletedWorkItemIds = input.workItems const draftCompletedWorkItemIds = input.workItems
.filter((item) => { .filter((item) => {
@ -55,10 +65,28 @@ export function calculatePerformanceSurveyWorkItemProgress(input: {
}) })
}) })
.map((item) => item.id) .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 { return {
completedCount: persistedWorkItemIds.length + draftCompletedWorkItemIds.length, completedCount: persistedWorkItemIds.length + draftCompletedWorkItemIds.length,
persistedCount: persistedWorkItemIds.length, persistedCount: persistedWorkItemIds.length,
totalScore: persistedTotalScore + draftTotalScore,
persistedWorkItemIds, persistedWorkItemIds,
draftCompletedWorkItemIds, draftCompletedWorkItemIds,
unscoredWorkItemIds: input.workItems unscoredWorkItemIds: input.workItems