java实现多级评论

字段的设计:

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_dynamic_comment")
public class DynamicComment {
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;
    @TableField("dynamic_id")
    private Integer dynamicId;
    @TableField("user_id")
    private Integer userId;
    //回复的人的id
    @TableField("father_id")
    private Integer fatherId;
    /*//最上级的评论
    @TableField("origin_Id")
    private Integer originId;*/
    @NotBlank(message = "内容不能为空")
    private String context;
    //后台可以自己设置
    private String publicTime;
    //等级
    @NotNull(message = "等级不能为空")
    private Integer level;
}

前端传递过来的参数里面的level是指当前回复是在评论中的等级(如主评论是第1级,评论的回复或者二级评论就是第2级)

发布评论:

controller层

//发布评论
@RequestMapping("/commitCom")
public ResultVo commitCom(@RequestBody @Validated DynamicComment dynamicComment,BindingResult bindingResult) {
    return dynamicService.commitCom(dynamicComment);
}

service层

//发布评论
@Override
public ResultVo commitCom(DynamicComment dynamicComment) {
    //先进行参数的判断
    if (Objects.isNull(dynamicComment)) {
        return new ResultVo(1002, "参数不合法", null);
    }
    //获取时间
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = new Date();
    String format = simpleDateFormat.format(date);
    dynamicComment.setPublicTime(format);
    //设置用户的id
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    User user = (User) authentication.getPrincipal();
    dynamicComment.setUserId(user.getId());
    //添加评论
    int insert = dynamicCommentMapper.insert(dynamicComment);
    if (insert <= 0) {
        return new ResultVo(500, "内部服务器出错", null);
    } else {
        return new ResultVo(200, "操作成功", null);
    }
}

查看评论:

使用了树这种结构来实现

定义返回的数据类型

public class DynamicCommentVo {
    private Integer id;
    private Integer dynamicId;
    private Integer userId;
    //回复的人的id
    private Integer fatherId;
    /*//最上级的评论
    private Integer originId;*/
    private String context;
    //等级
    private Integer level;
    private String publicTime;
    //评论的人的信息
    private User commentUser;
    //被回复评论的人的昵称(到时候前端可以进行某某@某某)
    private String fatherName;
    //嵌套(子评论)
    private List<DynamicCommentVo> children;

}

controller层

//查看评论
@RequestMapping("/look")
public ResultVo lookComment(@RequestParam Integer dynamicId){
    return dynamicService.lookComment(dynamicId);
}

service:

//查看评论
@Override
public ResultVo lookComment(Integer dynamicId) {
    //根据动态的id先把所有相关的数据查询出来
    QueryWrapper<DynamicComment> qw=new QueryWrapper<>();
    qw.lambda().eq(DynamicComment::getDynamicId,dynamicId);
    List<DynamicComment> dynamicComments = dynamicCommentMapper.selectList(qw);
    if(dynamicComments.size()==0){
        return new ResultVo(200,"暂无评论",null);
    }
    //返回的数据类型
    List<DynamicCommentVo> dynamicCommentVos=new ArrayList<>();
    //补充评论的内容copy属性转换为vo
    for (DynamicComment dynamicComment : dynamicComments) {
        DynamicCommentVo dynamicCommentVo=new DynamicCommentVo();
        BeanUtils.copyProperties(dynamicComment,dynamicCommentVo);
        //作者的信息
        User user = userMapper.selectById(dynamicComment.getUserId());
        dynamicCommentVo.setCommentUser(user);
        //toUser信息 level>1 说明有回复对象
        if(dynamicComment.getLevel()>1){
            //查询回复的用户的信息
            //System.out.println("进来了"+dynamicComment.getLevel());
            User user1 = userMapper.selectById(dynamicComment.getFatherId());
            dynamicCommentVo.setFatherName(user1.getName());
            //System.out.println("昵称"+dynamicCommentVo.getFatherName());
        }
        dynamicCommentVos.add(dynamicCommentVo);
    }
    //很重要的一步!!!
    //构造树
    MyTreeNode myTreeNode = treeUtils.buildTree(dynamicCommentVos);
    System.out.println(myTreeNode.toString());
    //根节点的子节点(即level为1的评论 )
    List<MyTreeNode> children = myTreeNode.getChildren();

    List<DynamicCommentVo> level1DynamicCommentVo=new ArrayList<>();
    for (MyTreeNode child : children) {
        System.out.println(child.getContent());
        System.out.println(child.getChildren());
        level1DynamicCommentVo.add(child.getContent());
    }
    return new ResultVo(200,"操作成功",level1DynamicCommentVo);
}

