实现发出子评论
此处发出post请求进行评论的回复与回复问题逻辑差不多,因此修改相关代码,进行复用
- 重构js方法
/**
* 实现评论的功能
*/
function comment(e) {
var type = e.getAttribute("data-type");//获取回复类型
//根据回复类型的不同获取父id
if (type == 1){
//问题
var parentId = $("#question_id").val();//获取questionId
var content = $("#comment_content").val();//获取问题评论的内容
}else if (type == 2){
//子评论
var parentId = e.getAttribute("data-id"); //获取父评论的id
var content = $("#sub_commit").val();//获取子评论的内容
}
postComment(parentId,type,content);
}
/**
* 发出post请求
* @param parentId 评论父Id
* @param type 评论父类型
* @param content 评论内容
*/
function postComment(parentId,type,content) {
//添加非空判断
if (!content){
alert("回复内容不能为空");
return;
}
//发出POST请求
$.ajax({
type:"POST",
url:"/comment",
contentType:"application/json",
dataType:"json",
data:JSON.stringify({
"parentId":parentId,
"content":content,
"type":type
}),
success:function (response) {
if (response.code == 200){
//回复成功后刷新页面以显示内容
window.location.reload();
}else {
if(response.code == 3001){
//登录异常
var isAccepted = confirm(response.message);
if (isAccepted){
window.open("https://github.com/login/oauth/authorize?client_id=728bc9dfda3dc246ba09&redirect_uri=http://localhost:8887/callback&scope=user&state=1");
//实现不刷新页面的登录
window.localStorage.setItem("closable","true");
}
}else {
alert(response.message);
}
}
}
});
}
后端实现显示子评论
- 为了请求后返回时可以返回子评论列表,改装ResultDTO
public class ResultDTO<T> {
private Integer code;
private String message;
private T data;
...
public static <T> ResultDTO successOf(T t){
ResultDTO resultDTO = new ResultDTO();
resultDTO.setCode(200);
resultDTO.setMessage("请求成功");
resultDTO.setData(t);
return resultDTO;
}
}
- 请求查询子评论时候,为了公用之前查询问题的评论的方法,对其进行改装,增加评论的类型参数
public List<CommentDTO> getListByParentId(Long parentId, CommentTypeEnum type) {
...
commentExample.createCriteria().andParentIdEqualTo(parentId)
.andTypeEqualTo(type.getType());
...
}
- 编写controller
@ResponseBody
@RequestMapping(value = "/comment/{id}",method = RequestMethod.GET)
public ResultDTO getSubComments(@PathVariable(name = "id") Long id){
List<CommentDTO> commentDTOs = commentService.getListByParentId(id, CommentTypeEnum.COMMENT);
return ResultDTO.successOf(commentDTOs);
}
- js方法的编写
/**
* 点击 展开/折叠二级评论
*/
function collapseComments(e) {
var id = e.getAttribute("data-id"); //获取点击评论的id
var comments = $("#comment-"+id);//获取点击到的评论的子回复部分div
var isCollapse = $("#comment-"+id).hasClass("in")//获取样式,以判断展开状态
if (isCollapse){
comments.removeClass("in");//移除样式,使其折叠
e.classList.remove("active");
}else{
var subCommentContainer = $("#comment-"+id);
if (subCommentContainer.children().length == 1){
//需要请求后台数据,然后再展开
$.getJSON("/comment/"+id,function (subComments) {
//追加标签以显示子评论数据
$.each(subComments.data.reverse(),function (index,comment) {
//子评论动态构成
var commentElement = $("<div/>",{
"class":"col-lg-12 col-md-12 col-sm-12 col-xs-12 comments"
});
var mediaElement = $("<div/>",{
"class":"media"
});
var mediaLeftElement = $("<div/>",{
"class":"media-left"
}).append($("<img/>",{
"class":"media-object img-rounded",
"src":comment.user.avatarUrl
}));
var mediaBodyElement = $("<div/>",{
"class":"media-body"
}).append($("<h5/>",{
"class":"media-heading",
"text":comment.user.name
})).append($("<div/>",{
"text":comment.content
})).append($("<div/>",{
"class":"comment-operate"
}).append($("<span/>",{
"class":"pull-right",
"text":moment(comment.timeModified).format('YYYY-MM-DD HH:mm')
})));
commentElement.append(mediaElement);
mediaElement.append(mediaLeftElement);
mediaElement.append(mediaBodyElement);
subCommentContainer.prepend(commentElement);
});
});
}
comments.addClass("in"); //添加css样式,使其展开
e.classList.add("active");
}
}
注意:在js代码中,为了转换时间格式,引入了文件moment.js
question.html
<script src="/js/moment.js"></script>
实现显示评论的回复数
- 修改数据表,增加评论数字段
ALTER TABLE tbl_comment ADD comment_account int default 0;
- 创建自己的mapper,以实现修改评论数
CommentExtMapper.xml和java文件
package com.july.community.mapper;
import com.july.community.model.Comment;
public interface CommentExtMapper {
int incComment(Comment record);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.july.community.mapper.CommentExtMapper">
<resultMap id="BaseResultMap" type="com.july.community.model.Comment">
<constructor>
<idArg column="id" javaType="java.lang.Long" jdbcType="BIGINT" />
<arg column="parent_id" javaType="java.lang.Long" jdbcType="BIGINT" />
<arg column="type" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="commentator" javaType="java.lang.Long" jdbcType="BIGINT" />
<arg column="time_create" javaType="java.lang.Long" jdbcType="BIGINT" />
<arg column="time_modified" javaType="java.lang.Long" jdbcType="BIGINT" />
<arg column="like_count" javaType="java.lang.Long" jdbcType="BIGINT" />
<arg column="content" javaType="java.lang.String" jdbcType="VARCHAR" />
<arg column="comment_count" javaType="java.lang.Integer" jdbcType="INTEGER" />
</constructor>
</resultMap>
<update id="incComment" parameterType="com.july.community.model.Comment">
update tbl_comment set
comment_count = comment_count + #{commentCount,jdbcType=INTEGER}
where id = #{id}
</update>
</mapper>
- 添加增加评论数的逻辑
@Autowired
private CommentExtMapper commentExtMapper;
...
...
//给评论添加回复数
parentComment.setCommentCount(1);
commentExtMapper.incComment(parentComment);
注意,controller中插入时传入的comment需要:
comment.setCommentCount(0);
特别的,需要构建的子评论前端代码如下,上部分通过js来动态生成
<!--子回复-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 collapse sub-comments"
th:id="${'comment-' + comment.id}">
<!--二级评论-->
<!--<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 comments"
th:each="comment : ${commentList}">
<div class="media">
<div class="media-left">
<img th:src="${comment.user.avatarUrl}"
class="media-object img-rounded">
</div>
<div class="media-body">
<h5 class="media-heading" th:text="${comment.user.name}">
</h5>
<!–评论内容–>
<div th:text="${comment.content}"></div>
<div class="comment-operate">
<span class="pull-right"
th:text="${#dates.format(comment.timeModified,'yyyy-MM-dd HH:mm')}"></span></span>
</div>
</div>
</div>
</div>-->
<!--子评论输入框-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<input type="text" class="form-control" placeholder="评论一下..." id="sub_commit"
required>
<button type="button" class="btn btn-success pull-right" th:data-type="2"
th:data-id="${comment.id}" onclick="comment(this)">评论
</button>
</div>
</div>
前端代码
完整的html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="${question.title}"></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/bootstrap-theme.min.css">
<script src="/js/jquery-3.4.1.min.js"></script>
<script src="/js/bootstrap.min.js" type="application/javascript"></script>
<link rel="stylesheet" href="/css/community.css">
<script src="/js/moment.js" type="application/javascript"></script>
<script src="/js/community.js" type="application/javascript"></script>
</head>
<body>
<!--导航条-->
<div th:insert="navigation :: nav"></div>
<!--问题列表-->
<div class="container-fluid main profile">
<div class="row">
<!--左边内容-->
<div class="col-lg-9 col-md-12 col-sm-12 col-xs-12">
<!--问题信息-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<h3><span th:text="${question.title}"></span></h3>
<!-- 标签和发起人等信息 -->
<span class="text-tag"><span th:text="${question.tag}"></span></span>
<span class="text-desc">作者:<span th:text="${question.user.name}"></span> | 评论数:<span
th:text="${question.commentCount}"></span> * 阅读数:<span
th:text="${question.viewCount}"></span> | 最近更新时间: <span
th:text="${#dates.format(question.timeModified,'yyyy-MM-dd')}"></span></span>
<hr class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<!--正文部分-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" th:text="${question.description}"></div>
<hr class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<!-- 相关操作 -->
<a class="operation" th:href="@{'/publish/' + ${question.id}}"
th:if="${session.user != null && session.user.id == question.creator}"><span
class="glyphicon glyphicon-edit" aria-hidden="true"></span>编辑</a>
</div>
<!--评论列表展示部分-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<h4><span th:text="${question.commentCount}"></span> 个回复</h4>
<hr class="col-lg-12 col-md-12 col-sm-12 col-xs-12 comment-hr">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 comments" th:each="comment : ${commentList}">
<div class="media">
<div class="media-left">
<a href="#">
<img th:src="${comment.user.avatarUrl}" class="media-object img-rounded">
</a>
</div>
<div class="media-body" th:id="${'comment-body-'+ comment.id}">
<h5 class="media-heading">
<span th:text="${comment.user.name}"></span>
</h5>
<!--评论内容-->
<div th:text="${comment.content}"></div>
<!--对评论的操作-->
<div class="comment-operate">
<span class="glyphicon glyphicon-thumbs-up icon"></span> <!--点赞-->
<span th:data-id="${comment.id}" onclick="collapseComments(this)" class="comment-icon">
<span class="glyphicon glyphicon-comment"></span> <!--评论-->
<span th:text="${comment.commentCount}"></span><!--评论的回复数-->
</span>
<span class="pull-right"
th:text="${#dates.format(comment.timeModified,'yyyy-MM-dd HH:mm')}"></span></span>
</div>
<!--子回复-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 collapse sub-comments"
th:id="${'comment-' + comment.id}">
<!--二级评论-->
<!--<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 comments"
th:each="comment : ${commentList}">
<div class="media">
<div class="media-left">
<img th:src="${comment.user.avatarUrl}"
class="media-object img-rounded">
</div>
<div class="media-body">
<h5 class="media-heading" th:text="${comment.user.name}">
</h5>
<!–评论内容–>
<div th:text="${comment.content}"></div>
<div class="comment-operate">
<span class="pull-right"
th:text="${#dates.format(comment.timeModified,'yyyy-MM-dd HH:mm')}"></span></span>
</div>
</div>
</div>
</div>-->
<!--子评论输入框-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<input type="text" class="form-control" placeholder="评论一下..." id="sub_commit"
required>
<button type="button" class="btn btn-success pull-right" th:data-type="2"
th:data-id="${comment.id}" onclick="comment(this)">评论
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<hr class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<!--评论回复部分-->
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12" id="comment_section">
<h4>提交回复</h4>
<!-- 评论人 -->
<div class="media-body">
<div class="media">
<!-- 头像部分 -->
<div class="media-left">
<a href="#">
<img class="media-object img-rounded" th:src="${session.user.avatarUrl}">
</a>
</div>
<!--用户名部分-->
<div class="media-body">
<h5 class="media-heading">
<span th:text="${session.user.name}"></span>
</h5>
</div>
</div>
</div>
<!--输入框-->
<input type="hidden" id="question_id" th:value="${question.id}">
<textarea id="comment_content" class="form-control comment" rows="6" required></textarea>
<button type="button" class="btn btn-success btn-comment" th:data-type="1" onclick="comment(this)">回复
</button>
</div>
</div>
<!--右边作者信息-->
<div class="col-lg-3 col-md-12 col-sm-12 col-xs-12">
<div class="list-group section">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<h4>发起人</h4>
<div class="media-body">
<div class="media">
<div class="media-left">
<a href="#">
<img class="media-object img-circle" th:src="${question.user.avatarUrl}">
</a>
</div>
<div class="media-body">
<h5 class="media-heading">
<span th:text="${question.user.name}"></span>
</h5>
</div>
</div>
</div>
</div>
<hr class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<h4>相关问题</h4>
</div>
</div>
</div>
</div>
</div>
</body>
</html>