评论列表
  1. 根据文档可以知道请求地址、请求方式、请求参数

CommentsController

@GetMapping("article/{id}")
    public Result comments(@PathVariable("id") Long articleId){

        return commentsService.commentsByArticleId(articleId);

    }
  1. 根据返回数据形式可以,涉及到了文章id,作者名字,内容,子评论,创建时间,登记,给哪位用户,对应的表:文章表、用户表、内容表、评论表。
  • 封装一个CommentVo,又因为有子评论,所以使用一个集合来保存

CommentVo

@Data
public class CommentVo {
    //防止前端 精度损失 把id转为string
    @JsonSerialize(using = ToStringSerializer.class)
    private String id;

    private UserVo author;

    private String content;

    private List<CommentVo> childrens;

    private String createDate;

    private Integer level;

    private UserVo toUser;
}
  • 注意点:因为文章的id是用的分布式id,在传给前端的时候回有精度损失问题,所以将类型转换为string

CommentsController

@RestController
@RequestMapping("comments")
public class CommentsController {

    @Autowired
    private CommentsService commentsService;

    @GetMapping("article/{id}")
    public Result comments(@PathVariable("id") Long articleId){

        return commentsService.commentsByArticleId(articleId);

    }
}

CommentsService

public interface CommentsService {


    Result commentsByArticleId(Long articleId);
}

CommentsServiceImpl

  • 分析:根据文章id如何去查找对应的评论
    1. 在comment表中根据文章id去查询作者id,以及level级别
    2. 如果当前level为1的话,那么说明还有子评论
    3. 如果有子评论,那么根据parent_id进行查询
@Override
public Result commentsByArticleId(Long articleId) {
    LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Comment::getArticleId,articleId);
    wrapper.eq(Comment::getLevel,1);
    List<Comment> comments = commentMapper.selectList(wrapper);
    List<CommentVo> commentVoList = copyList(comments);
    return Result.success(commentVoList);
}
private List<CommentVo> copyList(List<Comment> comments) {
    ArrayList<CommentVo> commentVoArrayList = new ArrayList<>();
    for(Comment comment : comments){
        commentVoArrayList.add(copy(comment));
    }
    return commentVoArrayList;
}
private CommentVo copy(Comment comment) {
        CommentVo commentVo = new CommentVo();
        BeanUtils.copyProperties(comment,commentVo);
        //作者信息
        Long authorId = comment.getAuthorId();
        UserVo userVo = sysUserService.findUserVoById(authorId);
        commentVo.setAuthor(userVo);
        //子评论
        Integer level = comment.getLevel();
        if(level == 1){
            Long id = comment.getId();
            List<CommentVo> commentVoList = findCommentsByParentId(id);
            commentVo.setChildrens(commentVoList);
        }
        //to User 给谁评论
        if (level > 1){//没有评论
            Long toUid = comment.getToUid();
            UserVo toUserVo = this.sysUserService.findUserVoById(toUid);
            commentVo.setToUser(toUserVo);
        }
        return commentVo;
    }
private List<CommentVo> findCommentsByParentId(Long id) {
    LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(Comment::getParentId,id);
    queryWrapper.eq(Comment::getLevel,2);
    return copyList(commentMapper.selectList(queryWrapper));
}
评论
  1. 根据文档可知请求地址、请求方式、请求参数
  2. 封装请求参数
@Data
public class CommentParam {

    private Long articleId;

    private String content;

    private Long parent;

    private Long toUserId;
}
  1. 同时,只能登陆才能进行评论,所以要将之后的接口添加到之前写的WebConfig中的addInterceptors方法中,进行拦截对应的接口
@Override
public void addInterceptors(InterceptorRegistry registry) {
    //拦截test接口,后续实际遇到需要拦截的接口时,在配置为真正的拦截接口
    registry.addInterceptor(loginInterceptor)
            .addPathPatterns("/test").addPathPatterns("/comments/create/change");
}

CommentsController

@PostMapping("create/change")
public Result comment(@RequestBody CommentParam commentParam){
    return commentsService.comment(commentParam);
}

CommentsService

Result comment(CommentParam commentParam);

CommentsServiceImpl

  • 思考:如何将之前登陆过的用户信息进行读取?
    1. 之前有说到ThreadLocal,在登陆拦截器中,每次放行之后都会将用户信息直接放入UserThreadLocal中,那么可以直接取。
@Override
    public Result comment(CommentParam commentParam) {
        //登陆的时候,就把用户信息存在了ThreadLocal中
        SysUser sysUser = UserThreadLocal.get();
        Comment comment = new Comment();
        comment.setArticleId(commentParam.getArticleId());
        comment.setAuthorId(sysUser.getId());
        comment.setContent(commentParam.getContent());
        comment.setCreateDate(System.currentTimeMillis());
        Long parent = commentParam.getParent();
        if (parent == null || parent == 0) {
            comment.setLevel(1);
        }else{
            comment.setLevel(2);
        }
        comment.setParentId(parent == null ? 0 : parent);
        Long toUserId = commentParam.getToUserId();
        comment.setToUid(toUserId == null ? 0 : toUserId);
        commentMapper.insert(comment);
        return Result.success(null);
    }