1. 回复列表
1.1 question.html中增加标签
<h4>
<span th:text="${question.commentCount}"></span>个回复
</h4>
<hr class="col-lg-12 col-md-12 col-sm-12 col-xs-12 comment-sp">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 comments" th:each="comment : ${comments}">
<div class="media">
<div class="media-left">
<a href="">
<img th:src="${comment.user.getAvatarUrl()}" class="media-object img-rounded">
</a>
</div>
<div class="media-body">
<h5 class="media-heading">
<span th:text="${comment.user.name}"></span>
</h5>
<div th:text="${comment.content}"></div>
<div class="menu">
<span class="glyphicon glyphicon-thumbs-up icon"></span>
<span class="glyphicon glyphicon-comment icon"></span>
<span class="pull-right" th:text="${#dates.format(comment.gmtCreate,'yyyy-MM-dd')}"></span>
</div>
</div>
</div>
</div>
1.2 增加样式
1.3 CommentCreateDTO
把之前的CommentDTO变为CommentCreateDTO
它的意思是提供创建评论的数据,对应页面传来的参数
1.4 新建CommentDTO
比Comment多了个User对象,为了展示出所有的数据
1.5 QuestionController
package life.guohui.community.controller;
@Controller
public class QuestionController {
@Autowired
private QuestionService questionService;
@Autowired
private CommentService commentService;
@GetMapping("question/{id}")
public String question(@PathVariable(name = "id") Long id,
Model model){
QuestionDTO questionDTO = questionService.getById(id);
List<CommentDTO> comments = commentService.listByQuestionId(id);
//累加阅读数
questionService.inView(id);
model.addAttribute("question",questionDTO);
model.addAttribute("comments",comments);
return "question";
}
}
1.6 CommentService
public List<CommentDTO> listByQuestionId(Long id) {
CommentExample example = new CommentExample();
example.createCriteria().andParentIdEqualTo(id).andTypeEqualTo(CommentTypeEnum.QUESTION.getType());
List<Comment> comments = commentMapper.selectByExample(example);
if(comments.size() == 0){
return new ArrayList<>();
}
//获取去重的评论人
Set<Long> commentators = comments.stream().map(comment -> comment.getCommentator()).collect(Collectors.toSet());
List<Long> userIds = new ArrayList();
userIds.addAll(commentators);
//获取评论人并转换为map
UserExample userExample = new UserExample();
userExample.createCriteria().andIdIn(userIds);
List<User> users = userMapper.selectByExample(userExample);
Map<Long, User> userMap = users.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));
//转换comment为commentDTO
List<CommentDTO> commentDTOS = comments.stream().map(comment -> {
CommentDTO commentDTO = new CommentDTO();
BeanUtils.copyProperties(comment,commentDTO);
commentDTO.setUser(userMap.get(comment.getCommentator()));
return commentDTO;
}).collect(Collectors.toList());
return commentDTOS;
}
页面显示效果
2. 校验回复和页面调整
2.1 CustomizeErrorCode中添加校验信息
2.2 CommentController
StringUtiles
的使用需要导入依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
2.3 前端js添加验证
在响应成功后刷新页面
window.location.reload();
2.4 把评论根据时间排序
2.5 页面调整
3. 二级评论展示
3.1 点击信息后
调用collapseComments方法
function collapseComments(e) {
//获得当前评论的id
var id = e.getAttribute("data-id");
//根据id获得此评论下的二级评论元素对象
var comments = $("#comment-"+id);
var collapse = e.getAttribute("data-collapse");
if(collapse){
//折叠二级评论
comments.removeClass("in");
e.removeAttribute("data-collapse");
e.classList.remove("active");
}else {
var subCommentContainer = $("#comment-" + id);
if (subCommentContainer.children().length != 1) {
//展开二级评论
comments.addClass("in");
// 标记二级评论展开状态
e.setAttribute("data-collapse", "in");
e.classList.add("active");
} else {
$.getJSON("/comment/" + id, function (data) {
$.each(data.data.reverse(), function (index, comment) {
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",
"html": comment.user.name
})).append($("<div/>", {
"html": comment.content
})).append($("<div/>", {
"class": "menu"
}).append($("<span/>", {
"class": "pull-right",
"html": moment(comment.gmtCreate).format('YYYY-MM-DD')
})));
var mediaElement = $("<div/>", {
"class": "media"
}).append(mediaLeftElement).append(mediaBodyElement);
var commentElement = $("<div/>", {
"class": "col-lg-12 col-md-12 col-sm-12 col-xs-12 comments"
}).append(mediaElement);
subCommentContainer.prepend(commentElement);
});
//展开二级评论
comments.addClass("in");
// 标记二级评论展开状态
e.setAttribute("data-collapse", "in");
e.classList.add("active");
});
}
}
}
3.2 信息图标高亮
3.2 ResultDTO加一个泛型
方便返回数据
package life.guohui.community.dto;
@Data
public class ResultDTO<T> {
private Integer code;
private String message;
private T data;
public static ResultDTO errorOf(Integer code,String message){
ResultDTO resultDTO = new ResultDTO();
resultDTO.setCode(code);
resultDTO.setMessage(message);
return resultDTO;
}
public static ResultDTO errorOf(CustomizeErrorCode errorCode) {
return errorOf(errorCode.getCode(),errorCode.getMessage());
}
public static ResultDTO okOf(){
ResultDTO resultDTO = new ResultDTO();
resultDTO.setCode(200);
resultDTO.setMessage("请求成功");
return resultDTO;
}
public static <T> ResultDTO okOf(T t){
ResultDTO resultDTO = new ResultDTO();
resultDTO.setCode(200);
resultDTO.setMessage("请求成功");
resultDTO.setData(t);
return resultDTO;
}
public static ResultDTO errorOf(CustomizeException e) {
return errorOf(e.getCode(),e.getMessage());
}
}
3.3 重构listByTarget方法
让它通过上级的id
,和type
(评论类型)去查对应的所有下级评论
type
用CommentTypeEnum
类表示
3.4 查询二级评论API
4. 发布二级评论
4.1 JS中comment()方法
拿到它的父评论Id,和评论的内容,调用comment2target方法,0表示它属于二级评论
4.2 comment2target方法Ajax
向服务器发送请求,添加评论
function comment2target(targetId,type,content) {
if(!content){
alert("不能回复空内容~~");
return;
}
$.ajax({
type:"post",
url:"/comment",
contentType:"application/json",
data:JSON.stringify({
"parentId":targetId,
"content":content,
"type":type
}),
success:function (response) {
if(response.code == 200){
window.location.reload();
}else {
if(response.code == 2003){
var isAccepted = confirm(response.message);
if(isAccepted){
window.open("https://github.com/login/oauth/authorize?client_id=Iv1.bf5154208e60707f&redirect_uri=http://localhost:8887/callback&scope=user&state=1");
window.localStorage.setItem("closable",true);
}
}
}
console.log(response);
},
dataType:"json"
});
}
4.3 二级评论数的显示
当添加一级评论-comment
时,需要设置它的评论数初始值为0,给问题对象-question
评论数+1。
当添加二级评论-comment
时,要获得它对应的一级评论对象,给它的评论数+1。
对应的Mapper.xml
<update id="incCommentCount" parameterType="life.guohui.community.model.Comment">
update COMMENT
set comment_count = comment_count + #{commentCount,jdbcType=INTEGER}
where id = #{id}
</update>
网友评论