deleted likes
This commit is contained in:
@@ -14,18 +14,14 @@ import com.krylov.refound.enums.PostStatus;
|
||||
import com.krylov.refound.enums.PostType;
|
||||
import com.krylov.refound.exception.ApiException;
|
||||
import com.krylov.refound.mapper.PostMapper;
|
||||
import com.krylov.refound.repository.FavoriteRepository;
|
||||
import com.krylov.refound.repository.ImageRepository;
|
||||
import com.krylov.refound.repository.PostRepository;
|
||||
import com.krylov.refound.util.PostSpecification;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -50,7 +46,6 @@ public class PostService {
|
||||
private final ImageRepository imageRepository;
|
||||
private final GeocodingService geocodingService;
|
||||
private final UserService userService;
|
||||
private final FavoriteRepository favoriteRepository;
|
||||
private final FileStorageService fileStorageService;
|
||||
private final StatisticsService statisticsService;
|
||||
private final ObjectMapper objectMapper;
|
||||
@@ -84,21 +79,13 @@ public class PostService {
|
||||
}
|
||||
|
||||
public Page<PostResponse> getFeed(String search, Pageable pageable) {
|
||||
Specification<Post> spec = PostSpecification.hasSearch(search).and((root, query, cb) -> root.get("status").in(FEED_VISIBLE_STATUSES));
|
||||
Specification<Post> spec = PostSpecification.hasSearch(search)
|
||||
.and((root, query, cb) ->
|
||||
root.get("status").in(FEED_VISIBLE_STATUSES));
|
||||
|
||||
Page<Post> postsPage = postRepository.findAll(spec, pageable);
|
||||
|
||||
List<Long> postIds = postsPage.getContent().stream()
|
||||
.map(Post::getId)
|
||||
.toList();
|
||||
|
||||
if (postIds.isEmpty()) {
|
||||
return Page.empty(pageable);
|
||||
}
|
||||
|
||||
Map<Long, Long> likeCounts = countLikes(postIds);
|
||||
Set<Long> userFavoriteIds = currentUserFavoriteIds(postIds);
|
||||
|
||||
return postsPage.map(post -> toResponse(post, likeCounts, userFavoriteIds, true));
|
||||
return postsPage.map(post -> toResponse(post, true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,15 +102,8 @@ public class PostService {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
List<Long> postIds = posts.stream()
|
||||
.map(Post::getId)
|
||||
.toList();
|
||||
|
||||
Map<Long, Long> likeCounts = countLikes(postIds);
|
||||
Set<Long> userFavoriteIds = currentUserFavoriteIds(postIds);
|
||||
|
||||
return posts.stream()
|
||||
.map(post -> toResponse(post, likeCounts, userFavoriteIds, false))
|
||||
.map(post -> toResponse(post, false))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -203,9 +183,6 @@ public class PostService {
|
||||
Post post = postRepository.findById(id)
|
||||
.orElseThrow(() -> new ApiException(ErrorCode.NOT_FOUND, "Post not found", HttpStatus.NOT_FOUND));
|
||||
|
||||
// Сначала избранное — иначе DataIntegrityViolationException (FK) при удалении поста
|
||||
favoriteRepository.deleteByPostIn(List.of(post));
|
||||
|
||||
// Без этого файлы останутся в MinIO мусором после удаления объявления
|
||||
post.getImages().forEach(img -> deleteFileQuietly(img.getUrl()));
|
||||
|
||||
@@ -234,13 +211,7 @@ public class PostService {
|
||||
post.setStatus(newStatus);
|
||||
Post updated = postRepository.save(post);
|
||||
log.info("Статус поста id={} изменён: {} -> {}", id, previousStatus, newStatus);
|
||||
|
||||
List<Long> postIds = List.of(id);
|
||||
PostResponse response = mapper.toResponse(updated);
|
||||
response.setLikeCount(countLikes(postIds).getOrDefault(id, 0L));
|
||||
response.setFavorite(currentUserFavoriteIds(postIds).contains(id));
|
||||
|
||||
return response;
|
||||
return mapper.toResponse(updated);
|
||||
}
|
||||
|
||||
public List<PostResponse> searchByCity(String city) {
|
||||
@@ -256,15 +227,8 @@ public class PostService {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
List<Long> postIds = posts.stream()
|
||||
.map(Post::getId)
|
||||
.toList();
|
||||
|
||||
Map<Long, Long> likeCounts = countLikes(postIds);
|
||||
Set<Long> userFavoriteIds = currentUserFavoriteIds(postIds);
|
||||
|
||||
return posts.stream()
|
||||
.map(post -> toResponse(post, likeCounts, userFavoriteIds, true))
|
||||
.map(post -> toResponse(post, true))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -328,45 +292,8 @@ public class PostService {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Long, Long> countLikes(List<Long> postIds) {
|
||||
if (postIds.isEmpty()) {
|
||||
return Map.of();
|
||||
}
|
||||
return favoriteRepository.countLikesByPostIds(postIds).stream()
|
||||
.collect(Collectors.toMap(
|
||||
row -> (Long) row[0],
|
||||
row -> (Long) row[1]
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает id постов, лайкнутых текущим пользователем, либо пустой набор,
|
||||
* если пользователь не авторизован.
|
||||
*/
|
||||
public Set<Long> currentUserFavoriteIds(List<Long> postIds) {
|
||||
if (postIds.isEmpty()) {
|
||||
return Set.of();
|
||||
}
|
||||
try {
|
||||
User currentUser = userService.getCurrentUser();
|
||||
return new HashSet<>(favoriteRepository.findFavoritePostIds(currentUser.getId(), postIds));
|
||||
} catch (ApiException e) {
|
||||
if (e.getErrorCode() == ErrorCode.UNAUTHORIZED) {
|
||||
// Ожидаемо для анонимных пользователей — не считаем ошибкой
|
||||
log.debug("Избранное не подгружено: пользователь не авторизован");
|
||||
} else {
|
||||
// Подозрительный случай: в SecurityContext есть аутентификация с логином,
|
||||
// но пользователя с таким логином нет в БД (например, удалён после выдачи токена)
|
||||
log.warn("Избранное не подгружено: {}", e.getMessage());
|
||||
}
|
||||
return Set.of();
|
||||
}
|
||||
}
|
||||
|
||||
public PostResponse toResponse(Post post, Map<Long, Long> likeCounts, Set<Long> userFavoriteIds, boolean includeUserRole) {
|
||||
public PostResponse toResponse(Post post, boolean includeUserRole) {
|
||||
PostResponse response = mapper.toResponse(post);
|
||||
response.setLikeCount(likeCounts.getOrDefault(post.getId(), 0L));
|
||||
response.setFavorite(userFavoriteIds.contains(post.getId()));
|
||||
response.setReward(post.getIsReward());
|
||||
if (includeUserRole) {
|
||||
response.setUserRole(post.getUser().getRole());
|
||||
@@ -389,10 +316,6 @@ public class PostService {
|
||||
Post post = postRepository.findById(postId)
|
||||
.orElseThrow(() -> new ApiException(ErrorCode.NOT_FOUND, "Post not found", HttpStatus.NOT_FOUND));
|
||||
|
||||
List<Long> postIds = List.of(postId);
|
||||
Map<Long, Long> likeCounts = countLikes(postIds);
|
||||
Set<Long> userFavoriteIds = currentUserFavoriteIds(postIds);
|
||||
|
||||
return toResponse(post, likeCounts, userFavoriteIds, true);
|
||||
return toResponse(post, true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user