diff --git a/backend/src/main/java/com/openisle/config/PostDataSyncer.java b/backend/src/main/java/com/openisle/config/PostDataSyncer.java new file mode 100644 index 000000000..b526a5e6f --- /dev/null +++ b/backend/src/main/java/com/openisle/config/PostDataSyncer.java @@ -0,0 +1,43 @@ +package com.openisle.config; + +import com.openisle.service.CommentService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * + */ +@Slf4j +@RequiredArgsConstructor +@Component +public class PostDataSyncer implements CommandLineRunner { + + private final JdbcTemplate jdbcTemplate; + private final CommentService commentService; + @Override + public void run(String... args) { + + // 我们需要处理下历史数据,一些帖子的评论数量和最后回复时间可能为空 + // 系统下次升级后,可以删掉这些代码 + List oldPosts = jdbcTemplate.query(""" + select distinct p.id from posts p join comments c on p.id = c.post_id + where last_reply_at is null + """, + (rs, rowNum) -> rs.getLong(1)); + + log.info("found {} old posts: {}", oldPosts.size(), oldPosts); + oldPosts.forEach(postId -> { + long cnt = commentService.countComments(postId); + LocalDateTime lastCommentTime = commentService.getLastCommentTime(postId); + jdbcTemplate.update("update posts set comment_count = ?, last_reply_at = ? where id = ?", cnt, lastCommentTime, postId); + log.info("update post {} success", postId); + }); + } +} diff --git a/backend/src/main/java/com/openisle/mapper/PostMapper.java b/backend/src/main/java/com/openisle/mapper/PostMapper.java index 58652f17b..3272ecdc3 100644 --- a/backend/src/main/java/com/openisle/mapper/PostMapper.java +++ b/backend/src/main/java/com/openisle/mapper/PostMapper.java @@ -60,7 +60,8 @@ 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(commentService.countComments(post.getId())); + dto.setCommentCount(post.getCommentCount()); dto.setStatus(post.getStatus()); dto.setPinnedAt(post.getPinnedAt()); diff --git a/backend/src/main/java/com/openisle/model/Post.java b/backend/src/main/java/com/openisle/model/Post.java index 0f5a709f1..fe52bc6d5 100644 --- a/backend/src/main/java/com/openisle/model/Post.java +++ b/backend/src/main/java/com/openisle/model/Post.java @@ -67,4 +67,10 @@ public class Post { @Column private LocalDateTime pinnedAt; + @Column(nullable = false) + private long commentCount = 0; + + @Column + private LocalDateTime lastReplyAt; + } diff --git a/backend/src/main/java/com/openisle/service/CommentService.java b/backend/src/main/java/com/openisle/service/CommentService.java index 3ac994e30..fb9be9b7f 100644 --- a/backend/src/main/java/com/openisle/service/CommentService.java +++ b/backend/src/main/java/com/openisle/service/CommentService.java @@ -58,6 +58,11 @@ public class CommentService { comment.setContent(content); comment = commentRepository.save(comment); log.debug("Comment {} saved for post {}", comment.getId(), postId); + + post.setCommentCount(post.getCommentCount() + 1); + post.setLastReplyAt(LocalDateTime.now()); + postRepository.save(post); + imageUploader.addReferences(imageUploader.extractUrls(content)); if (!author.getId().equals(post.getAuthor().getId())) { notificationService.createNotification(post.getAuthor(), NotificationType.COMMENT_REPLY, post, comment, null, null, null, null); @@ -101,6 +106,13 @@ public class CommentService { comment.setContent(content); comment = commentRepository.save(comment); log.debug("Reply {} saved for parent {}", comment.getId(), parentId); + + Post post = postRepository.findById(parent.getPost().getId()) + .orElseThrow(() -> new com.openisle.exception.NotFoundException("Post not found")); + post.setCommentCount(post.getCommentCount() + 1); + post.setLastReplyAt(LocalDateTime.now()); + postRepository.save(post); + imageUploader.addReferences(imageUploader.extractUrls(content)); if (!author.getId().equals(parent.getAuthor().getId())) { notificationService.createNotification(parent.getAuthor(), NotificationType.COMMENT_REPLY, parent.getPost(), comment, null, null, null, null); diff --git a/backend/src/main/java/com/openisle/service/PostService.java b/backend/src/main/java/com/openisle/service/PostService.java index 30a785ce5..baf92458a 100644 --- a/backend/src/main/java/com/openisle/service/PostService.java +++ b/backend/src/main/java/com/openisle/service/PostService.java @@ -612,7 +612,7 @@ public class PostService { .sorted(java.util.Comparator .comparing(Post::getPinnedAt, java.util.Comparator.nullsLast(java.util.Comparator.reverseOrder())) .thenComparing(p -> { - java.time.LocalDateTime t = commentRepository.findLastCommentTime(p); + java.time.LocalDateTime t = p.getLastReplyAt(); return t != null ? t : p.getCreatedAt(); }, java.util.Comparator.nullsLast(java.util.Comparator.reverseOrder()))) .toList();