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.qo.ThemeQo; import com.tanpu.community.api.beans.req.theme.ForwardThemeReq; import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp; 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 com.tanpu.community.util.ConvertUtil; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; import static com.tanpu.community.api.constants.RedisKeyConstant.*; @Service public class CommentService { @Resource private CommentMapper commentMapper; @Resource private UuidGenHelper uuidGenHelper; @Resource private RedisCache redisCache; @Resource private FeignService feignService; @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.selectCount((new LambdaQueryWrapper<CommentEntity>() .eq(CommentEntity::getThemeId, themeId)) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)); } public Integer getCommentCountByThemeIds(List<String> themeIds) { return commentMapper.selectCount((new LambdaQueryWrapper<CommentEntity>() .in(CommentEntity::getThemeId, themeIds)) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)); } public Integer getCommentCountByThemeIds(List<String> themeIds, Date startDate, Date endDate) { return commentMapper.selectCount((new LambdaQueryWrapper<CommentEntity>() .in(CommentEntity::getThemeId, themeIds)) .gt(CommentEntity::getCreateTime, startDate) .lt(CommentEntity::getCreateTime, endDate) .eq(CommentEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED)); } //统计主题集合的评论量 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)); } /** * 获取单个帖子的所有评论 * * @param themeId * @return */ 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(); } public void queryRecentComments(List<ThemeQo> themes) { if (CollectionUtils.isEmpty(themes)) return; List<String> themeIds = themes.stream().map(ThemeQo::getThemeId).collect(Collectors.toList()); List<CommentEntity> commentEntities = commentMapper.selectList(new LambdaQueryWrapper<CommentEntity>() .in(CommentEntity::getThemeId, themeIds) .orderByDesc(CommentEntity::getCreateTime)); LinkedHashMap<String, List<CommentEntity>> collect = commentEntities.stream().collect(Collectors.groupingBy(CommentEntity::getThemeId, LinkedHashMap::new, Collectors.toList())); // 查询用户信息 List<String> authorIds = new ArrayList<>(commentEntities.stream().map(CommentEntity::getAuthorId).collect(Collectors.toSet())); List<UserInfoResp> queryUsersListNew = feignService.getUserList(authorIds); Map<String, String> nameMap = queryUsersListNew.stream().collect(Collectors.toMap(UserInfoResp::getUserId, UserInfoResp::getNickName)); for (ThemeQo theme : themes) { if (collect.containsKey(theme.getThemeId())) { List<CommentEntity> comments = collect.get(theme.getThemeId()); theme.setRecentComments(ConvertUtil.comment2Simple(comments, nameMap)); } } } }