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

- 修复作品详情弹框评审记录字段名(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 字符串为数组,并计算评审统计数据
const parsedList = await Promise.all(
filteredList.map(async (contest) => {
// 计算总作品数(已提交的作品)
// 计算总作品数(已提交或评审中的作品)
const totalWorksCount = await this.prisma.contestWork.count({
where: {
contestId: contest.id,
status: 'submitted',
status: { in: ['submitted', 'reviewing'] },
isLatest: true,
validState: 1,
},
});
// 计算已完成评审的作品数(所有评委都评分的作品)
// 简化逻辑:统计有评分记录的作品数
// 计算已完成评审的作品数(有评分记录的作品)
const reviewedCount = await this.prisma.contestWork.count({
where: {
contestId: contest.id,
status: 'submitted',
status: { in: ['submitted', 'reviewing'] },
isLatest: true,
validState: 1,
scores: {
some: {
validState: 1,
@ -302,6 +303,11 @@ export class ContestsService {
contestTenants: this.parseContestTenants(contest.contestTenants),
totalWorksCount,
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: [
{ finalScore: 'desc' },
@ -547,6 +556,25 @@ export class ResultsService {
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 {
contest: {
id: contest.id,
@ -554,7 +582,7 @@ export class ResultsService {
resultState: contest.resultState,
resultPublishTime: contest.resultPublishTime,
},
list: works,
list: enrichedWorks,
total,
page,
pageSize,

View File

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

View File

@ -72,7 +72,10 @@
<a @click="handleViewWorkDetail(record)">{{ record.workNo || "-" }}</a>
</template>
<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) }}
</span>
<span v-else>-</span>

View File

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