文章評論功能的實現
前端代碼的實現
思路:數據庫綁定文章的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對象,用來填充回覆