This commit is contained in:
2026-10-23 03:02:22 +07:00
parent 980ca18b60
commit 0879a8946a
20 changed files with 1827 additions and 960 deletions
+40 -3
View File
@@ -222,6 +222,8 @@ func screenState(session *screen_service.ScreenSession) *proto.ScreenState {
TimerRemainingSeconds: timerRemaining,
TimerState: timerState,
Text: session.Text,
QrUrl: session.QRURL,
TimerType: proto.ScreenTimerType(session.TimerType),
}
if time.Since(session.LastSeen) <= 5*time.Second {
state.Status = "connected"
@@ -277,6 +279,15 @@ func (s *server) SetScreenMode(ctx context.Context, req *proto.SetScreenModeReq)
if _, err := s.gameService.GetGame(ctx, int(req.GameID)); err != nil {
return nil, status.Error(codes.NotFound, "игра не найдена")
}
if req.Mode == proto.ScreenMode_SCREEN_MODE_QR {
if !screen_service.ValidQR(req.QrUrl, req.Text) {
return nil, status.Error(codes.InvalidArgument, "Укажите ссылку HTTP/HTTPS до 2048 байт и текст до 10000 байт")
}
if err := s.screenService.SetQR(ctx, int(req.GameID), req.QrUrl, req.Text); err != nil {
return nil, status.Error(codes.Internal, "не удалось изменить QR-код")
}
return &proto.SetScreenModeRsp{}, nil
}
if err := s.screenService.SetMode(ctx, int(req.GameID), int32(req.Mode)); err != nil {
return nil, status.Error(codes.Internal, "не удалось изменить режим экранов")
}
@@ -287,12 +298,12 @@ func (s *server) SetScreenTimer(ctx context.Context, req *proto.SetScreenTimerRe
if !canManageScreens(ctx) {
return nil, status.Error(codes.PermissionDenied, "permission denied")
}
if req == nil || req.GameID <= 0 || req.DurationSeconds <= 0 || req.DurationSeconds > 24*60*60 {
if req == nil || req.GameID <= 0 || req.DurationSeconds <= 0 || req.DurationSeconds > 24*60*60 || !screen_service.ValidTimerType(int32(req.TimerType)) {
return nil, status.Error(codes.InvalidArgument, "некорректные параметры таймера")
}
label := strings.TrimSpace(req.Label)
if label == "" {
label = "Перерыв"
label = screen_service.TimerLabel(int32(req.TimerType))
}
if len(label) > 200 {
return nil, status.Error(codes.InvalidArgument, "слишком длинная надпись таймера")
@@ -300,7 +311,7 @@ func (s *server) SetScreenTimer(ctx context.Context, req *proto.SetScreenTimerRe
if _, err := s.gameService.GetGame(ctx, int(req.GameID)); err != nil {
return nil, status.Error(codes.NotFound, "игра не найдена")
}
if err := s.screenService.SetTimer(ctx, int(req.GameID), req.DurationSeconds, label); err != nil {
if err := s.screenService.SetTimer(ctx, int(req.GameID), req.DurationSeconds, label, int32(req.TimerType)); err != nil {
return nil, status.Error(codes.Internal, "не удалось настроить таймер экранов")
}
return &proto.SetScreenTimerRsp{}, nil
@@ -366,3 +377,29 @@ func (s *server) GetScreenResults(ctx context.Context, req *proto.GetScreenResul
}
return &proto.GetScreenResultsRsp{Questions: mapResultsQuestions(results.Questions), Teams: mapTeamResults(results.Teams)}, nil
}
func (s *server) GetScreenTeams(ctx context.Context, req *proto.GetScreenTeamsReq) (*proto.GetScreenTeamsRsp, error) {
if req == nil || req.ScreenID == "" || req.AccessToken == "" {
return nil, status.Error(codes.InvalidArgument, "некорректные данные экрана")
}
id, err := strconv.Atoi(req.ScreenID)
if err != nil || id <= 0 {
return nil, status.Error(codes.InvalidArgument, "некорректный идентификатор экрана")
}
session, err := s.screenService.Get(ctx, id, hashScreenToken(req.AccessToken))
if errors.Is(err, screen_service.ErrScreenNotFound) {
return nil, status.Error(codes.Unauthenticated, "недействительная сессия экрана")
}
if err != nil || session.GameID == nil {
return nil, status.Error(codes.FailedPrecondition, "экран не привязан к игре")
}
teams, err := s.teamService.GetScreenTeams(ctx, *session.GameID)
if err != nil {
return nil, status.Error(codes.Internal, "не удалось получить команды")
}
result := make([]*proto.ScreenTeam, 0, len(teams))
for _, team := range teams {
result = append(result, &proto.ScreenTeam{ID: team.ID, Name: team.Name})
}
return &proto.GetScreenTeamsRsp{Teams: result}, nil
}