feat(posts): 优化帖子评论统计性能

- 在 Post 模型中添加 commentCount 和 lastReplyAt 字段
- 在 CommentService 中实现更新帖子评论统计的方法
- 在 PostMapper 中使用 Post 模型中的评论统计字段
- 新增数据库迁移脚本,添加评论统计字段和索引
- 更新相关测试用例
This commit is contained in:
sivdead
2025-09-12 11:08:59 +08:00
parent d2ce203236
commit 1a21ba8935
7 changed files with 178 additions and 2 deletions

View File

@@ -67,7 +67,7 @@ public class PostMapper {
dto.setCategory(categoryMapper.toDto(post.getCategory()));
dto.setTags(post.getTags().stream().map(tagMapper::toDto).collect(Collectors.toList()));
dto.setViews(post.getViews());
dto.setCommentCount(commentService.countComments(post.getId()));
dto.setCommentCount(post.getCommentCount());
dto.setStatus(post.getStatus());
dto.setPinnedAt(post.getPinnedAt());
dto.setRssExcluded(post.getRssExcluded() == null || post.getRssExcluded());
@@ -82,7 +82,7 @@ public class PostMapper {
List<User> participants = commentService.getParticipants(post.getId(), 5);
dto.setParticipants(participants.stream().map(userMapper::toAuthorDto).collect(Collectors.toList()));
LocalDateTime last = commentService.getLastCommentTime(post.getId());
LocalDateTime last = post.getLastReplyAt();
dto.setLastReplyAt(last != null ? last : post.getCreatedAt());
dto.setReward(0);
dto.setSubscribed(false);

View File

@@ -72,4 +72,10 @@ public class Post {
@Column(nullable = true)
private Boolean rssExcluded = true;
@Column(nullable = false)
private long commentCount = 0;
@Column(nullable = true)
private LocalDateTime lastReplyAt;
}

View File

@@ -69,6 +69,10 @@ public class CommentService {
comment.setContent(content);
comment = commentRepository.save(comment);
log.debug("Comment {} saved for post {}", comment.getId(), postId);
// Update post comment statistics
updatePostCommentStats(post);
imageUploader.addReferences(imageUploader.extractUrls(content));
if (!author.getId().equals(post.getAuthor().getId())) {
notificationService.createNotification(post.getAuthor(), NotificationType.COMMENT_REPLY, post, comment,
@@ -118,6 +122,10 @@ public class CommentService {
comment.setContent(content);
comment = commentRepository.save(comment);
log.debug("Reply {} saved for parent {}", comment.getId(), parentId);
// Update post comment statistics
updatePostCommentStats(parent.getPost());
imageUploader.addReferences(imageUploader.extractUrls(content));
if (!author.getId().equals(parent.getAuthor().getId())) {
notificationService.createNotification(parent.getAuthor(), NotificationType.COMMENT_REPLY, parent.getPost(),
@@ -263,9 +271,13 @@ public class CommentService {
imageUploader.removeReferences(imageUploader.extractUrls(comment.getContent()));
// 逻辑删除评论
Post post = comment.getPost();
commentRepository.delete(comment);
// 删除积分历史
pointHistoryRepository.deleteAll(pointHistories);
// Update post comment statistics
updatePostCommentStats(post);
// 重新计算受影响用户的积分
if (!usersToRecalculate.isEmpty()) {
@@ -311,4 +323,19 @@ public class CommentService {
int replies = commentRepository.findByParentOrderByCreatedAtAsc(comment).size();
return reactions + replies;
}
/**
* Update post comment statistics (comment count and last reply time)
*/
private void updatePostCommentStats(Post post) {
long commentCount = commentRepository.countByPostId(post.getId());
LocalDateTime lastReplyAt = commentRepository.findLastCommentTime(post);
post.setCommentCount(commentCount);
post.setLastReplyAt(lastReplyAt);
postRepository.save(post);
log.debug("Updated post {} stats: commentCount={}, lastReplyAt={}",
post.getId(), commentCount, lastReplyAt);
}
}