This commit is contained in:
2026-10-19 02:56:22 +07:00
parent 97b5545b32
commit 53a60dee6b
+103 -23
View File
@@ -12,6 +12,7 @@ import {
NRate,
NSelect,
NSpace,
NTable,
NTabPane,
NTabs,
NText,
@@ -1064,6 +1065,26 @@ const reviewsCount = ref(0)
const answersQuestions = ref<Question[]>([])
const answersTeams = ref<TeamAnswers[]>([])
const resultQuestions = ref<ResultsQuestion[]>([])
const resultTeams = ref<TeamResult[]>([])
const isLoadingResults = ref(false)
const hasResultsError = ref(false)
async function loadAnswerResults() {
isLoadingResults.value = true
hasResultsError.value = false
try {
const res = await client.GetGameResults({ gameID: Number(gameId) })
resultQuestions.value = res.questions || []
resultTeams.value = res.teams || []
} catch (err) {
hasResultsError.value = true
console.error('Не удалось загрузить таблицу результатов', err)
} finally {
isLoadingResults.value = false
}
}
// Баллы по ключу "teamID:questionCode" (undefined — балл не выставлен)
const scores = ref<Record<string, number | undefined>>({})
@@ -1090,6 +1111,7 @@ async function loadGameAnswers() {
}
}
scores.value = next
await loadAnswerResults()
}
async function openReviewsModal() {
@@ -1538,31 +1560,78 @@ useSimplePolling(() => {
</n-tab-pane>
<n-tab-pane v-if="canManageGame" name="answers" tab="Проверка ответов">
<div class="game-tab-content">
<div v-if="answersQuestions.length == 0" class="answers-empty">
Вопросы дела не заданы или команды ещё не отвечали.
</div>
<UiBlock v-for="question in answersQuestions" :key="question.code">
<p class="answers-question-title">{{ question.code }}: {{ question.text }}</p>
<p class="answers-question-answer">
Правильный ответ:<br /><span class="correct-answer">{{ question.answer || '—' }}</span>
</p>
<div v-for="team in answersTeams" :key="team.team?.ID" class="answers-team-row">
<div class="answers-team-name">
{{ team.team?.name }}
</div>
<div class="answers-team-answer">
{{ teamAnswer(team, question.code) || '—' }}
</div>
<n-input-number
:value="scores[scoreKey(team.team?.ID, question.code)]"
@update:value="onScoreUpdate(scoreKey(team.team?.ID, question.code), $event)"
placeholder="Балл"
class="answers-score-input"
/>
<UiBlock>
<p class="screens-title">Таблица результатов</p>
<p>Сохранённые оценки. Таблица обновляется после сохранения баллов.</p>
<n-text v-if="isLoadingResults">Загрузка результатов…</n-text>
<n-alert v-else-if="hasResultsError" type="error">
Не удалось загрузить таблицу результатов.
</n-alert>
<p v-else-if="resultTeams.length === 0">Результатов пока нет.</p>
<div v-else class="answer-results-scroll">
<n-table :single-line="false">
<thead>
<tr>
<th scope="col">Место</th>
<th scope="col">Команда</th>
<th v-for="question in resultQuestions" :key="question.code" scope="col">
{{ question.code }}
</th>
<th scope="col">Сумма</th>
<th scope="col">Поездки</th>
</tr>
</thead>
<tbody>
<tr v-for="team in resultTeams" :key="team.team?.ID">
<td>{{ team.place }}</td>
<td>{{ team.team?.name }}</td>
<td v-for="question in resultQuestions" :key="question.code">
{{ team.answers?.find((answer) => answer.questionCode === question.code)?.score ?? '—' }}
</td>
<td>{{ team.totalScore }}</td>
<td>{{ team.actionsCount }}</td>
</tr>
</tbody>
</n-table>
</div>
</UiBlock>
<div
v-if="answersQuestions.length === 0 || answersTeams.length === 0"
class="answers-empty"
>
Вопросы дела не заданы или команды ещё не отвечали.
</div>
<template v-else>
<UiBlock v-for="team in answersTeams" :key="team.team?.ID">
<h3 class="answers-team-name">{{ team.team?.name }}</h3>
<div
v-for="question in answersQuestions"
:key="question.code"
class="answers-question"
>
<p class="answers-question-title">{{ question.code }}: {{ question.text }}</p>
<p class="answers-question-answer">
Правильный ответ:<br /><span class="correct-answer">{{ question.answer || '—' }}</span>
</p>
<div class="answers-team-row">
<div class="answers-team-answer">
{{ teamAnswer(team, question.code) || '—' }}
</div>
<n-input-number
:value="scores[scoreKey(team.team?.ID, question.code)]"
@update:value="onScoreUpdate(scoreKey(team.team?.ID, question.code), $event)"
placeholder="Балл"
class="answers-score-input"
/>
</div>
</div>
</UiBlock>
</template>
<n-flex justify="end">
<n-button @click="saveAllScores()" :disabled="answersQuestions.length == 0">
<n-button
@click="saveAllScores()"
:disabled="answersQuestions.length === 0 || answersTeams.length === 0"
>
Сохранить баллы
</n-button>
</n-flex>
@@ -1980,10 +2049,19 @@ useSimplePolling(() => {
text-decoration: underline;
}
.answer-results-scroll {
overflow-x: auto;
}
.answers-empty {
color: #777;
}
.answers-question {
margin-top: 16px;
overflow-wrap: anywhere;
}
.answers-question-title {
font-size: 17px;
font-weight: 600;
@@ -2015,8 +2093,10 @@ useSimplePolling(() => {
}
.answers-team-name {
font-size: 18px;
font-weight: 600;
width: 180px;
margin: 0;
overflow-wrap: anywhere;
}
.answers-team-answer {