评论回复功能,总结开发-Java
上一篇文章是将所有的评论和回复集成到一张表中,只能支持一级评论和回复,不能对别人的回复进行回复
所以这次将评论和回复划分出来,分为两张表,分别是评论表和回复表
Comment表和 Reply表
表格设计
Comment表
-- auto-generated definition
create table comment
(
id bigint not null
constraint comment_pk
primary key,
uid varchar(255),
uname varchar(50),
content text,
create_time timestamp
);
comment on table comment is '评论表';
comment on column comment.id is '主键id';
comment on column comment.uid is '用户id';
comment on column comment.uname is '用户名';
comment on column comment.content is '评论内容';
comment on column comment.create_time is '评论时间';
alter table comment
owner to postgres;
Reply表
-- auto-generated definition
create table reply
(
id bigint not null
constraint reply_pk
primary key,
tr_id bigint,
tr_status integer default 0,
uid varchar(255),
uname varchar(50),
rcontent text,
create_time timestamp
);
comment on table reply is '回复表';
comment on column reply.id is '主键id';
comment on column reply.tr_id is '回复的id';
comment on column reply.tr_status is '是回复还是评论,0表示回复评论,1表示回复回复';
comment on column reply.uid is '用户id';
comment on column reply.uname is '用户名';
comment on column reply.rcontent is '回复内容';
comment on column reply.create_time is '创建时间';
alter table reply
owner to postgres;
实体类和链表类
实体类
comment类
@Data
@TableName(value = "comment")
public class Comment implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 用户id
*/
@TableField(value = "uid")
private String uid;
/**
* 用户名
*/
@TableField(value = "uname")
private String uname;
/**
* 评论内容
*/
@TableField(value = "content")
private String content;
/**
* 评论时间
*/
@TableField(value = "create_time")
private LocalDateTime createTime;
}
CommentNode类
@Data
public class CommentNode {
private Comment comment;
private List<ReplyNode> replyNodes = new ArrayList<>();
}
Reply类
@Data
@TableName(value = "reply")
public class Reply implements Serializable {
/**
* 主键id
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 评论或者回复id
*/
@TableField(value = "tr_id")
private Long trId;
/**
* 是回复还是评论,0表示回复评论,1表示回复回复
*/
@TableField(value = "tr_status")
private Integer trStatus;
/**
* 用户id
*/
@TableField(value = "uid")
private String uid;
/**
* 用户名
*/
@TableField(value = "uname")
private String uname;
/**
* 回复内容
*/
@TableField(value = "rcontent")
private String rcontent;
/**
* 创建时间
*/
@TableField(value = "create_time")
private LocalDateTime createTime;
private static final long serialVersionUID = 1L;
}
ReplyNode类
@Data
public class ReplyNode {
private Reply reply;
private List<ReplyNode> replyNodes = new ArrayList<>();
}
我们的整体设计思路是取出一级评论,在使用链表的形式,使用递归去查询该评论或者该回复是否含有回复,如果有就插入,没有就结束
@Override
public List<Comment> findAll() {
return commentMapper.selectList(new QueryWrapper<>());
}
@Override
public List<CommentNode> pageInfo() {
//得到所有评论
List<Comment> commentList = findAll();
//装下所有评论的List
List<CommentNode> commentNodes = new ArrayList<>();
for (Comment comment : commentList) {
CommentNode commentNode = new CommentNode();
//把每个Comment变成CommentNode
commentNode.setComment(comment);
//获取评论ID
Long id = comment.getId();
//找到是这个评论的所有回复
List<Reply> thisReplyList = replyService.findAllById(id);
//遍历每个第一层回复
for (Reply re : thisReplyList) {
ReplyNode replayNode = new ReplyNode();
replayNode.setReply(re);
commentNode.getReplyNodes().add(replayNode);
//得到回复的回复
List<Reply> replayList = replyService.findAllByTrid(re.getTrId());
//递归
addReplyNode(replayList, replayNode);
}
commentNodes.add(commentNode);
}
return commentNodes;
}
/**
* 插入链表 参数分别代表需要待插入的节点list 和这些节点的父亲是谁
*/
public void addReplyNode(List<Reply> replyList, ReplyNode node) {
//为空就直接返回
if (replyList.isEmpty()) {
return;
}
//挨个遍历list中的节点信息,然后如果节点还有孩子就继续递归
for (Reply re : replyList) {
ReplyNode replyNode = new ReplyNode();
replyNode.setReply(re);
node.getReplyNodes().add(replyNode);
List<Reply> replayList = replyService.findAllByTrid(re.getId());
//有孩子就继续递归
addReplyNode(replayList, replyNode);
}
}