This commit is contained in:
2026-09-01 01:27:12 +07:00
parent 69666ee264
commit f648beaa33
3 changed files with 34 additions and 25 deletions
+12 -19
View File
@@ -2,16 +2,11 @@ package team_answers_repo
import (
"context"
"errors"
"evening_detective_server/internal/repos"
"github.com/jackc/pgx/v5/pgxpool"
)
var (
ErrAnswerNotFound = errors.New("Ответ не найден")
)
type TeamAnswersRepo struct {
pool *pgxpool.Pool
}
@@ -136,28 +131,26 @@ func (r *TeamAnswersRepo) GetAnswersByGameID(
}
// SetAnswerScore выставляет балл за ответ; score == nil сбрасывает балл.
// Балл можно выставить и за неотвеченный вопрос (команда может не дать
// ответ): если строки (team_id, question_code) ещё нет, она создаётся с
// пустым ответом и выставленным баллом.
func (r *TeamAnswersRepo) SetAnswerScore(
ctx context.Context,
teamId int,
questionCode string,
score *int,
) error {
tag, err := r.pool.Exec(
_, err := r.pool.Exec(
ctx,
`UPDATE team_answers
SET
score = $1,
updated_at = NOW()
WHERE team_id = $2 AND question_code = $3`,
score,
`INSERT INTO team_answers (team_id, question_code, answer, score)
VALUES ($1, $2, '', $3)
ON CONFLICT (team_id, question_code)
DO UPDATE SET
score = EXCLUDED.score,
updated_at = NOW()`,
teamId,
questionCode,
score,
)
if err != nil {
return err
}
if tag.RowsAffected() == 0 {
return ErrAnswerNotFound
}
return nil
return err
}
+22 -6
View File
@@ -418,8 +418,10 @@ func (s *GameService) SubmitTeamAnswers(ctx context.Context, teamId int, passwor
// GetGameAnswers возвращает полную картину для оценки организатором:
// вопросы сценария с правильными ответами и ответы всех команд с баллами.
// Ответы на удалённые из сценария вопросы не возвращаются (как в
// GetTeamAnswers).
// Команда может не дать ответ на вопрос — такой вопрос попадает в список
// ответов команды с пустым текстом и без балла (организатор видит его и
// может выставить балл, в т.ч. штрафной). Ответы на удалённые из сценария
// вопросы не возвращаются (как в GetTeamAnswers).
func (s *GameService) GetGameAnswers(ctx context.Context, gameId int) (*GameAnswers, error) {
game, err := s.gamesRepo.GetGameByID(ctx, gameId)
if err != nil {
@@ -437,23 +439,37 @@ func (s *GameService) GetGameAnswers(ctx context.Context, gameId int) (*GameAnsw
if err != nil {
return nil, err
}
answersByTeam := make(map[int][]AnswerScore, len(teams))
answerByTeamAndCode := make(map[int]map[string]AnswerScore, len(teams))
for _, row := range rows {
if _, ok := byCode[row.QuestionCode]; !ok {
continue
}
score := row.Score
answersByTeam[row.TeamId] = append(answersByTeam[row.TeamId], AnswerScore{
if answerByTeamAndCode[row.TeamId] == nil {
answerByTeamAndCode[row.TeamId] = make(map[string]AnswerScore, len(questions))
}
answerByTeamAndCode[row.TeamId][row.QuestionCode] = AnswerScore{
QuestionCode: row.QuestionCode,
Text: row.Text,
Score: score,
})
}
}
teamAnswers := make([]TeamAnswers, 0, len(teams))
for _, team := range teams {
byCode := answerByTeamAndCode[team.ID]
// Все вопросы сценария в порядке сценария; неотвеченные — с пустым
// текстом и без балла, чтобы организатор видел пропуски.
answers := make([]AnswerScore, 0, len(questions))
for _, question := range questions {
if answer, ok := byCode[question.Code]; ok {
answers = append(answers, answer)
continue
}
answers = append(answers, AnswerScore{QuestionCode: question.Code})
}
teamAnswers = append(teamAnswers, TeamAnswers{
Team: mapTeam(team),
Answers: answersByTeam[team.ID],
Answers: answers,
})
}
return &GameAnswers{