package com.mzl.flower.service.film.impl; import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageHelper; import com.mzl.flower.config.exception.ValidationException; import com.mzl.flower.config.security.SecurityUtils; import com.mzl.flower.constant.Constants; import com.mzl.flower.dto.request.film.CommentSearchDTO; import com.mzl.flower.dto.response.current.CurrentUserDTO; import com.mzl.flower.dto.response.customer.CustomerDTO; import com.mzl.flower.dto.response.film.CommentDTO; import com.mzl.flower.dto.security.UserDTO; import com.mzl.flower.entity.film.CommentPo; import com.mzl.flower.entity.film.CommentPoExample; import com.mzl.flower.entity.system.User; import com.mzl.flower.enums.SortRuleEnum; import com.mzl.flower.mapper.customer.CustomerMapper; import com.mzl.flower.mapper.film.CommentMS; import com.mzl.flower.mapper.film.CommentPoExMapper; import com.mzl.flower.mapper.film.CommentPoMapper; import com.mzl.flower.service.film.CommentLikesService; import com.mzl.flower.service.film.CommentService; import com.mzl.flower.service.system.UserService; import com.mzl.flower.utils.CommentTreeUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @Slf4j @Component @Service public class CommentServiceImpl implements CommentService { @Resource private CommentPoMapper commentPoMapper; @Resource private UserService userService; @Resource private CommentPoExMapper commentPoExMapper; @Resource private CustomerMapper customerMapper; @Resource private CommentService commentService; @Resource private CommentLikesService commentLikesService; /** * 获取文章的评论信息 * * @param commentSearchDTO * @return */ @Override public List getCommentByFilmId(CommentSearchDTO commentSearchDTO) { CurrentUserDTO currentUser = userService.getCurrentUser(); // 直接调用 mapper 方法获取评论列表 List commentPos = commentPoMapper.selectByArticleId(commentSearchDTO.getFilmId()); List commentDTOS = CommentMS.INSTANCE.toDTO(commentPos); if (CollectionUtils.isNotEmpty(commentDTOS)) { //构建评论信息 buildCommentInfo(commentDTOS, currentUser); } commentDTOS = CommentTreeUtils.toTree(commentDTOS); // 排序逻辑保持不变 if (SortRuleEnum.hottest.equals(commentSearchDTO.getSortRule())) { commentDTOS = commentDTOS.stream() .sorted(Comparator.comparing(CommentDTO::getLikeCount, Comparator.nullsLast(Comparator.reverseOrder())) .thenComparing(CommentDTO::getRepliesCount, Comparator.nullsLast(Comparator.reverseOrder()))) .collect(Collectors.toList()); } else if (SortRuleEnum.newest.equals(commentSearchDTO.getSortRule())) { commentDTOS = commentDTOS.stream() .sorted(Comparator.comparing(CommentDTO::getCreateTime, Comparator.nullsLast(Comparator.reverseOrder()))) .collect(Collectors.toList()); } return commentDTOS; } /** * 获取所有通过审核文章的评论信息 * * @param startTime * @param endTime * @return */ @Override public List getAllArticleComment(LocalDateTime startTime, LocalDateTime endTime) { return CommentMS.INSTANCE.toDTO(commentPoExMapper.getAllArticleComment(startTime, endTime)); } @Override public List getAllCommentReply(LocalDateTime startTime, LocalDateTime endTime) { return CommentMS.INSTANCE.toDTO(commentPoExMapper.getAllCommentReply(startTime, endTime)); } /** * 获取最新评论信息 * * @param commentSearchDTO * @return */ @Override public PageInfo getLatestComment(CommentSearchDTO commentSearchDTO) { PageHelper.startPage(commentSearchDTO.getCurrentPage(), commentSearchDTO.getPageSize()); List commentPos = commentPoExMapper.selectLatestComments(commentSearchDTO.getContent(), commentSearchDTO.getCreateBy()); PageInfo pageInfo = CommentMS.INSTANCE.toPage(new PageInfo<>(commentPos)); if (CollectionUtils.isNotEmpty(pageInfo.getList())) { // 构建评论信息 buildCommentInfo(pageInfo.getList(), null); } return pageInfo; } /** * 获取文章的评论数量 * * @param articleId * @return */ @Override public Long getCommentCountByArticle(Integer articleId) { CommentPoExample example = new CommentPoExample(); example.createCriteria().andIsDeletedEqualTo(false) .andStateEqualTo(true) .andArticleIdEqualTo(articleId); return commentPoMapper.countByExample(example); } /** * 获取评论数量 * * @return */ @Override public Long getTotal() { CommentPoExample example = new CommentPoExample(); example.createCriteria().andIsDeletedEqualTo(false) .andStateEqualTo(true); return commentPoMapper.countByExample(example); } /** * 创建评论 * * @param commentDTO * @return */ @Override public CommentDTO create(CommentDTO commentDTO) { if (StringUtils.isEmpty(commentDTO.getContent())) { throw new ValidationException("评论内容不能为空"); } //todo 评论内风险校验,评论内容可以是图片资源,考虑增加一个contextType字段用来区分资源类型 CommentPo commentPo = new CommentPo(); BeanUtils.copyProperties(commentDTO, commentPo); if(StringUtils.isEmpty(commentDTO.getParentId())|| commentDTO.getParentId()<=0){ commentPo.setParentId(0); } commentPo.setState(true); commentPo.create(SecurityUtils.getUserId()); if (commentPoMapper.insert(commentPo) <= 0) { CommentDTO commentDTO1 = new CommentDTO(); return commentDTO1; // throw new ValidationException("添加评论失败"); } BeanUtils.copyProperties(commentPo, commentDTO); commentDTO.setId(commentPo.getId().intValue()); return commentDTO; } /** * 删除评论 * * @param commentId * @return */ @Override public Boolean delete(Integer commentId) { List commentIds = new ArrayList<>(); List children = new ArrayList<>(); // 通过父级ID获取子级评论信息 this.getAllChildrenByPreId(children, commentId); if (CollectionUtils.isNotEmpty(children)) { commentIds.addAll(children.stream().map(CommentDTO::getId).collect(Collectors.toList())); } commentIds.add(commentId); CommentPoExample example = new CommentPoExample(); example.createCriteria().andIdIn(commentIds); CommentPo commentPo = new CommentPo(); commentPo.setDeleted(true); commentPo.setUpdateTime(LocalDateTime.now()); if (commentPoMapper.updateByExampleSelective(commentPo, example) <= 0) { throw new ValidationException("删除评论失败"); } return true; } /** * 通过父级ID获取子级评论信息 * * @param result 存放结果 * @param preId * @return */ @Override public void getAllChildrenByPreId(List result, Integer preId) { CommentPoExample example = new CommentPoExample(); example.createCriteria().andIsDeletedEqualTo(false) .andStateEqualTo(true) .andPreIdEqualTo(preId); List commentDTOS = CommentMS.INSTANCE.toDTO(commentPoMapper.selectByExample(example)); if (CollectionUtils.isNotEmpty(commentDTOS)) { result.addAll(commentDTOS); commentDTOS.forEach(commentDTO -> { this.getAllChildrenByPreId(result, commentDTO.getId()); }); } } @Override public String getArticleIdByCommentId(Integer commentId) { CommentPo commentPo = commentPoMapper.selectByPrimaryKey(commentId); return commentPo == null ? null : commentPo.getCreateBy(); } @Override public CommentDTO getById(Integer commentId) { return CommentMS.INSTANCE.toDTO(commentPoMapper.selectByPrimaryKey(commentId)); } /** * 构建评论信息 * * @param commentDTOS * @param currentUser */ private void buildCommentInfo(List commentDTOS, CurrentUserDTO currentUser) { if (CollectionUtils.isEmpty(commentDTOS)) { return; } List userIds = commentDTOS.stream() .map(CommentDTO::getCreateBy) .distinct() .collect(Collectors.toList()); Map> idUsers = userService.getByIds(userIds).stream() .collect(Collectors.groupingBy(User::getId)); Map> preIdMap = commentDTOS.stream() .collect(Collectors.groupingBy(CommentDTO::getParentId)); commentDTOS.forEach(commentDTO -> { // 设置用户名和头像 User userInfo = idUsers.getOrDefault(commentDTO.getCreateBy(), Collections.emptyList()).stream() .findFirst() .orElse(null); if (userInfo != null) { //获取用户信息 CustomerDTO currentCustomer = customerMapper.getCurrentCustomer(commentDTO.getCreateBy()); if(!ObjectUtils.isEmpty(currentCustomer)){ commentDTO.setCommentUserName(currentCustomer.getNickName()); commentDTO.setPicture(currentCustomer.getCover()); User user = userService.findByTel(currentCustomer.getTel(), Constants.USER_TYPE.customer.name()); if(!ObjectUtils.isEmpty(user)){ commentDTO.setLevel(user.getVipGrade()); } } } // 获取点赞数 commentDTO.setLikeCount(commentLikesService.getLikeCountCommentId(commentDTO.getId())); // 是否已点赞,这里面传入的是用户ID if (currentUser != null) { commentDTO.setIsLike(commentLikesService.isLike(commentDTO.getId(), currentUser.getId())); } // 回复数量 commentDTO.setRepliesCount(preIdMap.getOrDefault(commentDTO.getId(), Collections.emptyList()).size()); }); } }