Merge pull request #13 from SlimusMinus/add_likes

added likes on post
This commit is contained in:
SlimusMinus
2026-06-25 00:07:44 +03:00
committed by GitHub
3 changed files with 87 additions and 13 deletions

View File

@@ -23,4 +23,5 @@ public class PostResponse {
private List<String> images; private List<String> images;
private boolean isFavorite; private boolean isFavorite;
private Long userId; private Long userId;
private Long likeCount;
} }

View File

@@ -10,15 +10,22 @@ import org.springframework.data.jpa.repository.Query;
public interface FavoriteRepository extends JpaRepository<Favorite, Long> { public interface FavoriteRepository extends JpaRepository<Favorite, Long> {
boolean existsByUserAndPost(User user, Post post); boolean existsByUserAndPost(User user, Post post);
List<Favorite> findByUser(User user); List<Favorite> findByUser(User user);
void deleteByUserAndPost(User user, Post post); void deleteByUserAndPost(User user, Post post);
@Query(""" @Query("""
SELECT f.post.id FROM Favorite f SELECT f.post.id FROM Favorite f
WHERE f.user.id = :userId WHERE f.user.id = :userId
AND f.post.id IN :postIds AND f.post.id IN :postIds
""") """)
List<Long> findFavoritePostIds(Long userId, List<Long> postIds); List<Long> findFavoritePostIds(Long userId, List<Long> postIds);
// ADD THIS METHOD:
@Query("""
SELECT f.post.id, COUNT(f.id)
FROM Favorite f
WHERE f.post.id IN :postIds
GROUP BY f.post.id
""")
List<Object[]> countLikesByPostIds(List<Long> postIds);
} }

View File

@@ -4,11 +4,13 @@ import com.krylov.refound.dto.PostRequest;
import com.krylov.refound.dto.PostResponse; import com.krylov.refound.dto.PostResponse;
import com.krylov.refound.entity.Image; import com.krylov.refound.entity.Image;
import com.krylov.refound.entity.Post; import com.krylov.refound.entity.Post;
import com.krylov.refound.entity.User;
import com.krylov.refound.enums.ErrorCode; import com.krylov.refound.enums.ErrorCode;
import com.krylov.refound.enums.PostCategory; import com.krylov.refound.enums.PostCategory;
import com.krylov.refound.enums.PostStatus; import com.krylov.refound.enums.PostStatus;
import com.krylov.refound.exception.ApiException; import com.krylov.refound.exception.ApiException;
import com.krylov.refound.mapper.PostMapper; import com.krylov.refound.mapper.PostMapper;
import com.krylov.refound.repository.FavoriteRepository;
import com.krylov.refound.repository.ImageRepository; import com.krylov.refound.repository.ImageRepository;
import com.krylov.refound.repository.PostRepository; import com.krylov.refound.repository.PostRepository;
import java.io.IOException; import java.io.IOException;
@@ -16,8 +18,12 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
@@ -36,6 +42,7 @@ public class PostService {
private final ImageRepository imageRepository; private final ImageRepository imageRepository;
private final NominatimService nominatimService; private final NominatimService nominatimService;
private final UserService userService; private final UserService userService;
private final FavoriteRepository favoriteRepository;
public PostRequest create(PostRequest request, MultipartFile image) { public PostRequest create(PostRequest request, MultipartFile image) {
@@ -66,17 +73,76 @@ public class PostService {
} }
public List<PostResponse> getFeed() { public List<PostResponse> getFeed() {
return repository.findAll().stream() List<Post> posts = repository.findAll();
.map(post -> {
PostResponse response = mapper.toResponse(post); // Get all post IDs
log.info("Post {}: images = {}, phone = {}", post.getId(), response.getImages()); // ← сюда List<Long> postIds = posts.stream()
return response; .map(Post::getId)
}).toList(); .toList();
// Count likes for each post
Map<Long, Long> likeCounts = favoriteRepository.countLikesByPostIds(postIds).stream()
.collect(Collectors.toMap(
row -> (Long) row[0], // post ID
row -> (Long) row[1] // like count
));
// Get current user's favorites if authenticated
Set<Long> userFavoriteIds = new HashSet<>();
try {
User currentUser = userService.getCurrentUser();
userFavoriteIds = new HashSet<>(
favoriteRepository.findFavoritePostIds(currentUser.getId(), postIds)
);
} catch (Exception e) {
// User not authenticated - that's OK
}
// Set like counts and favorite status
final Set<Long> finalUserFavoriteIds = userFavoriteIds;
return posts.stream()
.map(post -> {
PostResponse response = mapper.toResponse(post);
response.setLikeCount(likeCounts.getOrDefault(post.getId(), 0L));
response.setFavorite(finalUserFavoriteIds.contains(post.getId()));
return response;
})
.toList();
} }
public List <PostResponse> getById(Long id) { public List <PostResponse> getById(Long id) {
return repository.findByUserId(id).stream().map(mapper::toResponse).toList(); List<Post> posts = repository.findByUserId(id);
List<Long> postIds = posts.stream()
.map(Post::getId)
.toList();
Map<Long, Long> likeCounts = favoriteRepository.countLikesByPostIds(postIds).stream()
.collect(Collectors.toMap(
row -> (Long) row[0],
row -> (Long) row[1]
));
Set<Long> userFavoriteIds = new HashSet<>();
try {
User currentUser = userService.getCurrentUser();
userFavoriteIds = new HashSet<>(
favoriteRepository.findFavoritePostIds(currentUser.getId(), postIds)
);
} catch (Exception e) {
// User not authenticated
}
final Set<Long> finalUserFavoriteIds = userFavoriteIds;
return posts.stream()
.map(post -> {
PostResponse response = mapper.toResponse(post);
response.setLikeCount(likeCounts.getOrDefault(post.getId(), 0L));
response.setFavorite(finalUserFavoriteIds.contains(post.getId()));
return response;
})
.toList();
} }
public PostResponse update(Long id, PostRequest request, MultipartFile image) { public PostResponse update(Long id, PostRequest request, MultipartFile image) {