定义树的结点类:

public class MyTreeNode {
    private Integer parentId;
    private Integer Id;
    //子节点
    private List<MyTreeNode> commentVoList;
    //内容
    private DynamicCommentVo content;
    //创建节点

    public static MyTreeNode buildNode(DynamicCommentVo commentVo) {
        MyTreeNode node=new MyTreeNode();
        node.setId(commentVo.getId());
        node.setParentId(commentVo.getFatherId());
        node.setContent(commentVo);
        return node;
    }
    public static MyTreeNode buildRoot() {
        MyTreeNode node=new MyTreeNode();
        node.setId(0);
        node.setParentId(-999);
        node.setContent(null);
        ArrayList<MyTreeNode> children=new ArrayList<>();
        node.setChildren(children);
        return node;
    }
    public Integer getParentId() {
        return parentId;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }

    public Integer getId() {
        return Id;
    }

    public void setId(Integer id) {
        Id = id;
    }

    public List<MyTreeNode> getChildren() {
        return commentVoList;
    }

    public void setChildren(List<MyTreeNode> commentVoList) {
        this.commentVoList = commentVoList;
    }

    public DynamicCommentVo getContent() {
        return content;
    }

    public void setContent(DynamicCommentVo content) {
        this.content = content;
    }

}

树的工具类:

//实现多级评论,将此篇文章的全部评论封装成为一棵树
@Component
public class TreeUtils {

    public  MyTreeNode buildTree(List<DynamicCommentVo> commentVoList){
        //创建根节点 id为0
        MyTreeNode root = MyTreeNode.buildRoot();
        //根节点的子节点列表
        List<MyTreeNode> rootChildren=new ArrayList<>();
        //将评论封装为树的节点
        List<MyTreeNode> nodes=new ArrayList<>();
        for (DynamicCommentVo commentVo : commentVoList) {
            MyTreeNode TreeNode = MyTreeNode.buildNode(commentVo);
            nodes.add(TreeNode);
        }
        for (MyTreeNode node : nodes) {
            MyTreeNode parentNode=findParentNode(node,nodes);
            if(parentNode!=null){
                //不为空,说明有父节点
                if(parentNode.getChildren()==null){
                    //说明这个节点是父节点的第一个子节点,创建一个子节点数组
                    List<MyTreeNode> children=new ArrayList<>();
                    children.add(node);
                    parentNode.setChildren(children);
                }else{
                    parentNode.getChildren().add(node);
                }
            }else{
                //为空,说明父节点为根节点
                //父节点添加子节点
                rootChildren.add(node);
                //子节点添加父节点id
                node.setParentId(root.getId());
            }
            root.setChildren(rootChildren);
        }
        return root;
    }
    //找到子节点的父节点
    public MyTreeNode findParentNode(MyTreeNode childNode,List<MyTreeNode> allNodes){
        for (MyTreeNode node : allNodes) {
            if(node.getId().equals(childNode.getParentId())){
                //将子评论的内容添加到父评论的children列表中。
                //如果父评论(CommentVo)的子评论列表为null,则新建一个列表。
                List<DynamicCommentVo> fatherCommentVoList = node.getContent().getChildren();
                if(fatherCommentVoList==null){
                    fatherCommentVoList=new ArrayList<>();
                    fatherCommentVoList.add(childNode.getContent());
                    node.getContent().setChildren(fatherCommentVoList);
                }else{
                    node.getContent().getChildren().add(childNode.getContent());
                }
                //System.out.println("孩子的结点数"+node.getContent().getChildren().size());
                //添加此节点的父亲节点
                childNode.setParentId(node.getId());
                return node;
            }
        }
        return null;

    }
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值