評論回覆功能,總結開發-Java

zukxu123發表於2020-10-31

評論回覆功能,總結開發-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);
		}
	}

相關文章