diff --git a/han-note-comment/han-note-comment-biz/pom.xml b/han-note-comment/han-note-comment-biz/pom.xml
index a229522..96ffe1e 100644
--- a/han-note-comment/han-note-comment-biz/pom.xml
+++ b/han-note-comment/han-note-comment-biz/pom.xml
@@ -113,6 +113,12 @@
han-note-kv-api
+
+
+ com.github.phantomthief
+ buffer-trigger
+
+
diff --git a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/constants/MQConstants.java b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/constants/MQConstants.java
index cd39c26..85628d4 100644
--- a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/constants/MQConstants.java
+++ b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/constants/MQConstants.java
@@ -12,4 +12,9 @@ public interface MQConstants {
*/
String TOPIC_COUNT_NOTE_COMMENT = "CountNoteCommentTopic";
+ /**
+ * Topic: 评论热度值更新
+ */
+ String TOPIC_COMMENT_HEAT_UPDATE = "CommentHeatUpdateTopic";
+
}
\ No newline at end of file
diff --git a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/consumer/CommentHeatUpdateConsumer.java b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/consumer/CommentHeatUpdateConsumer.java
new file mode 100644
index 0000000..65a8ea4
--- /dev/null
+++ b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/consumer/CommentHeatUpdateConsumer.java
@@ -0,0 +1,90 @@
+package com.hanserwei.hannote.comment.biz.consumer;
+
+import com.github.phantomthief.collection.BufferTrigger;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.hanserwei.framework.common.utils.JsonUtils;
+import com.hanserwei.hannote.comment.biz.constants.MQConstants;
+import com.hanserwei.hannote.comment.biz.domain.dataobject.CommentDO;
+import com.hanserwei.hannote.comment.biz.domain.mapper.CommentDOMapper;
+import com.hanserwei.hannote.comment.biz.model.bo.CommentHeatBO;
+import com.hanserwei.hannote.comment.biz.utils.HeatCalculator;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.time.Duration;
+import java.util.List;
+import java.util.Set;
+
+@Component
+@RocketMQMessageListener(consumerGroup = "han_note_group_" + MQConstants.TOPIC_COMMENT_HEAT_UPDATE, // Group 组
+ topic = MQConstants.TOPIC_COMMENT_HEAT_UPDATE // 主题 Topic
+)
+@Slf4j
+public class CommentHeatUpdateConsumer implements RocketMQListener {
+
+ @Resource
+ private CommentDOMapper commentDOMapper;
+
+ private final BufferTrigger bufferTrigger = BufferTrigger.batchBlocking()
+ .bufferSize(50000) // 缓存队列的最大容量
+ .batchSize(300) // 一批次最多聚合 300 条
+ .linger(Duration.ofSeconds(2)) // 多久聚合一次(2s 一次)
+ .setConsumerEx(this::consumeMessage) // 设置消费者方法
+ .build();
+
+ @Override
+ public void onMessage(String body) {
+ // 往 bufferTrigger 中添加元素
+ bufferTrigger.enqueue(body);
+ }
+
+ private void consumeMessage(List bodys) {
+ log.info("==> 【评论热度值计算】聚合消息, size: {}", bodys.size());
+ log.info("==> 【评论热度值计算】聚合消息, {}", JsonUtils.toJsonString(bodys));
+
+ // 将聚合后的消息体 Json 转 Set, 去重相同的评论 ID, 防止重复计算
+ Set commentIds = Sets.newHashSet();
+ bodys.forEach(body -> {
+ try {
+ Set list = JsonUtils.parseSet(body, Long.class);
+ commentIds.addAll(list);
+ } catch (Exception e) {
+ log.error("", e);
+ }
+ });
+
+ log.info("==> 去重后的评论 ID: {}", commentIds);
+
+ // 批量查询评论
+ List commentDOS = commentDOMapper.selectByCommentIds(commentIds.stream().toList());
+
+ // 评论 ID
+ List ids = Lists.newArrayList();
+ // 热度值 BO
+ List commentBOS = Lists.newArrayList();
+
+ //重新计算每条评论的热度值
+ commentDOS.forEach(commentDO -> {
+ Long commentId = commentDO.getId();
+ // 被点赞数
+ Long likeTotal = commentDO.getLikeTotal();
+ // 被回复数
+ Long childCommentTotal = commentDO.getChildCommentTotal();
+
+ // 计算热度值
+ BigDecimal heatNum = HeatCalculator.calculateHeat(likeTotal, childCommentTotal);
+ ids.add(commentId);
+ commentBOS.add(CommentHeatBO.builder()
+ .id(commentId)
+ .heat(heatNum.doubleValue())
+ .build());
+ });
+ // 批量更新评论热度值
+ commentDOMapper.batchUpdateHeatByCommentIds(ids, commentBOS);
+ }
+}
\ No newline at end of file
diff --git a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/domain/dataobject/CommentDO.java b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/domain/dataobject/CommentDO.java
index 36650aa..ef05284 100644
--- a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/domain/dataobject/CommentDO.java
+++ b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/domain/dataobject/CommentDO.java
@@ -104,6 +104,12 @@ public class CommentDO {
@TableField(value = "create_time")
private LocalDateTime createTime;
+ /**
+ * 下级评论总数
+ */
+ @TableField(value = "child_comment_total")
+ private Long childCommentTotal;
+
/**
* 更新时间
*/
diff --git a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/domain/mapper/CommentDOMapper.java b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/domain/mapper/CommentDOMapper.java
index 3e2d1be..9c09da1 100644
--- a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/domain/mapper/CommentDOMapper.java
+++ b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/domain/mapper/CommentDOMapper.java
@@ -3,6 +3,7 @@ package com.hanserwei.hannote.comment.biz.domain.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hanserwei.hannote.comment.biz.domain.dataobject.CommentDO;
import com.hanserwei.hannote.comment.biz.model.bo.CommentBO;
+import com.hanserwei.hannote.comment.biz.model.bo.CommentHeatBO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -26,4 +27,14 @@ public interface CommentDOMapper extends BaseMapper {
* @return 插入数量
*/
int batchInsert(@Param("comments") List comments);
+
+ /**
+ * 批量更新热度值
+ *
+ * @param commentIds 评论 ID 列表
+ * @param commentHeatBOS 热度值列表
+ * @return 更新数量
+ */
+ int batchUpdateHeatByCommentIds(@Param("commentIds") List commentIds,
+ @Param("commentHeatBOS") List commentHeatBOS);
}
\ No newline at end of file
diff --git a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/model/bo/CommentHeatBO.java b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/model/bo/CommentHeatBO.java
new file mode 100644
index 0000000..6cf0458
--- /dev/null
+++ b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/model/bo/CommentHeatBO.java
@@ -0,0 +1,22 @@
+package com.hanserwei.hannote.comment.biz.model.bo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class CommentHeatBO {
+ /**
+ * 评论 ID
+ */
+ private Long id;
+
+ /**
+ * 热度值
+ */
+ private Double heat;
+}
\ No newline at end of file
diff --git a/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/utils/HeatCalculator.java b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/utils/HeatCalculator.java
new file mode 100644
index 0000000..e8c384c
--- /dev/null
+++ b/han-note-comment/han-note-comment-biz/src/main/java/com/hanserwei/hannote/comment/biz/utils/HeatCalculator.java
@@ -0,0 +1,40 @@
+package com.hanserwei.hannote.comment.biz.utils;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public class HeatCalculator {
+
+ // 热度计算的权重配置
+ private static final double LIKE_WEIGHT = 0.7; // 点赞权重 70%
+ private static final double REPLY_WEIGHT = 0.3; // 回复权重 30%
+
+ public static BigDecimal calculateHeat(long likeCount, long replyCount) {
+ // 点赞数权重 70%,被回复数权重 30%
+ BigDecimal likeWeight = new BigDecimal(LIKE_WEIGHT);
+ BigDecimal replyWeight = new BigDecimal(REPLY_WEIGHT);
+
+ // 转换点赞数和回复数为 BigDecimal
+ BigDecimal likeCountBD = new BigDecimal(likeCount);
+ BigDecimal replyCountBD = new BigDecimal(replyCount);
+
+ // 计算热度 (点赞数*点赞权重 + 回复数*回复权重)
+ BigDecimal heat = likeCountBD.multiply(likeWeight).add(replyCountBD.multiply(replyWeight));
+
+ // 四舍五入保留两位小数
+ return heat.setScale(2, RoundingMode.HALF_UP);
+ }
+
+ public static void main(String[] args) {
+ int likeCount = 150; // 点赞数
+ int replyCount = 10; // 被回复数
+
+ // 计算热度
+ BigDecimal heat = calculateHeat(likeCount, replyCount);
+
+ // 输出热度值
+ System.out.println("Calculated Heat: " + heat);
+ }
+
+
+}
\ No newline at end of file
diff --git a/han-note-comment/han-note-comment-biz/src/main/resources/mapperxml/CommentDOMapper.xml b/han-note-comment/han-note-comment-biz/src/main/resources/mapperxml/CommentDOMapper.xml
index 7751a6d..eb904bc 100644
--- a/han-note-comment/han-note-comment-biz/src/main/resources/mapperxml/CommentDOMapper.xml
+++ b/han-note-comment/han-note-comment-biz/src/main/resources/mapperxml/CommentDOMapper.xml
@@ -19,18 +19,35 @@
+
-
- id, note_id, user_id, content_uuid, is_content_empty, image_url, `level`, reply_total,
- like_total, parent_id, reply_comment_id, reply_user_id, is_top, create_time, update_time
+
+ id,
+ note_id,
+ user_id,
+ content_uuid,
+ is_content_empty,
+ image_url,
+ `level`,
+ reply_total,
+ like_total,
+ parent_id,
+ reply_comment_id,
+ reply_user_id,
+ is_top,
+ create_time,
+ update_time,
+ child_comment_total