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