admin dcf9b4bcbf
All checks were successful
continuous-integration/drone/push Build is passing
v0.0.33 Уведомления о лайках
2025-09-18 10:13:33 +03:00

172 lines
5.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"context"
"errors"
"tailly_back_v2/internal/domain"
"tailly_back_v2/internal/repository"
"time"
)
// Интерфейс сервиса лайков
type LikeService interface {
LikePost(ctx context.Context, userID, postID int) (*domain.Like, error)
UnlikePost(ctx context.Context, userID, postID int) error
GetByPostID(ctx context.Context, postID int) ([]*domain.Like, error)
GetCountForPost(ctx context.Context, postID int) (int, error)
CheckIfLiked(ctx context.Context, userID, postID int) (bool, error)
// Новые методы для уведомлений
GetLikeNotifications(ctx context.Context, userID int, unreadOnly bool, limit, offset int) ([]*domain.LikeNotification, int, int, error)
MarkLikeNotificationAsRead(ctx context.Context, notificationID, userID int) error
MarkAllLikeNotificationsAsRead(ctx context.Context, userID int) error
}
// Реализация сервиса лайков
type likeService struct {
likeRepo repository.LikeRepository
postRepo repository.PostRepository
userRepo repository.UserRepository // Добавляем для получения информации о пользователях
}
// Конструктор сервиса
func NewLikeService(likeRepo repository.LikeRepository, postRepo repository.PostRepository, userRepo repository.UserRepository) LikeService {
return &likeService{
likeRepo: likeRepo,
postRepo: postRepo,
userRepo: userRepo,
}
}
// Поставить лайк посту
func (s *likeService) LikePost(ctx context.Context, userID, postID int) (*domain.Like, error) {
// Проверяем существование поста
post, err := s.postRepo.GetByID(ctx, postID)
if err != nil {
if errors.Is(err, repository.ErrPostNotFound) {
return nil, errors.New("post not found")
}
return nil, err
}
// Проверяем, не поставил ли пользователь уже лайк
if liked, err := s.CheckIfLiked(ctx, userID, postID); err != nil {
return nil, err
} else if liked {
return nil, errors.New("you have already liked this post")
}
// Проверяем, что пользователь не лайкает свой собственный пост
if post.AuthorID == userID {
return nil, errors.New("cannot like your own post")
}
like := &domain.Like{
PostID: postID,
UserID: userID,
CreatedAt: time.Now(),
IsRead: false,
NotifiedAt: time.Now(),
}
if err := s.likeRepo.Create(ctx, like); err != nil {
return nil, err
}
return like, nil
}
// Убрать лайк с поста
func (s *likeService) UnlikePost(ctx context.Context, userID, postID int) error {
// Проверяем существование поста
if _, err := s.postRepo.GetByID(ctx, postID); err != nil {
if errors.Is(err, repository.ErrPostNotFound) {
return errors.New("post not found")
}
return err
}
// Проверяем, ставил ли пользователь лайк
if liked, err := s.CheckIfLiked(ctx, userID, postID); err != nil {
return err
} else if !liked {
return errors.New("you haven't liked this post yet")
}
return s.likeRepo.DeleteByUserAndPost(ctx, userID, postID)
}
// Получить все лайки для поста
func (s *likeService) GetByPostID(ctx context.Context, postID int) ([]*domain.Like, error) {
// Проверяем существование поста
if _, err := s.postRepo.GetByID(ctx, postID); err != nil {
if errors.Is(err, repository.ErrPostNotFound) {
return nil, errors.New("post not found")
}
return nil, err
}
likes, err := s.likeRepo.GetByPostID(ctx, postID)
if err != nil {
return nil, err
}
if likes == nil {
return []*domain.Like{}, nil
}
return likes, nil
}
// Получить количество лайков для поста
func (s *likeService) GetCountForPost(ctx context.Context, postID int) (int, error) {
likes, err := s.GetByPostID(ctx, postID)
if err != nil {
return 0, err
}
return len(likes), nil
}
// Проверить, поставил ли пользователь лайк
func (s *likeService) CheckIfLiked(ctx context.Context, userID, postID int) (bool, error) {
_, err := s.likeRepo.GetByUserAndPost(ctx, userID, postID)
if err != nil {
if errors.Is(err, repository.ErrLikeNotFound) {
return false, nil
}
return false, err
}
return true, nil
}
// Новые методы для уведомлений
func (s *likeService) GetLikeNotifications(ctx context.Context, userID int, unreadOnly bool, limit, offset int) ([]*domain.LikeNotification, int, int, error) {
var notifications []*domain.LikeNotification
var err error
if unreadOnly {
notifications, err = s.likeRepo.GetUnreadLikeNotifications(ctx, userID, limit, offset)
} else {
notifications, err = s.likeRepo.GetAllLikeNotifications(ctx, userID, limit, offset)
}
if err != nil {
return nil, 0, 0, err
}
totalCount, unreadCount, err := s.likeRepo.GetLikeNotificationCounts(ctx, userID)
if err != nil {
return nil, 0, 0, err
}
return notifications, totalCount, unreadCount, nil
}
func (s *likeService) MarkLikeNotificationAsRead(ctx context.Context, notificationID, userID int) error {
return s.likeRepo.MarkLikeNotificationAsRead(ctx, notificationID, userID)
}
func (s *likeService) MarkAllLikeNotificationsAsRead(ctx context.Context, userID int) error {
return s.likeRepo.MarkAllLikeNotificationsAsRead(ctx, userID)
}