Merge pull request #29 from SlimusMinus/add-favorites_posts

added functional favorites posts
This commit is contained in:
SlimusMinus
2026-08-24 00:49:00 +03:00
committed by GitHub
5 changed files with 64 additions and 20 deletions

View File

@@ -30,4 +30,12 @@ public class FavoriteController {
log.info("get all likes"); log.info("get all likes");
return service.getFavorites(); return service.getFavorites();
} }
@GetMapping("/posts")
public List<PostResponse> getAllFavoritesPosts(){
log.info("get all favorites posts");
return service.getAllFavoritesPosts();
}
} }

View File

@@ -6,6 +6,7 @@ import com.krylov.refound.entity.User;
import java.util.List; import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface FavoriteRepository extends JpaRepository<Favorite, Long> { public interface FavoriteRepository extends JpaRepository<Favorite, Long> {
@@ -29,4 +30,7 @@ public interface FavoriteRepository extends JpaRepository<Favorite, Long> {
GROUP BY f.post.id GROUP BY f.post.id
\s""") \s""")
List<Object[]> countLikesByPostIds(List<Long> postIds); List<Object[]> countLikesByPostIds(List<Long> postIds);
@Query("select f.post.id from Favorite f where f.user.id = :userId")
List<Long> findPostIdsByUserId(@Param("userId") Long userId);
} }

View File

@@ -50,4 +50,7 @@ public interface PostRepository extends JpaRepository<Post, Long>, JpaSpecificat
""") """)
List<MapMarkerDto> findMapMarkers(@Param("excludedStatuses") Collection<PostStatus> excludedStatuses); List<MapMarkerDto> findMapMarkers(@Param("excludedStatuses") Collection<PostStatus> excludedStatuses);
@Query("SELECT p FROM Post p WHERE p.id = :postIds")
List<Long> findFavoritePostIds(List<Long> postIds);
} }

View File

@@ -10,6 +10,8 @@ import com.krylov.refound.mapper.PostMapper;
import com.krylov.refound.repository.FavoriteRepository; import com.krylov.refound.repository.FavoriteRepository;
import com.krylov.refound.repository.PostRepository; import com.krylov.refound.repository.PostRepository;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -18,10 +20,33 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class FavoriteService { public class FavoriteService {
private final FavoriteRepository repository; private final FavoriteRepository repository;
private final PostRepository postRepository; private final PostRepository postRepository;
private final UserService userService; private final UserService userService;
private final PostMapper mapper; 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) @Transactional(readOnly = true)
public List<PostResponse> getFavorites() { public List<PostResponse> getFavorites() {
@@ -33,24 +58,28 @@ public class FavoriteService {
.toList(); .toList();
} }
@Transactional public List<PostResponse> getAllFavoritesPosts() {
public void toggle(Long postId) {
User user = userService.getCurrentUser(); User user = userService.getCurrentUser();
if (user == null) {
Post post = postRepository.findById(postId).orElseThrow(() -> new ApiException( return List.of();
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);
} }
List<Long> favoritePostIds = repository.findPostIdsByUserId(user.getId());
if (favoritePostIds.isEmpty()) {
return List.of();
}
List<Post> posts = postRepository.findAllById(favoritePostIds);
List<Long> postIds = posts.stream()
.map(Post::getId)
.toList();
Map<Long, Long> likeCounts = postService.countLikes(postIds);
Set<Long> userFavoriteIds = postService.currentUserFavoriteIds(postIds); // тут будет == postIds, но ок для единообразия
return posts.stream()
.map(post -> postService.toResponse(post, likeCounts, userFavoriteIds, true))
.toList();
} }
} }

View File

@@ -325,7 +325,7 @@ public class PostService {
} }
} }
private Map<Long, Long> countLikes(List<Long> postIds) { public Map<Long, Long> countLikes(List<Long> postIds) {
if (postIds.isEmpty()) { if (postIds.isEmpty()) {
return Map.of(); return Map.of();
} }
@@ -340,7 +340,7 @@ public class PostService {
* Возвращает id постов, лайкнутых текущим пользователем, либо пустой набор, * Возвращает id постов, лайкнутых текущим пользователем, либо пустой набор,
* если пользователь не авторизован. * если пользователь не авторизован.
*/ */
private Set<Long> currentUserFavoriteIds(List<Long> postIds) { public Set<Long> currentUserFavoriteIds(List<Long> postIds) {
if (postIds.isEmpty()) { if (postIds.isEmpty()) {
return Set.of(); return Set.of();
} }
@@ -360,7 +360,7 @@ public class PostService {
} }
} }
private PostResponse toResponse(Post post, Map<Long, Long> likeCounts, Set<Long> userFavoriteIds, boolean includeUserRole) { public PostResponse toResponse(Post post, Map<Long, Long> likeCounts, Set<Long> userFavoriteIds, boolean includeUserRole) {
PostResponse response = mapper.toResponse(post); PostResponse response = mapper.toResponse(post);
response.setLikeCount(likeCounts.getOrDefault(post.getId(), 0L)); response.setLikeCount(likeCounts.getOrDefault(post.getId(), 0L));
response.setFavorite(userFavoriteIds.contains(post.getId())); response.setFavorite(userFavoriteIds.contains(post.getId()));