文章评论功能的实现
前端代码的实现
思路:数据库绑定文章的id,用户的id和评论的id,需要的时候就根据文章的id去查评论,评论id去查用户去联查就好了,用户和评论的关系是一对多的关系。即一个用户有多条评论,但一条评论只能属于一个用户。
实现:发布发布评论按钮时,获取当文章的id,评论的内容,判断评论的内容是否为空,
如果为空提醒用户输入评论内容,反之发送一个ajax请求到后台,先判断用户是否登陆,如果用户没有登陆,提醒用户登陆并跳转到登陆页面。
后台代码
判断用户是否登陆,如果用户登陆,保存评论
创建一个评论的实现类,填充实现类,添加到数据库
mapper接口和SQL
如果添加记录成功,就返回一个评论的dto对象,返回给前端,让js填充评论内容
beanCopier 是cglib下的bean复制工具,复制的对象拥有的属性可以比被复制的属性少,但是其他属性一定要一样。还有两个对象都需要由getter方法,用于反射取值。
评论的dto对象
填充评论的js代码
想要源码的可以私信我,这里就贴出来给你们看
//填充文章评论和回复
function putInComment(data) {
$('#comment').val('');
var comment = $('.comment');
var commentBottom = $('.comment-bottom');
commentBottom.html('');
if (data.length == 0) {
var comments = $('<div class="comments">' +
'<span class="noComment" style="color: black">还没有评论,快来抢沙发吧!</span>' +
'</div>');
commentBottom.append(comments);
comment.append(commentBottom);
}
else {
var articleComment = $('<div class="article-comment"></div>');
var articleCommentTop = $('<div class="article-comment-top">' +
'<span class="article-comment-word">评论</span>' +
'<div class="article-comment-line"></div>' +
'</div>');
var newComment = $('<div class="new-comment">' +
'<i class="all-comment zi zi_list"></i>全部评论(<span class="commentNum">' + '' + '</span>)' +
'</div>');
articleComment.append(articleCommentTop);
articleComment.append(newComment);
var allComments = $('<div class="all-comments"></div>');
$.each(data, function (index, obj) {
var visitorReplies = $('<div class="visitorReplies"></div>');
if (obj.replies != null) {
$.each(obj.replies, function (index1, obj1) {
var visitorReply = $('<div id="p' + obj1.replyId + '" class="visitorReply"></div>');
var visitorReplyWords = $('<div class="visitorReplyWords">' +
'<a class="answerer">' + obj1.user.userName + '</a>: <a class="respondent">@' + obj1.user.userName + ' </a>' + obj1.replyContent +
'</div>');
var visitorReplyTime = $('<div class="visitorReplyTime">' +
'<span class="visitorReplyTimeTime">' + obj1.replyTime + '</span>' +
'<a>' +
'<i class="replyReply zi zi_msgchat"> 回复</i>' +
'</a>' +
'</div>');
visitorReply.append(visitorReplyWords);
visitorReply.append(visitorReplyTime);
visitorReply.append($('<hr data-am-widget="divider" style="" class="am-divider am-divider-dashed"/>'));
visitorReplies.append(visitorReply);
});
}
var subCommentList = $('<div class="sub-comment-list" id = "' + obj.commentId + '"></div>');
var moreComment = $('<div class="more-comment">' +
'<a>' +
'<i class="moreComment zi zi_msgchat"> 添加新评论</i>' +
'</a>' +
'</div>');
subCommentList.append(visitorReplies);
subCommentList.append(moreComment);
var subComment = $('<div class="sub-comment" id = "' + obj.commentId + '"></div>');
if (obj.replies != null) {
subComment.append(subCommentList);
}
subComment.append($('<div class="reply-sub-comment-list am-animation-slide-bottom">' +
'<div class="replyWord">' +
'<div class="replyWordBtn">' +
'<textarea class="replyWordTextarea" placeholder="写下你的评论..."></textarea>' +
'<button type="button" class="sendReplyWordBtn btn btn-success">发送</button>' +
'<button type="button" class="quitReplyWordBtn btn btn-secondary">取消</button>' +
'</div>' +
'</div>' +
'</div>'));
var amG = $('<div class="row"></div>');
amG.append($('<div class="visitorCommentImg col-sm-2 col-lg-1">' +
'<img src="' + obj.user.avatarUrl + '">' +
'</div>'));
var amUSm10 = $('<div class="col-sm-10 col-lg-11"></div>');
var visitorInfo = $('<div class="visitorInfo">' +
'<span class="visitorFloor">#' + (index + 1) + '楼</span>' +
'<span class="visitorName">' +
obj.user.userName +
'</span>' +
'<span class="visitorPublishDate">' +
obj.commentTime +
'</span>' +
'</div>');
var visitorSay = $('<div class="visitorSay">' +
obj.commentContent +
'</div>');
var toolGroup1 = $('<div class="tool-group">' +
'<a>' +
'<i class="like zi zi_digg"> <span>' + obj.comment_like_count + '</span>人赞</i>' +
'</a>' +
'<a>' +
'<i class="reply zi zi_msgchat"> 回复</i>' +
'</a>' +
'</div>');
var toolGroup2 = $('<div class="tool-group">' +
'<a>' +
'<i class="like zi zi_digg text-success"> <span>' + obj.comment_like_count + '</span>人赞</i>' +
'</a>' +
'<a>' +
'<i class="reply zi zi_msgchat"> 回复</i>' +
'</a>' +
'</div>');
amUSm10.append(visitorInfo);
amUSm10.append(visitorSay);
if (obj.comment_like_count > 0) {
amUSm10.append(toolGroup2);
} else {
amUSm10.append(toolGroup1);
}
amUSm10.append(subComment);
amG.append(amUSm10);
var visitorComment = $('<div class="visitorComment" id="' + obj.commentId + '"></div>');
visitorComment.append(amG);
visitorComment.append($('<hr>'));
allComments.append(visitorComment);
});
articleComment.append(allComments);
commentBottom.append(articleComment);
comment.append(commentBottom);
//添加评论数
$('.commentNum').html(data.length);
}
效果展示
评论中回复的实现
思路:基本实现下来和评论差不多,绑定的对象是评论和用户,不用考虑文章,因为每一条回复属于一个文章,也属于一个用户,文章和回复的关系是一对多的关系。即一条评论可以有多个回复。一条回复也属于一个用户,也是一对多。
实现:和评论基本一致,点击发送回复按钮,检查内容是否为空,不为空发送一个ajax到后端,判断用户是否登陆,没有登陆提醒用户登陆并跳转到登陆页面。
前台代码
//发送评论中的回复
$('.sendReplyWordBtn').click(function () {
var $this = $(this);
var replyContent = $this.parent().parent().find($('.replyWordTextarea')).val();
var pId = $this.parent().parent().parent().parent().attr("id");
if (replyContent == "") {
toastr.warning("留白我咋知道你想啥呢");
} else {
$.ajax({
type: 'POST',
url: '/article/comment/publishReply',
dataType: 'json',
data: {
replyContent: replyContent,
articleId: $(".likeBtn").attr('id'),
parentId: pId
},
success: function (data) {
if (data == null) {
toastr.warning('请先登陆噢');
window.location.replace("/login");
} else {
toastr.success('发布评论回复成功,+1条回复');
var sub_comment = $this.parent().parent().parent().parent();
var visitorReply = $('<div id=p' + data.replyId + ' class="visitorReply"></div>');
var visitorReplyWords = $('<div class="visitorReplyWords">' +
'<a class="answerer">' + data.user.userName + '</a>: <a class="respondent">@' + respondent + ' </a>' + data.replyContent + '' +
'</div>');
var visitorReplyTime = $('<div class="visitorReplyTime">' +
'<span class="visitorReplyTimeTime">' + data.replyTime + '</span>' +
'<a>' +
'<i class="replyReply zi zi_msgchat"> 回复</i>' +
'</a>' +
'</div>');
visitorReply.append(visitorReplyWords);
visitorReply.append(visitorReplyTime);
visitorReply.append('<hr data-am-widget="divider" style="" class="am-divider am-divider-dashed" />');
if (sub_comment.find('.sub-comment-list').length > 0) {
sub_comment.find('.visitorReplies').append(visitorReply);
} else {
var visitorReplies = $('<div class="visitorReplies"></div>');
var sub_comment_list = $('<div class="sub-comment-list"></div>');
visitorReplies.append(visitorReply);
sub_comment_list.append(visitorReplies);
sub_comment_list.append($('<div class="more-comment">' +
' <a>' +
'<i class="moreComment zi zi_msgchat"> 添加新评论</i>' +
'</a>' +
'</div>'));
sub_comment.prepend(sub_comment_list);
}
//给新加入的评论中的回复和下面的添加新评论添加点击事件
$this.parent().parent().parent().parent().find('.visitorReplies>div:last-child').find('.replyReply ').click(function () {
respondent = $(this).parent().parent().prev().find($('.answerer')).html();
$(this).parent().parent().parent().parent().parent().next().css("display", "block");
$(this).parent().parent().parent().parent().parent().next().find($('.replyWordTextarea')).val('@' + respondent + ' ');
$(this).parent().parent().parent().parent().parent().next().find($('.replyWordTextarea')).focus();
});
$this.parent().parent().parent().parent().find('.sub-comment-list').find('.more-comment').find('.moreComment').click(function () {
$(this).parent().parent().parent().next().find($('.replyWordTextarea')).val('');
$(this).parent().parent().parent().next().css("display", "block");
respondent = $(this).parent().parent().parent().parent().parent().find('.visitorInfo').find('.visitorName').html();
});
$this.parent().find($('.replyWordTextarea')).val('');
$this.parent().parent().parent().css("display", "none");
}
},
error: function () {
toastr.error("回复失败!");
}
});
}
});
后端代码
也是返回一个dto对象,用来填充回复