diff --git a/.gitignore b/.gitignore index 1b37fe0..59bfdc9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .env -*.exe \ No newline at end of file +*.exe +mockery diff --git a/internal/handlers/bot/queue.go b/internal/handlers/bot/queue.go index ecb96ce..ea96bbd 100644 --- a/internal/handlers/bot/queue.go +++ b/internal/handlers/bot/queue.go @@ -118,7 +118,12 @@ func (b *Bot) LetAhead(c telebot.Context) error { // Выбрать предмет func (b *Bot) ChooseSubject(c telebot.Context) error { + // Данные о пользователе user := c.Get("user").(models.User) + entry := models.QueueEntry{ + ChatID: fmt.Sprint(c.Chat().ID), + } + groups, err := b.scheduleService.GetGroups(b.ctx, user.Group) if err != nil { return err @@ -144,12 +149,26 @@ func (b *Bot) ChooseSubject(c telebot.Context) error { Subject: data, } + // Проверяем находится ли в данной очереди человек + _, err := b.queueService.Pos(b.ctx, queue, entry) + if errors.Is(err, services.ErrNotFound) { + btnText.WriteRune('🟥') + } else if err == nil { + btnText.WriteRune('🟩') + } else { + return err + } + // Проверяем, есть ли уже очередь по этому предмету - _, err := b.queueService.Range(b.ctx, queue) - if err == nil { - btnText.WriteString("✅ ") - } else if errors.Is(err, services.ErrNotFound) { - btnText.WriteString("❌ ") + length, err := b.queueService.Len(b.ctx, queue) + if err != nil { + return err + } + + if length != 0 { + fmt.Fprintf(&btnText, " (%d чел.) ", length) + } else { + btnText.WriteString(" (Пусто) ") } btnText.WriteString(subjects[i]) @@ -177,10 +196,6 @@ func (b *Bot) ChooseSubject(c telebot.Context) error { Subject: subject, } - entry := models.QueueEntry{ - ChatID: fmt.Sprint(c.Chat().ID), - } - err = b.queueService.SaveToCache(b.ctx, c.Chat().ID, queue) if err != nil { return err @@ -232,11 +247,11 @@ func (b *Bot) showSubject( entry models.QueueEntry, ) error { var sb strings.Builder - sb.WriteString("Очередь " + queue.Key()) + sb.WriteString(queue.Key()) entries, err := b.queueService.Range(b.ctx, queue) if errors.Is(err, services.ErrNotFound) { - sb.WriteString("\nОчередь не создана") + sb.WriteString("\nОчередь пуста") } else if err == nil { // Находим имена пользователей for i, entry := range entries { @@ -250,20 +265,24 @@ func (b *Bot) showSubject( return err } - sb.WriteString(fmt.Sprintf("\n%3d. %s", i+1, user.Name)) + // Если это текущий пользователь, то выделяем жирным для видимости + if chatID == c.Chat().ID { + fmt.Fprintf(&sb, "\n*%3d. %s*", i+1, user.Name) + } else { + fmt.Fprintf(&sb, "\n%3d. %s", i+1, user.Name) + } } // Находим позицию текущего пользователя pos, err := b.queueService.Pos(b.ctx, queue, entry) - msgText := fmt.Sprintf("\nВаша текущая позиция в очереди - %d", pos) - if errors.Is(err, services.ErrNotFound) { - msgText = "\nВы не записаны в очередь" - } else if err != nil { + if err == nil { + fmt.Fprintf(&sb, "\nВы %d в очереди", pos) + } else if errors.Is(err, services.ErrNotFound) { + sb.WriteString("\nВы не записаны в очередь") + } else { return err } - - sb.WriteString(msgText) } else { return err } @@ -273,7 +292,7 @@ func (b *Bot) showSubject( menu = b.subjectAdminMenu } - err = c.Edit(sb.String(), menu) + err = c.Edit(sb.String(), menu, telebot.ModeMarkdown) if err != nil && !errors.Is(err, telebot.ErrSameMessageContent) { return err } diff --git a/internal/handlers/bot/users.go b/internal/handlers/bot/users.go index 7ca7394..d88893d 100644 --- a/internal/handlers/bot/users.go +++ b/internal/handlers/bot/users.go @@ -175,14 +175,21 @@ func (b *Bot) getUser(c tele.Context) (models.User, error) { // Функция отображения профиля func (b *Bot) showProfile(c tele.Context, user models.User) error { - profile := fmt.Sprintf( - "Группа: %s\nФИО: %s\nПрава админа: %t", - user.Group, user.Name, user.QueueAccess, + var profileStr strings.Builder + fmt.Fprintf( + &profileStr, + "ФИО: %s\nГруппа: %s\nДоступ к очереди: ", + user.Name, user.Group, ) + if user.QueueAccess { + profileStr.WriteString("✔️") + } else { + profileStr.WriteString("✖️") + } if msg, ok := c.Get("msg").(tele.Editable); ok { - _, err := c.Bot().Edit(msg, profile, b.startMenu) + _, err := c.Bot().Edit(msg, profileStr.String(), b.startMenu) return err } else { - return c.Send(profile, b.startMenu) + return c.Send(profileStr.String(), b.startMenu) } } diff --git a/internal/interfaces/services.go b/internal/interfaces/services.go index 845edfc..76fccf6 100644 --- a/internal/interfaces/services.go +++ b/internal/interfaces/services.go @@ -61,6 +61,11 @@ type QueueService interface { queue models.Queue, entry models.QueueEntry, ) error + // Получает длину очереди + Len( + ctx context.Context, + queue models.Queue, + ) (int64, error) } // Сервис пользователей diff --git a/internal/repositories/redis/queue.go b/internal/repositories/redis/queue.go index 687bae8..6bffe9b 100644 --- a/internal/repositories/redis/queue.go +++ b/internal/repositories/redis/queue.go @@ -123,9 +123,6 @@ func (s *Storage) Len( len, err := s.cl.LLen(ctx, queue.Key()).Result() if err != nil { - if errors.Is(err, redis.Nil) { - return 0, fmt.Errorf("%s: %w", op, repositories.ErrNotFound) - } return 0, fmt.Errorf("%s: %w", op, err) } diff --git a/internal/services/queue/queue.go b/internal/services/queue/queue.go index 3671cc8..2cddf50 100644 --- a/internal/services/queue/queue.go +++ b/internal/services/queue/queue.go @@ -296,3 +296,31 @@ func (q *Queue) Remove( return nil } + +func (q *Queue) Len( + ctx context.Context, + queue models.Queue, +) (int64, error) { + const op = "queue.Len" + + log := q.log.With( + slog.String("op", op), + slog.String("queue_group", queue.Group), + slog.String("queue_subject", queue.Subject), + ) + + log.Info("Trying to get queue length") + + length, err := q.queueLength.Len(ctx, queue) + if err != nil { + log.Error("Failed to get queue length", + slog.String("err", err.Error()), + ) + + return 0, fmt.Errorf("%s: %w", op, err) + } + + log.Info("Successfully got") + + return length, nil +}