|
|
@ -1,91 +1,150 @@
|
|
|
|
package com.luojia_channel.modules.post.service.impl;
|
|
|
|
package com.luojia_channel.modules.post.service.impl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
|
|
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
import com.luojia_channel.common.domain.page.PageResponse;
|
|
|
|
import com.luojia_channel.common.domain.page.PageResponse;
|
|
|
|
import com.luojia_channel.common.exception.PostException;
|
|
|
|
import com.luojia_channel.common.exception.PostException;
|
|
|
|
import com.luojia_channel.common.utils.PageUtil;
|
|
|
|
import com.luojia_channel.common.utils.PageUtil;
|
|
|
|
|
|
|
|
import com.luojia_channel.common.utils.UserContext;
|
|
|
|
import com.luojia_channel.modules.post.dto.req.CommentPageQueryDTO;
|
|
|
|
import com.luojia_channel.modules.post.dto.req.CommentPageQueryDTO;
|
|
|
|
|
|
|
|
import com.luojia_channel.modules.post.dto.req.CommentSaveDTO;
|
|
|
|
import com.luojia_channel.modules.post.dto.resp.CommentInfoDTO;
|
|
|
|
import com.luojia_channel.modules.post.dto.resp.CommentInfoDTO;
|
|
|
|
import com.luojia_channel.modules.post.dto.resp.PostBasicInfoDTO;
|
|
|
|
import com.luojia_channel.modules.post.dto.resp.PostBasicInfoDTO;
|
|
|
|
import com.luojia_channel.modules.post.entity.Comment;
|
|
|
|
import com.luojia_channel.modules.post.entity.Comment;
|
|
|
|
import com.luojia_channel.modules.post.entity.Post;
|
|
|
|
import com.luojia_channel.modules.post.entity.Post;
|
|
|
|
import com.luojia_channel.modules.post.mapper.CommentMapper;
|
|
|
|
import com.luojia_channel.modules.post.mapper.CommentMapper;
|
|
|
|
import com.luojia_channel.modules.post.service.CommentService;
|
|
|
|
import com.luojia_channel.modules.post.service.CommentService;
|
|
|
|
|
|
|
|
import com.luojia_channel.modules.post.utils.ValidatePostUtil;
|
|
|
|
|
|
|
|
import com.luojia_channel.modules.user.entity.User;
|
|
|
|
|
|
|
|
import com.luojia_channel.modules.user.mapper.UserMapper;
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
@Service
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
@RequiredArgsConstructor
|
|
|
|
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {
|
|
|
|
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {
|
|
|
|
|
|
|
|
|
|
|
|
private CommentMapper commentMapper;
|
|
|
|
private final ValidatePostUtil validatePostUtil;
|
|
|
|
|
|
|
|
private final CommentMapper commentMapper;
|
|
|
|
|
|
|
|
private final UserMapper userMapper;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void saveComment(Comment comment) {
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
comment.setCreateTime(LocalDateTime.now());
|
|
|
|
public void saveComment(CommentSaveDTO commentSaveDTO) {
|
|
|
|
comment.setUpdateTime(LocalDateTime.now());
|
|
|
|
validatePostUtil.validateComment(commentSaveDTO);
|
|
|
|
commentMapper.insert(comment);
|
|
|
|
Comment comment = BeanUtil.copyProperties(commentSaveDTO, Comment.class);
|
|
|
|
|
|
|
|
if(!save(comment)){
|
|
|
|
|
|
|
|
throw new PostException("创建评论失败");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Long parentCommentId = commentSaveDTO.getParentCommentId();
|
|
|
|
|
|
|
|
if(parentCommentId != null){
|
|
|
|
|
|
|
|
LambdaUpdateWrapper<Comment> updateWrapper = Wrappers.lambdaUpdate(Comment.class)
|
|
|
|
|
|
|
|
.eq(Comment::getId, parentCommentId)
|
|
|
|
|
|
|
|
.setSql("reply_count = reply_count + 1");
|
|
|
|
|
|
|
|
int update = commentMapper.update(null, updateWrapper);
|
|
|
|
|
|
|
|
if(update <= 0) {
|
|
|
|
|
|
|
|
throw new PostException("回复评论失败");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Long topId = commentSaveDTO.getTopId();
|
|
|
|
|
|
|
|
// 更新顶级评论回复数
|
|
|
|
|
|
|
|
if(!parentCommentId.equals(topId)){
|
|
|
|
|
|
|
|
updateWrapper = Wrappers.lambdaUpdate(Comment.class)
|
|
|
|
|
|
|
|
.eq(Comment::getId, topId)
|
|
|
|
|
|
|
|
.setSql("reply_count = reply_count + 1");
|
|
|
|
|
|
|
|
update = commentMapper.update(null, updateWrapper);
|
|
|
|
|
|
|
|
if(update <= 0) {
|
|
|
|
|
|
|
|
throw new PostException("回复顶级评论失败");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO 消息通知
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void updateComment(Comment comment, Long userId) {
|
|
|
|
public void updateComment(CommentSaveDTO commentSaveDTO) {
|
|
|
|
validatePostOwnership(comment.getId(), userId);
|
|
|
|
validatePostUtil.validateComment(commentSaveDTO);
|
|
|
|
|
|
|
|
validatePostUtil.validateCommentOwnership(commentSaveDTO.getId());
|
|
|
|
|
|
|
|
Comment comment = BeanUtil.copyProperties(commentSaveDTO, Comment.class);
|
|
|
|
comment.setUpdateTime(LocalDateTime.now());
|
|
|
|
comment.setUpdateTime(LocalDateTime.now());
|
|
|
|
if(!updateById(comment)){
|
|
|
|
if(!updateById(comment)){
|
|
|
|
throw new PostException("更新帖子失败");
|
|
|
|
throw new PostException("更新评论失败");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void deleteComment(Long id, Long userId) {
|
|
|
|
public void deleteComment(Long id) {
|
|
|
|
validatePostOwnership(id, userId);
|
|
|
|
validatePostUtil.validateCommentOwnership(id);
|
|
|
|
commentMapper.deleteById(id);
|
|
|
|
LambdaQueryWrapper<Comment> queryWrapper = Wrappers.lambdaQuery(Comment.class)
|
|
|
|
|
|
|
|
.eq(Comment::getTopId, id);
|
|
|
|
|
|
|
|
int delete = commentMapper.delete(queryWrapper);
|
|
|
|
|
|
|
|
if(delete <= 0) {
|
|
|
|
|
|
|
|
throw new PostException("删除评论失败");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO 如果根评论删除,那么其他评论怎么办,目前做法是删除其下所有的子评论
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 分页查询一系列根评论
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public PageResponse<CommentInfoDTO> getCommentsByPostId(CommentPageQueryDTO commentPageQueryDTO) {
|
|
|
|
public PageResponse<CommentInfoDTO> getCommentsByPostId(CommentPageQueryDTO commentPageQueryDTO) {
|
|
|
|
|
|
|
|
if(commentPageQueryDTO.getPostId() == null || commentPageQueryDTO.getPostId() < 0){
|
|
|
|
|
|
|
|
throw new PostException("帖子id不合法");
|
|
|
|
|
|
|
|
}
|
|
|
|
LambdaQueryWrapper<Comment> queryWrapper = Wrappers.lambdaQuery(Comment.class)
|
|
|
|
LambdaQueryWrapper<Comment> queryWrapper = Wrappers.lambdaQuery(Comment.class)
|
|
|
|
.eq(Comment::getPostId, commentPageQueryDTO.getPostId())
|
|
|
|
.eq(Comment::getPostId, commentPageQueryDTO.getPostId())
|
|
|
|
|
|
|
|
.eq(Comment::getParentCommentId, 0L)
|
|
|
|
.orderByDesc(Comment::getCreateTime);
|
|
|
|
.orderByDesc(Comment::getCreateTime);
|
|
|
|
IPage<Comment> commentPage = commentMapper.selectPage(PageUtil.convert(commentPageQueryDTO), queryWrapper);
|
|
|
|
return getCommentInfoDTOPageResponse(commentPageQueryDTO, queryWrapper);
|
|
|
|
return PageUtil.convert(commentPage, CommentInfoDTO.class);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public List<CommentInfoDTO> getNestedCommentsByPostId(Long postId) {
|
|
|
|
public PageResponse<CommentInfoDTO> getReplyById(CommentPageQueryDTO commentPageQueryDTO) {
|
|
|
|
LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
if(commentPageQueryDTO.getCommentId() == null || commentPageQueryDTO.getCommentId() < 0){
|
|
|
|
queryWrapper.eq(Comment::getPostId, postId)
|
|
|
|
throw new PostException("评论id不合法");
|
|
|
|
.orderByAsc(Comment::getCreateTime);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<Comment> comments = commentMapper.selectList(queryWrapper);
|
|
|
|
|
|
|
|
return buildNestedComments(comments);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void validatePostOwnership(Long commentId, Long userId) {
|
|
|
|
|
|
|
|
Comment comment = commentMapper.selectById(commentId);
|
|
|
|
|
|
|
|
if (comment == null) {
|
|
|
|
|
|
|
|
throw new PostException("评论不存在");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!userId.equals(comment.getUserId())) {
|
|
|
|
|
|
|
|
throw new PostException("你无权操作他人的评论");
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LambdaQueryWrapper<Comment> queryWrapper = Wrappers.lambdaQuery(Comment.class)
|
|
|
|
|
|
|
|
.eq(Comment::getTopId, commentPageQueryDTO.getCommentId())
|
|
|
|
|
|
|
|
.orderByDesc(Comment::getCreateTime);
|
|
|
|
|
|
|
|
return getCommentInfoDTOPageResponse(commentPageQueryDTO, queryWrapper);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<CommentInfoDTO> convertToDTO(List<Comment> comments) {
|
|
|
|
private PageResponse<CommentInfoDTO> getCommentInfoDTOPageResponse(CommentPageQueryDTO commentPageQueryDTO, LambdaQueryWrapper<Comment> queryWrapper) {
|
|
|
|
|
|
|
|
IPage<Comment> commentPage = commentMapper.selectPage(PageUtil.convert(commentPageQueryDTO), queryWrapper);
|
|
|
|
|
|
|
|
List<Long> userIds = new ArrayList<>();
|
|
|
|
|
|
|
|
commentPage.getRecords().forEach(comment -> {
|
|
|
|
|
|
|
|
userIds.add(comment.getUserId());
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
List<User> users = userMapper.selectBatchIds(userIds);
|
|
|
|
|
|
|
|
Map<Long, User> userMap = users.stream()
|
|
|
|
|
|
|
|
.collect(Collectors.toMap(User::getId, user -> user));
|
|
|
|
|
|
|
|
return PageUtil.convert(commentPage, (comment) -> {
|
|
|
|
|
|
|
|
CommentInfoDTO commentInfoDTO = BeanUtil.copyProperties(comment, CommentInfoDTO.class);
|
|
|
|
|
|
|
|
User user = userMap.getOrDefault(comment.getUserId(), new User());
|
|
|
|
|
|
|
|
commentInfoDTO.setUserAvatar(user.getAvatar());
|
|
|
|
|
|
|
|
commentInfoDTO.setUserName(user.getUsername());
|
|
|
|
|
|
|
|
return commentInfoDTO;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private List<CommentInfoDTO> convertToDTO(List<Comment> commentList) {
|
|
|
|
List<CommentInfoDTO> dtos = new ArrayList<>();
|
|
|
|
List<CommentInfoDTO> dtos = new ArrayList<>();
|
|
|
|
for (Comment comment : comments) {
|
|
|
|
for (Comment comment : commentList) {
|
|
|
|
CommentInfoDTO dto = new CommentInfoDTO();
|
|
|
|
CommentInfoDTO dto = new CommentInfoDTO();
|
|
|
|
BeanUtils.copyProperties(comment, dto);
|
|
|
|
BeanUtils.copyProperties(comment, dto);
|
|
|
|
dtos.add(dto);
|
|
|
|
dtos.add(dto);
|
|
|
@ -93,16 +152,14 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
|
|
|
|
return dtos;
|
|
|
|
return dtos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<CommentInfoDTO> buildNestedComments(List<Comment> comments) {
|
|
|
|
// 根据评论创建嵌套评论,目前没用到
|
|
|
|
|
|
|
|
private List<CommentInfoDTO> buildNestedCommentList(List<Comment> comments) {
|
|
|
|
Map<Long, CommentInfoDTO> map = new HashMap<>();
|
|
|
|
Map<Long, CommentInfoDTO> map = new HashMap<>();
|
|
|
|
List<CommentInfoDTO> rootComments = new ArrayList<>();
|
|
|
|
List<CommentInfoDTO> rootComments = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
|
|
for (Comment comment : comments) {
|
|
|
|
for (Comment comment : comments) {
|
|
|
|
CommentInfoDTO dto = new CommentInfoDTO();
|
|
|
|
CommentInfoDTO dto = new CommentInfoDTO();
|
|
|
|
BeanUtils.copyProperties(comment, dto);
|
|
|
|
BeanUtils.copyProperties(comment, dto);
|
|
|
|
|
|
|
|
|
|
|
|
map.put(comment.getId(), dto);
|
|
|
|
map.put(comment.getId(), dto);
|
|
|
|
|
|
|
|
|
|
|
|
if (comment.getParentCommentId() == null) {
|
|
|
|
if (comment.getParentCommentId() == null) {
|
|
|
|
rootComments.add(dto);
|
|
|
|
rootComments.add(dto);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -115,7 +172,6 @@ public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> impl
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return rootComments;
|
|
|
|
return rootComments;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|