From fe6e98170b41dd0ccefc48ac9f4fa5fe3f8f952c Mon Sep 17 00:00:00 2001 From: SlimusMinus Date: Mon, 24 Aug 2026 00:48:22 +0300 Subject: [PATCH] added functional favorites posts --- .../controller/FavoriteController.java | 8 +++ .../repository/FavoriteRepository.java | 4 ++ .../refound/repository/PostRepository.java | 3 + .../refound/service/FavoriteService.java | 63 ++++++++++++++----- .../krylov/refound/service/PostService.java | 6 +- 5 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/krylov/refound/controller/FavoriteController.java b/src/main/java/com/krylov/refound/controller/FavoriteController.java index 0244d9f..e74c23d 100644 --- a/src/main/java/com/krylov/refound/controller/FavoriteController.java +++ b/src/main/java/com/krylov/refound/controller/FavoriteController.java @@ -30,4 +30,12 @@ public class FavoriteController { log.info("get all likes"); return service.getFavorites(); } + + @GetMapping("/posts") + public List getAllFavoritesPosts(){ + log.info("get all favorites posts"); + return service.getAllFavoritesPosts(); + } + + } diff --git a/src/main/java/com/krylov/refound/repository/FavoriteRepository.java b/src/main/java/com/krylov/refound/repository/FavoriteRepository.java index e08ff34..c376aad 100644 --- a/src/main/java/com/krylov/refound/repository/FavoriteRepository.java +++ b/src/main/java/com/krylov/refound/repository/FavoriteRepository.java @@ -6,6 +6,7 @@ import com.krylov.refound.entity.User; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface FavoriteRepository extends JpaRepository { @@ -29,4 +30,7 @@ public interface FavoriteRepository extends JpaRepository { GROUP BY f.post.id \s""") List countLikesByPostIds(List postIds); + + @Query("select f.post.id from Favorite f where f.user.id = :userId") + List findPostIdsByUserId(@Param("userId") Long userId); } diff --git a/src/main/java/com/krylov/refound/repository/PostRepository.java b/src/main/java/com/krylov/refound/repository/PostRepository.java index 24b8fe6..ecc60a9 100644 --- a/src/main/java/com/krylov/refound/repository/PostRepository.java +++ b/src/main/java/com/krylov/refound/repository/PostRepository.java @@ -50,4 +50,7 @@ public interface PostRepository extends JpaRepository, JpaSpecificat """) List findMapMarkers(@Param("excludedStatuses") Collection excludedStatuses); + @Query("SELECT p FROM Post p WHERE p.id = :postIds") + List findFavoritePostIds(List postIds); + } \ No newline at end of file diff --git a/src/main/java/com/krylov/refound/service/FavoriteService.java b/src/main/java/com/krylov/refound/service/FavoriteService.java index a1a86b5..665dcb9 100644 --- a/src/main/java/com/krylov/refound/service/FavoriteService.java +++ b/src/main/java/com/krylov/refound/service/FavoriteService.java @@ -10,6 +10,8 @@ import com.krylov.refound.mapper.PostMapper; import com.krylov.refound.repository.FavoriteRepository; import com.krylov.refound.repository.PostRepository; import java.util.List; +import java.util.Map; +import java.util.Set; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -18,10 +20,33 @@ import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor public class FavoriteService { + private final FavoriteRepository repository; private final PostRepository postRepository; private final UserService userService; private final PostMapper mapper; + private final PostService postService; + + @Transactional + public void toggle(Long postId) { + + User user = userService.getCurrentUser(); + + Post post = postRepository.findById(postId).orElseThrow(() -> new ApiException( + ErrorCode.NOT_FOUND, + "Post not found", + HttpStatus.NOT_FOUND + )); + + if (repository.existsByUserAndPost(user, post)) { + repository.deleteByUserAndPost(user, post); + } else { + Favorite f = new Favorite(); + f.setUser(user); + f.setPost(post); + repository.save(f); + } + } @Transactional(readOnly = true) public List getFavorites() { @@ -33,24 +58,28 @@ public class FavoriteService { .toList(); } - @Transactional - public void toggle(Long postId) { - + public List getAllFavoritesPosts() { User user = userService.getCurrentUser(); - - Post post = postRepository.findById(postId).orElseThrow(() -> new ApiException( - ErrorCode.NOT_FOUND, - "Post not found", - HttpStatus.NOT_FOUND - )); - - if (repository.existsByUserAndPost(user, post)) { - repository.deleteByUserAndPost(user, post); - } else { - Favorite f = new Favorite(); - f.setUser(user); - f.setPost(post); - repository.save(f); + if (user == null) { + return List.of(); } + + List favoritePostIds = repository.findPostIdsByUserId(user.getId()); + if (favoritePostIds.isEmpty()) { + return List.of(); + } + + List posts = postRepository.findAllById(favoritePostIds); + + List postIds = posts.stream() + .map(Post::getId) + .toList(); + + Map likeCounts = postService.countLikes(postIds); + Set userFavoriteIds = postService.currentUserFavoriteIds(postIds); // тут будет == postIds, но ок для единообразия + + return posts.stream() + .map(post -> postService.toResponse(post, likeCounts, userFavoriteIds, true)) + .toList(); } } diff --git a/src/main/java/com/krylov/refound/service/PostService.java b/src/main/java/com/krylov/refound/service/PostService.java index efb944f..502130b 100644 --- a/src/main/java/com/krylov/refound/service/PostService.java +++ b/src/main/java/com/krylov/refound/service/PostService.java @@ -325,7 +325,7 @@ public class PostService { } } - private Map countLikes(List postIds) { + public Map countLikes(List postIds) { if (postIds.isEmpty()) { return Map.of(); } @@ -340,7 +340,7 @@ public class PostService { * Возвращает id постов, лайкнутых текущим пользователем, либо пустой набор, * если пользователь не авторизован. */ - private Set currentUserFavoriteIds(List postIds) { + public Set currentUserFavoriteIds(List postIds) { if (postIds.isEmpty()) { return Set.of(); } @@ -360,7 +360,7 @@ public class PostService { } } - private PostResponse toResponse(Post post, Map likeCounts, Set userFavoriteIds, boolean includeUserRole) { + public PostResponse toResponse(Post post, Map likeCounts, Set userFavoriteIds, boolean includeUserRole) { PostResponse response = mapper.toResponse(post); response.setLikeCount(likeCounts.getOrDefault(post.getId(), 0L)); response.setFavorite(userFavoriteIds.contains(post.getId()));