content: package com.wenmrong.community1.community.service;
  
  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  import com.wenmrong.community1.community.dto.CommentDTO;
  import com.wenmrong.community1.community.enums.CommentTypeEnum;
  import com.wenmrong.community1.community.enums.NotificationStatusEnum;
  import com.wenmrong.community1.community.enums.NotificationTypeEnum;
  import com.wenmrong.community1.community.exception.CustomizeErrorCode;
  import com.wenmrong.community1.community.exception.CustomizeException;
  import com.wenmrong.community1.community.mapper.*;
  import com.wenmrong.community1.community.model.*;
  import org.springframework.beans.BeanUtils;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Service;
  import org.springframework.transaction.annotation.Transactional;
  
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  import java.util.stream.Collectors;
  
  @Service
  public class CommentService  extends ServiceImpl<CommentMapper, Comment> {
      @Autowired
      private CommentMapper commentMapper;
  
      @Autowired
      private QuestionMapper questionMapper;
  
      @Autowired
      private QuestionExtMapper questionExtMapper;
  
      @Autowired
      private UserMapper userMapper;
  
      @Autowired
      private CommentExtMapper commentExtMapper;
  
      @Autowired
      private NotificationMapper notificationMapper;
  
      @Transactional
      public void insert(Comment comment, User commentator) {
          if (comment.getParentId() == null || comment.getParentId() == 0) {
              throw new CustomizeException(CustomizeErrorCode.TARGET_PARAM_NOT_FOUND);
          }
  
          if (comment.getType() == null || !CommentTypeEnum.isExist(comment.getType())) {
              throw new CustomizeException(CustomizeErrorCode.TARGET_PARAM_NOT_FOUND);
  
          }
          if (comment.getType() == CommentTypeEnum.COMMENT.getType()) {
              //回复评论
              Comment dbComment = commentMapper.selectByPrimaryKey(comment.getParentId());
              if (dbComment == null) {
                  throw new CustomizeException(CustomizeErrorCode.COMMENT_NOT_FOUND);
              }
              //回复问题
              Question question = questionMapper.selectByPrimaryKey(dbComment.getParentId());
              if (question == null) {
                  throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
              }
              commentMapper.insert(comment);
              //增加评论数
              Comment parentComment = new Comment();
              parentComment.setId(comment.getParentId());
              parentComment.setCommentCount(1);
              //调用了commentExtMapper.xml文件里面调用了commentExtMapper接口,进而可以把参数传到commentExtMapper.xml
              commentExtMapper.incCommentCount(parentComment);
              //创建通知
              createNotification(comment, dbComment.getCommentator(), commentator.getName(), question.getTitle(), NotificationTypeEnum.REPLY_COMMENT, question.getId());
  
  
          } else {
              //回复问题
              Question question = questionMapper.selectByPrimaryKey(comment.getParentId());
              if (question == null) {
                  throw new CustomizeException(CustomizeErrorCode.QUESTION_NOT_FOUND);
              }
              //INTEGER类型模型默认初始化的时候为null,尽管数据库default=0
              comment.setCommentCount(0);
              commentMapper.insert(comment);
              question.setCommentCount(1);
              questionExtMapper.incCommentCount(question);
              createNotification(comment, question.getCreator(), commentator.getName(), question.getTitle(), NotificationTypeEnum.REPLY_QUESTION, question.getId());
          }
      }
  
      public void createNotification(Comment comment, Long receiver, String notifierName, String outerTitle, NotificationTypeEnum notificationType, Long outerId) {
          if (receiver == comment.getCommentator() && (notificationType.getType() == 1 || notificationType.getType() == 2)) {
              return;
          }
          Notification notification = new Notification();
          notification.setGmtCreate(System.currentTimeMillis());
          notification.setType(notificationType.getType());
          notification.setOuterid(outerId);
          notification.setNotifier(comment.getCommentator());
          notification.setStatus(NotificationStatusEnum.UNREAD.getStatus());
          notification.setReceiver(receiver);
          notification.setNotifierName(notifierName);
          notification.setOuterTitle(outerTitle);
          notificationMapper.insert(notification);
      }
  
      public List<CommentDTO> listByTargetId(Long id, CommentTypeEnum type) {
          CommentExample commentExample = new CommentExample();
          commentExample.createCriteria()
                  .andParentIdEqualTo(id)
                  .andTypeEqualTo(type.getType());
          commentExample.setOrderByClause("gmt_create desc");
          List<Comment> comments = commentMapper.selectByExample(commentExample);
  
          if (comments.size() == 0) {
              return new ArrayList<>();
          }
          // 获取去重的评论人
          Set<Long> commentators = comments.stream().map(comment -> comment.getCommentator()).collect(Collectors.toSet());
          List<Long> userIds = new ArrayList();
          userIds.addAll(commentators);
  
          //获取评论人并转化为map
          UserExample userExample = new UserExample();
          userExample.createCriteria()
                  .andIdIn(userIds);
          List<User> users = userMapper.selectByExample(userExample);
          Map<Long, User> userMap = users.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));
  
          //comments 转化为commentsDTOS(单一类型转复合类型的常用方法)
          List<CommentDTO> commentDTOS = comments.stream().map(comment -> {
              CommentDTO commentDTO = new CommentDTO();
              BeanUtils.copyProperties(comment, commentDTO);
              commentDTO.setUser(userMap.get(comment.getCommentator()));
              return commentDTO;
          }).collect(Collectors.toList());
  
          return commentDTOS;
  
  
      }
  }
  