修复评审相关数据显示问题

- 修复作品详情弹框评审记录字段名(score->totalScore, comment->comments)
- 修复评审详情弹框评分字段名(score->totalScore)
- 修复赛果发布详情评委评分不显示问题(添加judgeScore计算)
- 修复赛事列表已递交数统计(添加status in条件和覆盖_count.works)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
zhangxiaohua 2026-01-23 14:44:27 +08:00
parent c1f8ac072a
commit 2981449353
5 changed files with 50 additions and 13 deletions

View File

@ -273,22 +273,23 @@ export class ContestsService {
// 解析 contestTenants JSON 字符串为数组,并计算评审统计数据 // 解析 contestTenants JSON 字符串为数组,并计算评审统计数据
const parsedList = await Promise.all( const parsedList = await Promise.all(
filteredList.map(async (contest) => { filteredList.map(async (contest) => {
// 计算总作品数(已提交的作品) // 计算总作品数(已提交或评审中的作品)
const totalWorksCount = await this.prisma.contestWork.count({ const totalWorksCount = await this.prisma.contestWork.count({
where: { where: {
contestId: contest.id, contestId: contest.id,
status: 'submitted', status: { in: ['submitted', 'reviewing'] },
isLatest: true, isLatest: true,
validState: 1,
}, },
}); });
// 计算已完成评审的作品数(所有评委都评分的作品) // 计算已完成评审的作品数(有评分记录的作品)
// 简化逻辑:统计有评分记录的作品数
const reviewedCount = await this.prisma.contestWork.count({ const reviewedCount = await this.prisma.contestWork.count({
where: { where: {
contestId: contest.id, contestId: contest.id,
status: 'submitted', status: { in: ['submitted', 'reviewing'] },
isLatest: true, isLatest: true,
validState: 1,
scores: { scores: {
some: { some: {
validState: 1, validState: 1,
@ -302,6 +303,11 @@ export class ContestsService {
contestTenants: this.parseContestTenants(contest.contestTenants), contestTenants: this.parseContestTenants(contest.contestTenants),
totalWorksCount, totalWorksCount,
reviewedCount, reviewedCount,
// 覆盖 _count.works 为正确的统计数据(只统计 isLatest=true 且 validState=1 的作品)
_count: {
...contest._count,
works: totalWorksCount,
},
}; };
}), }),
); );

View File

@ -537,6 +537,15 @@ export class ResultsService {
}, },
}, },
}, },
scores: {
where: { validState: 1 },
select: {
id: true,
totalScore: true,
judgeName: true,
scoreTime: true,
},
},
}, },
orderBy: [ orderBy: [
{ finalScore: 'desc' }, { finalScore: 'desc' },
@ -547,6 +556,25 @@ export class ResultsService {
this.prisma.contestWork.count({ where }), this.prisma.contestWork.count({ where }),
]); ]);
// 计算每个作品的评委平均分(用于显示)
const enrichedWorks = works.map((work) => {
let judgeScore: number | null = work.finalScore
? Number(work.finalScore)
: null;
// 如果没有最终得分但有评分记录,则计算平均分作为评委评分
if (judgeScore === null && work.scores && work.scores.length > 0) {
const totalScores = work.scores.reduce(
(sum, s) => sum + Number(s.totalScore),
0,
);
judgeScore = Number((totalScores / work.scores.length).toFixed(2));
}
return {
...work,
judgeScore, // 评委评分(平均分)
};
});
return { return {
contest: { contest: {
id: contest.id, id: contest.id,
@ -554,7 +582,7 @@ export class ResultsService {
resultState: contest.resultState, resultState: contest.resultState,
resultPublishTime: contest.resultPublishTime, resultPublishTime: contest.resultPublishTime,
}, },
list: works, list: enrichedWorks,
total, total,
page, page,
pageSize, pageSize,

View File

@ -98,8 +98,8 @@
<div class="review-card"> <div class="review-card">
<div class="review-item"> <div class="review-item">
<span class="review-label">作品评分</span> <span class="review-label">作品评分</span>
<span v-if="record.score !== null && record.score !== undefined" class="review-score"> <span v-if="record.totalScore !== null && record.totalScore !== undefined" class="review-score">
{{ record.score }} {{ record.totalScore }}
</span> </span>
<span v-else class="not-reviewed">未评审</span> <span v-else class="not-reviewed">未评审</span>
</div> </div>
@ -113,9 +113,9 @@
{{ record.scoreTime ? formatDateTime(record.scoreTime) : '-' }} {{ record.scoreTime ? formatDateTime(record.scoreTime) : '-' }}
</span> </span>
</div> </div>
<div v-if="record.comment" class="review-item comment"> <div v-if="record.comments" class="review-item comment">
<span class="review-label">老师评语</span> <span class="review-label">老师评语</span>
<span class="review-value">{{ record.comment }}</span> <span class="review-value">{{ record.comments }}</span>
</div> </div>
</div> </div>
</a-tab-pane> </a-tab-pane>

View File

@ -72,7 +72,10 @@
<a @click="handleViewWorkDetail(record)">{{ record.workNo || "-" }}</a> <a @click="handleViewWorkDetail(record)">{{ record.workNo || "-" }}</a>
</template> </template>
<template v-else-if="column.key === 'finalScore'"> <template v-else-if="column.key === 'finalScore'">
<span v-if="record.finalScore !== null" class="score"> <span v-if="record.judgeScore !== null && record.judgeScore !== undefined" class="score">
{{ Number(record.judgeScore).toFixed(2) }}
</span>
<span v-else-if="record.finalScore !== null" class="score">
{{ Number(record.finalScore).toFixed(2) }} {{ Number(record.finalScore).toFixed(2) }}
</span> </span>
<span v-else>-</span> <span v-else>-</span>

View File

@ -134,8 +134,8 @@
{{ record.judge?.tenant?.name || "-" }} {{ record.judge?.tenant?.name || "-" }}
</template> </template>
<template v-else-if="column.key === 'score'"> <template v-else-if="column.key === 'score'">
<span v-if="record.score !== undefined && record.score !== null"> <span v-if="record.totalScore !== undefined && record.totalScore !== null">
{{ record.score }} {{ record.totalScore }}
</span> </span>
<span v-else class="text-gray">未评分</span> <span v-else class="text-gray">未评分</span>
</template> </template>