package nju.seec.helper.service.impl; import nju.seec.helper.aspect.auth.LoginUser; import nju.seec.helper.aspect.message.Message; import nju.seec.helper.dao.CommentDAO; import nju.seec.helper.dao.SlideDAO; import nju.seec.helper.dao.UserDAO; import nju.seec.helper.dto.comment.CommentDTO; import nju.seec.helper.entity.Comment; import nju.seec.helper.entity.Slide; import nju.seec.helper.enums.ExceptionType; import nju.seec.helper.enums.MessageType; import nju.seec.helper.exception.HelperException; import nju.seec.helper.service.CommentService; import nju.seec.helper.service.MessageService; import nju.seec.helper.vo.CommentVO; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.stream.Collectors; /** * @author cst */ @Service public class CommentServiceImpl implements CommentService { private final CommentDAO commentDAO; private final SlideDAO slideDAO; private final UserDAO userDAO; private final MessageService messageService; public CommentServiceImpl(CommentDAO commentDAO, SlideDAO slideDAO, UserDAO userDAO, MessageService messageService) { this.commentDAO = commentDAO; this.slideDAO = slideDAO; this.userDAO = userDAO; this.messageService = messageService; } @Message(MessageType.COMMENT_NEW) @Transactional(rollbackFor = Exception.class) @Override public CommentVO createComment(LoginUser user, CommentDTO commentDTO) { Slide slide = slideDAO.findSlideById(commentDTO.getSlideId()); Comment comment = commentDAO.save( new Comment() .setSlideId(slide.getId()) .setPageNumber(commentDTO.getPageNumber()) .setUser(userDAO.findUserById(user.getId())) .setTitle(commentDTO.getTitle()) .setContent(commentDTO.getContent()) .setShow(commentDTO.getShow()) ); return new CommentVO(comment); } @Transactional(rollbackFor = Exception.class) @Override public void deleteComment(LoginUser user, Long commentId) { Comment comment = commentDAO.findCommentById(commentId); if (!existsDelAuth(user, comment)) { throw HelperException.of(ExceptionType.FORBIDDEN, "您无权删除该评论"); } unTopComment(comment); commentDAO.delete(comment); } @Transactional(rollbackFor = Exception.class) @Override public void topComment(LoginUser user, Long commentId) { Comment comment = commentDAO.findCommentById(commentId); if (!comment.getShow()) { throw HelperException.of(ExceptionType.FORBIDDEN, "私密评论,无法置顶"); } if (!existsUpdateAuth(user, comment)) { throw HelperException.of(ExceptionType.FORBIDDEN, "您无权在该评论区置顶评论"); } unTopComment(comment); comment.setTopNumber((int) countTopComments(comment.getSlideId(), comment.getPageNumber()) + 1); commentDAO.save(comment); } private long countTopComments(Long slideId, Integer pageNumber) { return commentDAO.countBySlideIdAndPageNumberAndTopNumberNot(slideId, pageNumber, 0); } @Transactional(rollbackFor = Exception.class) @Override public void unTopComment(LoginUser user, Long commentId) { Comment comment = commentDAO.findCommentById(commentId); if (!existsUpdateAuth(user, comment)) { throw HelperException.of(ExceptionType.FORBIDDEN, "您无权在该评论区取消置顶评论"); } unTopComment(comment); commentDAO.save(comment); } @Transactional(readOnly = true) @Override public Page getCommentsBySlideAndPageNumber(Long slideId, Integer pageNumber, Pageable pageable) { return commentDAO.findBySlideIdAndPageNumberAndShow(slideId, pageNumber, true, pageable).map(CommentVO::new); } @Transactional(readOnly = true) @Override public CommentVO getOneComment(LoginUser user, Long commentId) { Comment comment = commentDAO.findCommentById(commentId); if (!existsGetAuth(user, comment)) { throw HelperException.of(ExceptionType.FORBIDDEN, "您无权获取该评论"); } return new CommentVO(comment); } @Transactional(readOnly = true) @Override public Page getSelfCommentsBySlideAndPageNumber(LoginUser user, Long slideId, Integer pageNumber, Boolean show, Pageable pageable) { return commentDAO.findBySlideIdAndPageNumberAndUserAndShow(slideId, pageNumber, userDAO.findUserById(user.getId()), show, pageable).map(CommentVO::new); } @Transactional(rollbackFor = Exception.class) @Override public void modifyCommentShow(LoginUser user, Long commentId, Boolean show) { Comment comment = commentDAO.findCommentById(commentId); if (comment.getShow().equals(show)) { return; } if (!existsUpdateAuth(user, comment)) { throw HelperException.of(ExceptionType.FORBIDDEN, "您无权修改该评论的展示状态"); } unTopComment(comment); commentDAO.save(comment.setShow(show)); } @Transactional(readOnly = true) @Override public Page getSelfComments(LoginUser user, String key, Pageable pageable) { return commentDAO.findByUserIdAndKey(user.getId(), key, pageable).map(CommentVO::new); } private void unTopComment(Comment comment) { Integer topNumber = comment.getTopNumber(); comment.setTopNumber(0); if (topNumber != 0) { commentDAO.saveAll( commentDAO.findBySlideIdAndPageNumberAndTopNumberGreaterThan(comment.getSlideId(), comment.getPageNumber(), topNumber) .parallelStream() .peek(topComment -> topComment.setTopNumber(topComment.getTopNumber() - 1)) .collect(Collectors.toList()) ); } } @Override public boolean existsAddAuth(LoginUser user, Comment comment) { return true; } @Override public boolean existsDelAuth(LoginUser user, Comment comment) { return comment.getUser().getId().equals(user.getId()); } @Override public boolean existsUpdateAuth(LoginUser user, Comment comment) { return comment.getUser().getId().equals(user.getId()) || slideDAO.findSlideById(comment.getSlideId()).getTeacher().getId().equals(user.getId()); } @Override public boolean existsGetAuth(LoginUser user, Comment comment) { return comment.getShow() || comment.getUser().getId().equals(user.getId()); } }