generated from VLADIMIR/template
fix
This commit is contained in:
Binary file not shown.
@@ -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
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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{
|
||||||
|
|||||||
Reference in New Issue
Block a user