评论列表新增根据热度排序功能
This commit is contained in:
parent
f25d77675f
commit
9a96b016cc
@ -132,7 +132,7 @@ public class DynamicCommentQryExe {
|
||||
}
|
||||
|
||||
private PageResult<DynamicComment> pageData(DynamicCommentLimitCmd cmd) {
|
||||
return dynamicCommentService.pageRootCommentsByTimeDesc(cmd.getPageReq(), cmd.getDynamicId());
|
||||
return dynamicCommentService.pageRootCommentsByHotScore(cmd.getPageReq(), cmd.getDynamicId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -12,6 +12,7 @@ import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicContent;
|
||||
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicPicture;
|
||||
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicTag;
|
||||
import com.red.circle.other.infra.database.rds.service.approval.ApprovalDynamicContentService;
|
||||
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicCommentService;
|
||||
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicContentService;
|
||||
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicLikeService;
|
||||
@ -49,10 +50,13 @@ public class DynamicMyQryExe {
|
||||
private final DynamicCommentService dynamicCommentService;
|
||||
private final UserSubscriptionService userSubscriptionService;
|
||||
private final UserProfileAppConvertor userProfileAppConvertor;
|
||||
private final ApprovalDynamicContentService approvalDynamicContentService;
|
||||
|
||||
public PageResult<DynamicListCO> execute(DynamicMyLimitCmd cmd) {
|
||||
List<Long> pendingDynamicIds = approvalDynamicContentService.listPendingDynamicIds();
|
||||
|
||||
PageResult<DynamicContent> dynamics = dynamicContentService
|
||||
.pageByTimeDesc(cmd.getUserId(), cmd.getPageReq());
|
||||
.pageByTimeDesc(cmd.getUserId(), cmd.getPageReq(), pendingDynamicIds);
|
||||
|
||||
if (CollectionUtils.isEmpty(dynamics.getRecords())) {
|
||||
return PageResult.newPageResult(0);
|
||||
|
||||
@ -0,0 +1,125 @@
|
||||
package com.red.circle.other.app.scheduler;
|
||||
|
||||
import com.red.circle.component.redis.annotation.TaskCacheLock;
|
||||
import com.red.circle.component.redis.service.RedisService;
|
||||
import com.red.circle.framework.mybatis.constant.PageConstant;
|
||||
import com.red.circle.other.infra.database.cache.service.other.DynamicCacheService;
|
||||
import com.red.circle.other.infra.database.rds.entity.dynamic.DynamicComment;
|
||||
import com.red.circle.other.infra.database.rds.service.dynamic.DynamicCommentService;
|
||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 评论热度分数更新定时任务.
|
||||
* 每10分钟执行一次,更新最近7天的评论热度分数
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DynamicCommentHotScoreTask {
|
||||
|
||||
private final DynamicCommentService dynamicCommentService;
|
||||
private final DynamicCacheService dynamicCacheService;
|
||||
|
||||
/**
|
||||
* 每10分钟执行一次
|
||||
*/
|
||||
@Scheduled(cron = "0 */10 * * * ?")
|
||||
@TaskCacheLock(key = "COMMENT_HOT_SCORE_UPDATE", expireSecond = 540)
|
||||
public void updateHotScore() {
|
||||
try {
|
||||
log.info("评论热度分数更新任务 - 开始执行");
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
// 查询最近7天的根评论(分批处理)
|
||||
long sevenDaysAgo = System.currentTimeMillis() - (7 * 24 * 60 * 60 * 1000L);
|
||||
int totalUpdated = 0;
|
||||
Long lastId = null;
|
||||
boolean hasMore = true;
|
||||
|
||||
while (hasMore) {
|
||||
// 分批查询,每次1000条
|
||||
List<DynamicComment> comments = queryRecentComments(sevenDaysAgo, lastId, 1000);
|
||||
|
||||
if (CollectionUtils.isEmpty(comments)) {
|
||||
hasMore = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// 批量更新热度分数
|
||||
for (DynamicComment comment : comments) {
|
||||
updateCommentHotScore(comment);
|
||||
totalUpdated++;
|
||||
}
|
||||
|
||||
// 准备下一批
|
||||
lastId = comments.get(comments.size() - 1).getId();
|
||||
hasMore = comments.size() >= 1000;
|
||||
}
|
||||
|
||||
long costTime = System.currentTimeMillis() - startTime;
|
||||
log.info("评论热度分数更新任务 - 执行完成,更新{}条评论,耗时{}ms", totalUpdated, costTime);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("评论热度分数更新任务 - 执行失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最近的根评论
|
||||
*/
|
||||
private List<DynamicComment> queryRecentComments(long since, Long lastId, int limit) {
|
||||
return dynamicCommentService.query()
|
||||
.isNull(DynamicComment::getRootCommentId)
|
||||
.ge(DynamicComment::getCreateTime, new java.sql.Timestamp(since))
|
||||
.gt(lastId != null, DynamicComment::getId, lastId)
|
||||
.orderByAsc(DynamicComment::getId)
|
||||
.last(PageConstant.formatLimit(limit))
|
||||
.list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新单条评论的热度分数
|
||||
*/
|
||||
private void updateCommentHotScore(DynamicComment comment) {
|
||||
try {
|
||||
// 获取点赞数
|
||||
Long likeCount = Optional.ofNullable(
|
||||
dynamicCacheService.getCommentLikeQuantity(comment.getDynamicContentId(), comment.getId())
|
||||
).orElse(0L);
|
||||
|
||||
// 计算热度分数
|
||||
double hotScore = calculateHotScore(comment, likeCount);
|
||||
|
||||
// 更新到数据库
|
||||
dynamicCommentService.update()
|
||||
.set(DynamicComment::getHotScore, hotScore)
|
||||
.eq(DynamicComment::getId, comment.getId())
|
||||
.last(PageConstant.LIMIT_ONE)
|
||||
.execute();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("更新评论热度分数失败,commentId={}", comment.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算热度分数
|
||||
* 公式: 点赞数 / (时间差小时数 + 2)^1.5
|
||||
*/
|
||||
private double calculateHotScore(DynamicComment comment, Long likeCount) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long ageMillis = currentTime - comment.getCreateTime().getTime();
|
||||
double ageHours = Math.max(ageMillis / (1000.0 * 60 * 60), 0.1);
|
||||
|
||||
return likeCount / Math.pow(ageHours + 2, 1.5);
|
||||
}
|
||||
|
||||
}
|
||||
@ -54,4 +54,10 @@ public class DynamicComment extends TimestampBaseEntity {
|
||||
@TableField("root_comment_id")
|
||||
private Long rootCommentId;
|
||||
|
||||
/**
|
||||
* 热度分数
|
||||
*/
|
||||
@TableField("hot_score")
|
||||
private Double hotScore;
|
||||
|
||||
}
|
||||
|
||||
@ -92,6 +92,14 @@ public interface DynamicCommentService extends BaseService<DynamicComment> {
|
||||
*/
|
||||
void deleteById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询根评论(按热度排序)
|
||||
*
|
||||
* @param pageQuery 分页参数
|
||||
* @param contentId 动态内容ID
|
||||
*/
|
||||
PageResult<DynamicComment> pageRootCommentsByHotScore(PageQuery pageQuery, Long contentId);
|
||||
|
||||
/**
|
||||
* 根据动态ID获得动态评论数量
|
||||
*
|
||||
|
||||
@ -54,7 +54,7 @@ public interface DynamicContentService extends BaseService<DynamicContent> {
|
||||
* @param pageNumber 第几页
|
||||
* @param userId 创建人
|
||||
*/
|
||||
PageResult<DynamicContent> pageByTimeDesc(Long userId, PageQuery pageQuery);
|
||||
PageResult<DynamicContent> pageByTimeDesc(Long userId, PageQuery pageQuery, List<Long> pendingDynamicIds);
|
||||
|
||||
/**
|
||||
* 获得分页数据
|
||||
|
||||
@ -68,6 +68,16 @@ public class DynamicCommentServiceImpl extends
|
||||
.page(pageQuery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<DynamicComment> pageRootCommentsByHotScore(PageQuery pageQuery, Long contentId) {
|
||||
return query()
|
||||
.eq(DynamicComment::getDynamicContentId, contentId)
|
||||
.isNull(DynamicComment::getRootCommentId)
|
||||
.orderByDesc(DynamicComment::getHotScore)
|
||||
.orderByDesc(DynamicComment::getCreateTime)
|
||||
.page(pageQuery);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNumberByRootIdByNotUserId(Long rootCommentId, Long notUserId) {
|
||||
|
||||
|
||||
@ -82,11 +82,12 @@ public class DynamicContentServiceImpl extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<DynamicContent> pageByTimeDesc(Long userId, PageQuery pageQuery) {
|
||||
public PageResult<DynamicContent> pageByTimeDesc(Long userId, PageQuery pageQuery, List<Long> pendingDynamicIds) {
|
||||
|
||||
return query()
|
||||
.eq(DynamicContent::getDel, Boolean.FALSE)
|
||||
.eq(DynamicContent::getCreateUser, userId)
|
||||
.notIn(CollectionUtils.isNotEmpty(pendingDynamicIds), DynamicContent::getId, pendingDynamicIds)
|
||||
.orderByDesc(DynamicContent::getCreateTime)
|
||||
.page(pageQuery);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user