mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-27 16:40:50 +08:00
Merge pull request #1136 from nagisa77/bugfix/1053
fix: 性能优化,首页下拉更新,实测6秒左右,稍慢 #1053
This commit is contained in:
@@ -217,11 +217,7 @@ public class PostController {
|
|||||||
// userVisitService.recordVisit(auth.getName());
|
// userVisitService.recordVisit(auth.getName());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return postService
|
return postMapper.toListDtos(postService.defaultListPosts(ids, tids, page, pageSize));
|
||||||
.defaultListPosts(ids, tids, page, pageSize)
|
|
||||||
.stream()
|
|
||||||
.map(postMapper::toSummaryDto)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/recent")
|
@GetMapping("/recent")
|
||||||
@@ -269,11 +265,7 @@ public class PostController {
|
|||||||
// userVisitService.recordVisit(auth.getName());
|
// userVisitService.recordVisit(auth.getName());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return postService
|
return postMapper.toListDtos(postService.listPostsByViews(ids, tids, page, pageSize));
|
||||||
.listPostsByViews(ids, tids, page, pageSize)
|
|
||||||
.stream()
|
|
||||||
.map(postMapper::toSummaryDto)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/latest-reply")
|
@GetMapping("/latest-reply")
|
||||||
@@ -305,8 +297,7 @@ public class PostController {
|
|||||||
// userVisitService.recordVisit(auth.getName());
|
// userVisitService.recordVisit(auth.getName());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
List<Post> posts = postService.listPostsByLatestReply(ids, tids, page, pageSize);
|
return postMapper.toListDtos(postService.listPostsByLatestReply(ids, tids, page, pageSize));
|
||||||
return posts.stream().map(postMapper::toSummaryDto).collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/featured")
|
@GetMapping("/featured")
|
||||||
@@ -333,10 +324,6 @@ public class PostController {
|
|||||||
// if (auth != null) {
|
// if (auth != null) {
|
||||||
// userVisitService.recordVisit(auth.getName());
|
// userVisitService.recordVisit(auth.getName());
|
||||||
// }
|
// }
|
||||||
return postService
|
return postMapper.toListDtos(postService.listFeaturedPosts(ids, tids, page, pageSize));
|
||||||
.listFeaturedPosts(ids, tids, page, pageSize)
|
|
||||||
.stream()
|
|
||||||
.map(postMapper::toSummaryDto)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,38 @@ public class PostMapper {
|
|||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<PostSummaryDto> toListDtos(List<Post> posts) {
|
||||||
|
if (posts == null || posts.isEmpty()) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
Map<Long, List<User>> participantsMap = commentService.getParticipantsForPosts(posts, 5);
|
||||||
|
return posts
|
||||||
|
.stream()
|
||||||
|
.map(post -> {
|
||||||
|
PostSummaryDto dto = new PostSummaryDto();
|
||||||
|
applyListFields(post, dto);
|
||||||
|
List<User> participants = participantsMap.get(post.getId());
|
||||||
|
if (participants != null) {
|
||||||
|
dto.setParticipants(
|
||||||
|
participants.stream().map(userMapper::toAuthorDto).collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
dto.setParticipants(List.of());
|
||||||
|
}
|
||||||
|
dto.setReactions(List.of());
|
||||||
|
return dto;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostSummaryDto toListDto(Post post) {
|
||||||
|
PostSummaryDto dto = new PostSummaryDto();
|
||||||
|
applyListFields(post, dto);
|
||||||
|
dto.setParticipants(List.of());
|
||||||
|
dto.setReactions(List.of());
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
public PostDetailDto toDetailDto(Post post, String viewer) {
|
public PostDetailDto toDetailDto(Post post, String viewer) {
|
||||||
PostDetailDto dto = new PostDetailDto();
|
PostDetailDto dto = new PostDetailDto();
|
||||||
applyCommon(post, dto);
|
applyCommon(post, dto);
|
||||||
@@ -61,6 +93,25 @@ public class PostMapper {
|
|||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyListFields(Post post, PostSummaryDto dto) {
|
||||||
|
dto.setId(post.getId());
|
||||||
|
dto.setTitle(post.getTitle());
|
||||||
|
dto.setContent(post.getContent());
|
||||||
|
dto.setCreatedAt(post.getCreatedAt());
|
||||||
|
dto.setAuthor(userMapper.toAuthorDto(post.getAuthor()));
|
||||||
|
dto.setCategory(categoryMapper.toDto(post.getCategory()));
|
||||||
|
dto.setTags(post.getTags().stream().map(tagMapper::toDto).collect(Collectors.toList()));
|
||||||
|
dto.setViews(post.getViews());
|
||||||
|
dto.setCommentCount(post.getCommentCount());
|
||||||
|
dto.setStatus(post.getStatus());
|
||||||
|
dto.setPinnedAt(post.getPinnedAt());
|
||||||
|
dto.setLastReplyAt(post.getLastReplyAt());
|
||||||
|
dto.setRssExcluded(post.getRssExcluded() == null || post.getRssExcluded());
|
||||||
|
dto.setClosed(post.isClosed());
|
||||||
|
dto.setVisibleScope(post.getVisibleScope());
|
||||||
|
dto.setType(post.getType());
|
||||||
|
}
|
||||||
|
|
||||||
private void applyCommon(Post post, PostSummaryDto dto) {
|
private void applyCommon(Post post, PostSummaryDto dto) {
|
||||||
dto.setId(post.getId());
|
dto.setId(post.getId());
|
||||||
dto.setTitle(post.getTitle());
|
dto.setTitle(post.getTitle());
|
||||||
|
|||||||
@@ -25,6 +25,13 @@ public interface CommentRepository extends JpaRepository<Comment, Long> {
|
|||||||
@org.springframework.data.repository.query.Param("post") Post post
|
@org.springframework.data.repository.query.Param("post") Post post
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@org.springframework.data.jpa.repository.Query(
|
||||||
|
"SELECT DISTINCT c.post.id, c.author FROM Comment c WHERE c.post.id IN :postIds"
|
||||||
|
)
|
||||||
|
java.util.List<Object[]> findDistinctAuthorsByPostIds(
|
||||||
|
@org.springframework.data.repository.query.Param("postIds") java.util.List<Long> postIds
|
||||||
|
);
|
||||||
|
|
||||||
@org.springframework.data.jpa.repository.Query(
|
@org.springframework.data.jpa.repository.Query(
|
||||||
"SELECT MAX(c.createdAt) FROM Comment c WHERE c.post = :post"
|
"SELECT MAX(c.createdAt) FROM Comment c WHERE c.post = :post"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ public interface PostRepository extends JpaRepository<Post, Long> {
|
|||||||
List<Post> findByStatusOrderByCreatedAtDesc(PostStatus status, Pageable pageable);
|
List<Post> findByStatusOrderByCreatedAtDesc(PostStatus status, Pageable pageable);
|
||||||
List<Post> findByStatusOrderByViewsDesc(PostStatus status);
|
List<Post> findByStatusOrderByViewsDesc(PostStatus status);
|
||||||
List<Post> findByStatusOrderByViewsDesc(PostStatus status, Pageable pageable);
|
List<Post> findByStatusOrderByViewsDesc(PostStatus status, Pageable pageable);
|
||||||
|
List<Post> findByStatusOrderByPinnedAtDescViewsDesc(PostStatus status, Pageable pageable);
|
||||||
|
List<Post> findByStatusOrderByPinnedAtDescLastReplyAtDesc(PostStatus status, Pageable pageable);
|
||||||
List<Post> findByStatusAndCreatedAtGreaterThanEqualOrderByCreatedAtDesc(
|
List<Post> findByStatusAndCreatedAtGreaterThanEqualOrderByCreatedAtDesc(
|
||||||
PostStatus status,
|
PostStatus status,
|
||||||
LocalDateTime createdAt
|
LocalDateTime createdAt
|
||||||
@@ -43,6 +45,16 @@ public interface PostRepository extends JpaRepository<Post, Long> {
|
|||||||
PostStatus status,
|
PostStatus status,
|
||||||
Pageable pageable
|
Pageable pageable
|
||||||
);
|
);
|
||||||
|
List<Post> findByCategoryInAndStatusOrderByPinnedAtDescViewsDesc(
|
||||||
|
List<Category> categories,
|
||||||
|
PostStatus status,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
List<Post> findByCategoryInAndStatusOrderByPinnedAtDescLastReplyAtDesc(
|
||||||
|
List<Category> categories,
|
||||||
|
PostStatus status,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
List<Post> findDistinctByTagsInAndStatus(List<Tag> tags, PostStatus status);
|
List<Post> findDistinctByTagsInAndStatus(List<Tag> tags, PostStatus status);
|
||||||
List<Post> findDistinctByTagsInAndStatus(List<Tag> tags, PostStatus status, Pageable pageable);
|
List<Post> findDistinctByTagsInAndStatus(List<Tag> tags, PostStatus status, Pageable pageable);
|
||||||
List<Post> findDistinctByTagsInAndStatusOrderByCreatedAtDesc(List<Tag> tags, PostStatus status);
|
List<Post> findDistinctByTagsInAndStatusOrderByCreatedAtDesc(List<Tag> tags, PostStatus status);
|
||||||
@@ -132,6 +144,26 @@ public interface PostRepository extends JpaRepository<Post, Long> {
|
|||||||
Pageable pageable
|
Pageable pageable
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"SELECT p FROM Post p JOIN p.tags t WHERE t IN :tags AND p.status = :status GROUP BY p.id HAVING COUNT(DISTINCT t.id) = :tagCount ORDER BY p.pinnedAt DESC, p.views DESC"
|
||||||
|
)
|
||||||
|
List<Post> findByAllTagsOrderByPinnedAtDescViewsDesc(
|
||||||
|
@Param("tags") List<Tag> tags,
|
||||||
|
@Param("status") PostStatus status,
|
||||||
|
@Param("tagCount") long tagCount,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"SELECT p FROM Post p JOIN p.tags t WHERE t IN :tags AND p.status = :status GROUP BY p.id HAVING COUNT(DISTINCT t.id) = :tagCount ORDER BY p.pinnedAt DESC, p.lastReplyAt DESC"
|
||||||
|
)
|
||||||
|
List<Post> findByAllTagsOrderByPinnedAtDescLastReplyAtDesc(
|
||||||
|
@Param("tags") List<Tag> tags,
|
||||||
|
@Param("status") PostStatus status,
|
||||||
|
@Param("tagCount") long tagCount,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT p FROM Post p JOIN p.tags t WHERE p.category IN :categories AND t IN :tags AND p.status = :status GROUP BY p.id HAVING COUNT(DISTINCT t.id) = :tagCount"
|
"SELECT p FROM Post p JOIN p.tags t WHERE p.category IN :categories AND t IN :tags AND p.status = :status GROUP BY p.id HAVING COUNT(DISTINCT t.id) = :tagCount"
|
||||||
)
|
)
|
||||||
@@ -174,6 +206,28 @@ public interface PostRepository extends JpaRepository<Post, Long> {
|
|||||||
Pageable pageable
|
Pageable pageable
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"SELECT p FROM Post p JOIN p.tags t WHERE p.category IN :categories AND t IN :tags AND p.status = :status GROUP BY p.id HAVING COUNT(DISTINCT t.id) = :tagCount ORDER BY p.pinnedAt DESC, p.views DESC"
|
||||||
|
)
|
||||||
|
List<Post> findByCategoriesAndAllTagsOrderByPinnedAtDescViewsDesc(
|
||||||
|
@Param("categories") List<Category> categories,
|
||||||
|
@Param("tags") List<Tag> tags,
|
||||||
|
@Param("status") PostStatus status,
|
||||||
|
@Param("tagCount") long tagCount,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
|
@Query(
|
||||||
|
"SELECT p FROM Post p JOIN p.tags t WHERE p.category IN :categories AND t IN :tags AND p.status = :status GROUP BY p.id HAVING COUNT(DISTINCT t.id) = :tagCount ORDER BY p.pinnedAt DESC, p.lastReplyAt DESC"
|
||||||
|
)
|
||||||
|
List<Post> findByCategoriesAndAllTagsOrderByPinnedAtDescLastReplyAtDesc(
|
||||||
|
@Param("categories") List<Category> categories,
|
||||||
|
@Param("tags") List<Tag> tags,
|
||||||
|
@Param("status") PostStatus status,
|
||||||
|
@Param("tagCount") long tagCount,
|
||||||
|
Pageable pageable
|
||||||
|
);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT p FROM Post p JOIN p.tags t WHERE p.category IN :categories AND t IN :tags AND p.status = :status GROUP BY p.id HAVING COUNT(DISTINCT t.id) = :tagCount ORDER BY p.createdAt DESC"
|
"SELECT p FROM Post p JOIN p.tags t WHERE p.category IN :categories AND t IN :tags AND p.status = :status GROUP BY p.id HAVING COUNT(DISTINCT t.id) = :tagCount ORDER BY p.createdAt DESC"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ import com.openisle.service.NotificationService;
|
|||||||
import com.openisle.service.PointService;
|
import com.openisle.service.PointService;
|
||||||
import com.openisle.service.SubscriptionService;
|
import com.openisle.service.SubscriptionService;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -316,6 +320,37 @@ public class CommentService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<Long, List<User>> getParticipantsForPosts(List<Post> posts, int limit) {
|
||||||
|
if (posts == null || posts.isEmpty()) {
|
||||||
|
return Map.of();
|
||||||
|
}
|
||||||
|
Map<Long, LinkedHashSet<User>> map = new HashMap<>();
|
||||||
|
List<Long> postIds = new ArrayList<>(posts.size());
|
||||||
|
for (Post post : posts) {
|
||||||
|
postIds.add(post.getId());
|
||||||
|
LinkedHashSet<User> set = new LinkedHashSet<>();
|
||||||
|
set.add(post.getAuthor());
|
||||||
|
map.put(post.getId(), set);
|
||||||
|
}
|
||||||
|
for (Object[] row : commentRepository.findDistinctAuthorsByPostIds(postIds)) {
|
||||||
|
Long postId = (Long) row[0];
|
||||||
|
User author = (User) row[1];
|
||||||
|
LinkedHashSet<User> set = map.get(postId);
|
||||||
|
if (set != null) {
|
||||||
|
set.add(author);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<Long, List<User>> result = new HashMap<>(map.size());
|
||||||
|
for (Map.Entry<Long, LinkedHashSet<User>> entry : map.entrySet()) {
|
||||||
|
List<User> list = new ArrayList<>(entry.getValue());
|
||||||
|
if (list.size() > limit) {
|
||||||
|
list = list.subList(0, limit);
|
||||||
|
}
|
||||||
|
result.put(entry.getKey(), list);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public java.util.List<Comment> getCommentsByIds(java.util.List<Long> ids) {
|
public java.util.List<Comment> getCommentsByIds(java.util.List<Long> ids) {
|
||||||
log.debug("getCommentsByIds called for ids {}", ids);
|
log.debug("getCommentsByIds called for ids {}", ids);
|
||||||
java.util.List<Comment> comments = commentRepository.findAllById(ids);
|
java.util.List<Comment> comments = commentRepository.findAllById(ids);
|
||||||
|
|||||||
@@ -339,6 +339,7 @@ public class PostService {
|
|||||||
post.setCategory(category);
|
post.setCategory(category);
|
||||||
post.setTags(new HashSet<>(tags));
|
post.setTags(new HashSet<>(tags));
|
||||||
post.setStatus(publishMode == PublishMode.REVIEW ? PostStatus.PENDING : PostStatus.PUBLISHED);
|
post.setStatus(publishMode == PublishMode.REVIEW ? PostStatus.PENDING : PostStatus.PUBLISHED);
|
||||||
|
post.setLastReplyAt(LocalDateTime.now());
|
||||||
|
|
||||||
// 什么都没设置的情况下,默认为ALL
|
// 什么都没设置的情况下,默认为ALL
|
||||||
if (Objects.isNull(postVisibleScopeType)) {
|
if (Objects.isNull(postVisibleScopeType)) {
|
||||||
@@ -809,9 +810,10 @@ public class PostService {
|
|||||||
boolean hasTags = tagIds != null && !tagIds.isEmpty();
|
boolean hasTags = tagIds != null && !tagIds.isEmpty();
|
||||||
|
|
||||||
java.util.List<Post> posts;
|
java.util.List<Post> posts;
|
||||||
|
Pageable pageable = buildPageable(page, pageSize);
|
||||||
|
|
||||||
if (!hasCategories && !hasTags) {
|
if (!hasCategories && !hasTags) {
|
||||||
posts = postRepository.findByStatusOrderByViewsDesc(PostStatus.PUBLISHED);
|
posts = postRepository.findByStatusOrderByPinnedAtDescViewsDesc(PostStatus.PUBLISHED, pageable);
|
||||||
} else if (hasCategories) {
|
} else if (hasCategories) {
|
||||||
java.util.List<Category> categories = categoryRepository.findAllById(categoryIds);
|
java.util.List<Category> categories = categoryRepository.findAllById(categoryIds);
|
||||||
if (categories.isEmpty()) {
|
if (categories.isEmpty()) {
|
||||||
@@ -822,16 +824,18 @@ public class PostService {
|
|||||||
if (tags.isEmpty()) {
|
if (tags.isEmpty()) {
|
||||||
return java.util.List.of();
|
return java.util.List.of();
|
||||||
}
|
}
|
||||||
posts = postRepository.findByCategoriesAndAllTagsOrderByViewsDesc(
|
posts = postRepository.findByCategoriesAndAllTagsOrderByPinnedAtDescViewsDesc(
|
||||||
categories,
|
categories,
|
||||||
tags,
|
tags,
|
||||||
PostStatus.PUBLISHED,
|
PostStatus.PUBLISHED,
|
||||||
tags.size()
|
tags.size(),
|
||||||
|
pageable
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
posts = postRepository.findByCategoryInAndStatusOrderByViewsDesc(
|
posts = postRepository.findByCategoryInAndStatusOrderByPinnedAtDescViewsDesc(
|
||||||
categories,
|
categories,
|
||||||
PostStatus.PUBLISHED
|
PostStatus.PUBLISHED,
|
||||||
|
pageable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -839,10 +843,15 @@ public class PostService {
|
|||||||
if (tags.isEmpty()) {
|
if (tags.isEmpty()) {
|
||||||
return java.util.List.of();
|
return java.util.List.of();
|
||||||
}
|
}
|
||||||
posts = postRepository.findByAllTagsOrderByViewsDesc(tags, PostStatus.PUBLISHED, tags.size());
|
posts = postRepository.findByAllTagsOrderByPinnedAtDescViewsDesc(
|
||||||
|
tags,
|
||||||
|
PostStatus.PUBLISHED,
|
||||||
|
tags.size(),
|
||||||
|
pageable
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return paginate(sortByPinnedAndViews(posts), page, pageSize);
|
return posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Post> listPostsByLatestReply(Integer page, Integer pageSize) {
|
public List<Post> listPostsByLatestReply(Integer page, Integer pageSize) {
|
||||||
@@ -859,9 +868,13 @@ public class PostService {
|
|||||||
boolean hasTags = tagIds != null && !tagIds.isEmpty();
|
boolean hasTags = tagIds != null && !tagIds.isEmpty();
|
||||||
|
|
||||||
java.util.List<Post> posts;
|
java.util.List<Post> posts;
|
||||||
|
Pageable pageable = buildPageable(page, pageSize);
|
||||||
|
|
||||||
if (!hasCategories && !hasTags) {
|
if (!hasCategories && !hasTags) {
|
||||||
posts = postRepository.findByStatusOrderByCreatedAtDesc(PostStatus.PUBLISHED);
|
posts = postRepository.findByStatusOrderByPinnedAtDescLastReplyAtDesc(
|
||||||
|
PostStatus.PUBLISHED,
|
||||||
|
pageable
|
||||||
|
);
|
||||||
} else if (hasCategories) {
|
} else if (hasCategories) {
|
||||||
java.util.List<Category> categories = categoryRepository.findAllById(categoryIds);
|
java.util.List<Category> categories = categoryRepository.findAllById(categoryIds);
|
||||||
if (categories.isEmpty()) {
|
if (categories.isEmpty()) {
|
||||||
@@ -872,16 +885,18 @@ public class PostService {
|
|||||||
if (tags.isEmpty()) {
|
if (tags.isEmpty()) {
|
||||||
return java.util.List.of();
|
return java.util.List.of();
|
||||||
}
|
}
|
||||||
posts = postRepository.findByCategoriesAndAllTagsOrderByCreatedAtDesc(
|
posts = postRepository.findByCategoriesAndAllTagsOrderByPinnedAtDescLastReplyAtDesc(
|
||||||
categories,
|
categories,
|
||||||
tags,
|
tags,
|
||||||
PostStatus.PUBLISHED,
|
PostStatus.PUBLISHED,
|
||||||
tags.size()
|
tags.size(),
|
||||||
|
pageable
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
posts = postRepository.findByCategoryInAndStatusOrderByCreatedAtDesc(
|
posts = postRepository.findByCategoryInAndStatusOrderByPinnedAtDescLastReplyAtDesc(
|
||||||
categories,
|
categories,
|
||||||
PostStatus.PUBLISHED
|
PostStatus.PUBLISHED,
|
||||||
|
pageable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -889,14 +904,15 @@ public class PostService {
|
|||||||
if (tags.isEmpty()) {
|
if (tags.isEmpty()) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
posts = postRepository.findByAllTagsOrderByCreatedAtDesc(
|
posts = postRepository.findByAllTagsOrderByPinnedAtDescLastReplyAtDesc(
|
||||||
tags,
|
tags,
|
||||||
PostStatus.PUBLISHED,
|
PostStatus.PUBLISHED,
|
||||||
tags.size()
|
tags.size(),
|
||||||
|
pageable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return paginate(sortByPinnedAndLastReply(posts), page, pageSize);
|
return posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Post> listPostsByCategories(
|
public List<Post> listPostsByCategories(
|
||||||
@@ -1394,6 +1410,13 @@ public class PostService {
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Pageable buildPageable(Integer page, Integer pageSize) {
|
||||||
|
if (page == null || pageSize == null) {
|
||||||
|
return Pageable.unpaged();
|
||||||
|
}
|
||||||
|
return PageRequest.of(page, pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
private List<Post> paginate(List<Post> posts, Integer page, Integer pageSize) {
|
private List<Post> paginate(List<Post> posts, Integer page, Integer pageSize) {
|
||||||
if (page == null || pageSize == null) {
|
if (page == null || pageSize == null) {
|
||||||
return posts;
|
return posts;
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Backfill last_reply_at for posts without comments to preserve latest-reply ordering
|
||||||
|
UPDATE posts
|
||||||
|
SET last_reply_at = created_at
|
||||||
|
WHERE last_reply_at IS NULL;
|
||||||
Reference in New Issue
Block a user