package com.tanpu.community.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fasterxml.jackson.core.type.TypeReference; import com.tanpu.biz.common.enums.community.CommentTypeEnum; import com.tanpu.biz.common.enums.community.ReportStatusEnum; import com.tanpu.common.exception.BizException; import com.tanpu.common.uuid.UuidGenHelper; import com.tanpu.community.api.beans.req.theme.ForwardThemeReq; import com.tanpu.community.api.enums.DeleteTagEnum; import com.tanpu.community.cache.RedisCache; import com.tanpu.community.dao.entity.community.CommentEntity; import com.tanpu.community.dao.entity.community.TimesCountEntity; import com.tanpu.community.dao.mapper.community.CommentMapper; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import static com.tanpu.community.api.constants.RedisKeyConstant.*; @Service public class CommentService { @Resource private CommentMapper commentMapper; @Autowired private UuidGenHelper uuidGenHelper; @Autowired private RedisCache redisCache; @Transactional public void insertComment(CommentEntity commentEntity) { commentEntity.setCommentId(uuidGenHelper.getUuidStr()); commentMapper.insert(commentEntity); //失效缓存 evictThemeCache(commentEntity.getThemeId()); } public CommentEntity queryByIdIncludeDelete(String commmentId) { return commentMapper.selectOne(new LambdaQueryWrapper<CommentEntity>() .eq(CommentEntity::getCommentId, commmentId)); } //统计主题集合的评论量 public Integer getTotalCountByThemeIds(List<String> themeIds) { if (CollectionUtils.isEmpty(themeIds)) { return 0; } return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>() .in(CommentEntity::getThemeId, themeIds)) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)) .size(); } //统计主题集合的评论量 public Integer getCommentCountByThemeId(String themeId) { return commentMapper.selectList((new LambdaQueryWrapper<CommentEntity>() .eq(CommentEntity::getThemeId, themeId)) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)) .size(); } //统计主题集合的评论量 public Map<String, Integer> getCountMapByThemeIds(List<String> themeIds) { if (CollectionUtils.isEmpty(themeIds)){ return new HashMap<>(); } LambdaQueryWrapper<CommentEntity> wrapper = (new LambdaQueryWrapper<CommentEntity>() .in(CommentEntity::getThemeId, themeIds)) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED) .groupBy(CommentEntity::getThemeId); return commentMapper.selectCountByThemeIds(wrapper).stream() .collect(Collectors.toMap(TimesCountEntity::getId, TimesCountEntity::getTimes)); } public List<CommentEntity> selectByThemeId(String themeId) { return redisCache.getList(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, themeId), 60, () -> { LambdaQueryWrapper<CommentEntity> queryWrapper = new LambdaQueryWrapper<CommentEntity>() .eq(CommentEntity::getThemeId, themeId) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode()) .orderByDesc(CommentEntity::getCreateTime); return commentMapper.selectList(queryWrapper); }, new TypeReference<List<CommentEntity>>() { }); } public List<CommentEntity> queryCommentsByUserId(String userId, String lastId, Integer pageSize) { LambdaQueryWrapper<CommentEntity> queryWrapper = new LambdaQueryWrapper<CommentEntity>() .eq(CommentEntity::getAuthorId, userId) .eq(CommentEntity::getCommentType, CommentTypeEnum.THEME.getCode()) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode()) .orderByDesc(CommentEntity::getCreateTime); if (StringUtils.isNotEmpty(lastId)) { CommentEntity commentEntity = commentMapper.selectOne(new LambdaQueryWrapper<CommentEntity>() .eq(CommentEntity::getCommentId, lastId)); if (commentEntity == null) throw new BizException("评论未找到,id:" + lastId); queryWrapper.lt(CommentEntity::getCreateTime, commentEntity.getCreateTime()); } if (pageSize != null) { queryWrapper.last("limit " + pageSize); } return commentMapper.selectList(queryWrapper); } //修改举报状态,可修改已删除 public void updateReportStatus(String commentId) { CommentEntity commentEntity = queryByIdIncludeDelete(commentId); if (commentEntity == null) { throw new BizException("评论未找到,id:" + commentId); } commentEntity.setReportStatus(ReportStatusEnum.REPORTED.getCode()); commentMapper.updateById(commentEntity); //失效缓存 evictThemeCache(commentEntity.getThemeId()); } //删除评论 @Transactional public void delete(String commentId, String userId) { CommentEntity commentEntity = this.queryByIdIncludeDelete(commentId); if (commentEntity==null || !commentEntity.getAuthorId().equals(userId)){ throw new BizException("删除评论与用户不匹配,commentId:"+commentId+",userId:"+userId); } commentEntity.setDeleteTag(DeleteTagEnum.DELETED.getCode()); commentMapper.updateById(commentEntity); //失效缓存 evictThemeCache(commentEntity.getThemeId()); } // 失效关联主题缓存 private void evictThemeCache(String themeId){ // 评论内容 redisCache.evict(StringUtils.joinWith("_", CACHE_COMMENT_THEMEID, themeId)); // 主题内容 redisCache.evict(StringUtils.joinWith("_", CACHE_THEME_ID, themeId)); // 评论数 redisCache.evict(StringUtils.joinWith("_", THEME_COMMENT_COUNT, themeId)); } public List<CommentEntity> queryAll() { return commentMapper.selectList(new LambdaQueryWrapper<CommentEntity>() .eq(CommentEntity::getDeleteTag,DeleteTagEnum.NOT_DELETED.getCode()) .orderByAsc(CommentEntity::getCreateTime)); } public CommentEntity queryByCommentId(String commentId) { return commentMapper.selectOne(new LambdaQueryWrapper<CommentEntity>().eq(CommentEntity::getCommentId,commentId)); } public String forwardSyncComment(ForwardThemeReq req, String userId) { CommentEntity commentEntity = CommentEntity.builder() .themeId(req.getFormerThemeId()) .authorId(userId) .content(req.getContent().get(0).getValue()) .commentType(CommentTypeEnum.THEME.getCode()) .build(); this.insertComment(commentEntity); return commentEntity.getCommentId(); } }