feat(interaction): 点赞与评论按集统计

This commit is contained in:
Zhou Weidong committed 2026-10-21 15:56:26 +08:00
1 parent c7ff729f84
commit c6f729fb27
28 files changed
+683 -41

No files matched your search

@@ -52,6 +52,7 @@ import java.util.Set;
public class CommentService {
private static final String DRAMA_ID_COLUMN = "drama_id";
private static final String EPISODE_ID_COLUMN = "episode_id";
private static final String COMMENT_COUNT_COLUMN = "comment_count";
public static final String STATUS_PENDING = "pending";
@@ -222,6 +223,35 @@ public class CommentService {
return counts;
}
/** 批量统计多集未删除评论数,按 episode_id 分组。 */
public Map<Long, Long> countByEpisodes(Collection<Long> episodeIds) {
if (episodeIds == null || episodeIds.isEmpty()) {
return Map.of();
}
List<Long> ids = episodeIds.stream().filter(Objects::nonNull).distinct().toList();
if (ids.isEmpty()) {
return Map.of();
}
QueryWrapper<ContentComment> wrapper = Wrappers.query();
wrapper.select(EPISODE_ID_COLUMN, "COUNT(*) AS " + COMMENT_COUNT_COLUMN)
.in(EPISODE_ID_COLUMN, ids)
.eq("deleted", 0)
.ne("status", STATUS_DELETED)
.groupBy(EPISODE_ID_COLUMN);
List<Map<String, Object>> rows = commentMapper.selectMaps(wrapper);
if (rows == null || rows.isEmpty()) {
return Map.of();
}
Map<Long, Long> counts = new HashMap<>();
for (Map<String, Object> row : rows) {
Long episodeId = asLong(row.get(EPISODE_ID_COLUMN));
if (episodeId != null) {
counts.put(episodeId, asLong(row.get(COMMENT_COUNT_COLUMN), 0L));
}
}
return counts;
}
private Long asLong(Object value) {
return value instanceof Number number ? number.longValue() : null;
}
@@ -5,7 +5,9 @@ package com.fruitshorts.interaction.service;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fruitshorts.common.exception.ErrorCode;
import com.fruitshorts.common.exception.ServiceException;
import com.fruitshorts.content.dal.entity.DramaEpisode;
import com.fruitshorts.content.service.DramaService;
import com.fruitshorts.content.service.EpisodeService;
import com.fruitshorts.interaction.dal.entity.ContentComment;
import com.fruitshorts.interaction.dal.entity.ContentLike;
import com.fruitshorts.interaction.dal.mapper.ContentCommentMapper;
@@ -29,17 +31,19 @@ import java.util.Locale;
public class LikeService {
public static final String TYPE_DRAMA = "DRAMA";
public static final String TYPE_EPISODE = "EPISODE";
public static final String TYPE_COMMENT = "COMMENT";
private final ContentLikeMapper likeMapper;
private final ContentCommentMapper commentMapper;
private final DramaService dramaService;
private final EpisodeService episodeService;
@Transactional(rollbackFor = Exception.class)
public LikeToggleRespVO toggle(Long userId, LikeToggleReqVO req) {
String type = req.getTargetType().trim().toUpperCase(Locale.ROOT);
if (!TYPE_DRAMA.equals(type) && !TYPE_COMMENT.equals(type)) {
throw new ServiceException(ErrorCode.BAD_REQUEST, "只支持对短剧或评论点赞");
if (!TYPE_DRAMA.equals(type) && !TYPE_EPISODE.equals(type) && !TYPE_COMMENT.equals(type)) {
throw new ServiceException(ErrorCode.BAD_REQUEST, "只支持对短剧、剧集或评论点赞");
}
Long targetId = req.getTargetId();
validateTarget(type, targetId);
@@ -74,6 +78,10 @@ public class LikeService {
return dramaService.getExisting(targetId).getLikeCount() == null
? 0L : dramaService.getExisting(targetId).getLikeCount();
}
if (TYPE_EPISODE.equals(type)) {
return episodeService.getExisting(targetId).getLikeCount() == null
? 0L : episodeService.getExisting(targetId).getLikeCount();
}
ContentComment comment = commentMapper.selectById(targetId);
return comment == null || comment.getLikeCount() == null ? 0L : comment.getLikeCount();
}
@@ -83,6 +91,10 @@ public class LikeService {
dramaService.adjustLikeCount(targetId, delta);
return;
}
if (TYPE_EPISODE.equals(type)) {
episodeService.adjustLikeCount(targetId, delta);
return;
}
commentMapper.update(null, Wrappers.<ContentComment>lambdaUpdate()
.eq(ContentComment::getId, targetId)
.setSql(delta > 0
@@ -95,6 +107,11 @@ public class LikeService {
dramaService.getPublished(targetId);
return;
}
if (TYPE_EPISODE.equals(type)) {
DramaEpisode episode = episodeService.getPublished(targetId);
dramaService.getPublished(episode.getDramaId());
return;
}
ContentComment comment = commentMapper.selectById(targetId);
if (comment == null || CommentService.STATUS_PUBLISHED.equals(comment.getStatus()) == false) {
throw new ServiceException(ErrorCode.DATA_NOT_FOUND, "评论不存在或未通过审核");
@@ -10,7 +10,7 @@ import lombok.Data;
@Data
public class LikeToggleReqVO {
/** DRAMA/COMMENT */
/** DRAMA/EPISODE/COMMENT */
@NotBlank(message = "缺少 targetType")
private String targetType;