mirror of https://github.com/halo-dev/halo
🍎 新增评论盖楼,管理员回复评论可使用表情。
parent
e31b6d9d24
commit
005a7e4f96
|
@ -6,6 +6,7 @@ import lombok.Data;
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
|
@ -93,4 +94,10 @@ public class Comment implements Serializable {
|
||||||
* 是否是博主的评论 0:不是 1:是
|
* 是否是博主的评论 0:不是 1:是
|
||||||
*/
|
*/
|
||||||
private Integer isAdmin;
|
private Integer isAdmin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前评论下的所有子评论
|
||||||
|
*/
|
||||||
|
@Transient
|
||||||
|
private List<Comment> childComments;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package cc.ryanc.halo.utils;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.model.domain.Comment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : RYAN0UP
|
||||||
|
* @date : 2018/7/12
|
||||||
|
*/
|
||||||
|
public class CommentUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取组装好的评论
|
||||||
|
*
|
||||||
|
* @param commentsRoot commentsRoot
|
||||||
|
* @return List
|
||||||
|
*/
|
||||||
|
public static List<Comment> getComments(List<Comment> commentsRoot) {
|
||||||
|
List<Comment> commentsResult = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < commentsRoot.size(); i++) {
|
||||||
|
if (commentsRoot.get(i).getCommentParent() == 0) {
|
||||||
|
commentsResult.add(commentsRoot.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Comment comment : commentsResult) {
|
||||||
|
comment.setChildComments(getChild(comment.getCommentId(), commentsRoot));
|
||||||
|
}
|
||||||
|
return commentsResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取评论的子评论
|
||||||
|
*
|
||||||
|
* @param id 评论编号
|
||||||
|
* @param commentsRoot commentsRoot
|
||||||
|
* @return List
|
||||||
|
*/
|
||||||
|
private static List<Comment> getChild(Long id, List<Comment> commentsRoot) {
|
||||||
|
List<Comment> commentsChild = new ArrayList<>();
|
||||||
|
for (Comment comment : commentsRoot) {
|
||||||
|
if (comment.getCommentParent() != 0) {
|
||||||
|
if (comment.getCommentParent().equals(id)) {
|
||||||
|
commentsChild.add(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Comment comment : commentsChild) {
|
||||||
|
if (comment.getCommentParent() != 0) {
|
||||||
|
comment.setChildComments(getChild(comment.getCommentId(), commentsRoot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (commentsChild.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return commentsChild;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import cc.ryanc.halo.service.CommentService;
|
||||||
import cc.ryanc.halo.service.MailService;
|
import cc.ryanc.halo.service.MailService;
|
||||||
import cc.ryanc.halo.service.PostService;
|
import cc.ryanc.halo.service.PostService;
|
||||||
import cc.ryanc.halo.service.UserService;
|
import cc.ryanc.halo.service.UserService;
|
||||||
|
import cc.ryanc.halo.utils.OwoUtil;
|
||||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.lang.Validator;
|
import cn.hutool.core.lang.Validator;
|
||||||
|
@ -196,8 +197,8 @@ public class CommentController extends BaseController {
|
||||||
comment.setCommentAuthorIp(ServletUtil.getClientIP(request));
|
comment.setCommentAuthorIp(ServletUtil.getClientIP(request));
|
||||||
comment.setCommentAuthorAvatarMd5(SecureUtil.md5(user.getUserEmail()));
|
comment.setCommentAuthorAvatarMd5(SecureUtil.md5(user.getUserEmail()));
|
||||||
comment.setCommentDate(DateUtil.date());
|
comment.setCommentDate(DateUtil.date());
|
||||||
String lastContent = " //<a href='#comment-id-" + lastComment.getCommentId() + "'>@" + lastComment.getCommentAuthor() + "</a>:" + lastComment.getCommentContent();
|
String lastContent = "<a href='#comment-id-" + lastComment.getCommentId() + "'>@" + lastComment.getCommentAuthor() + "</a> ";
|
||||||
comment.setCommentContent(commentContent + lastContent);
|
comment.setCommentContent(lastContent + OwoUtil.markToImg(commentContent));
|
||||||
comment.setCommentAgent(userAgent);
|
comment.setCommentAgent(userAgent);
|
||||||
comment.setCommentParent(commentId);
|
comment.setCommentParent(commentId);
|
||||||
comment.setCommentStatus(0);
|
comment.setCommentStatus(0);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import cc.ryanc.halo.model.domain.Post;
|
||||||
import cc.ryanc.halo.model.enums.PostType;
|
import cc.ryanc.halo.model.enums.PostType;
|
||||||
import cc.ryanc.halo.service.CommentService;
|
import cc.ryanc.halo.service.CommentService;
|
||||||
import cc.ryanc.halo.service.PostService;
|
import cc.ryanc.halo.service.PostService;
|
||||||
|
import cc.ryanc.halo.utils.CommentUtil;
|
||||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -119,7 +120,7 @@ public class FrontArchiveController extends BaseController {
|
||||||
Pageable pageable = PageRequest.of(0,999,sort);
|
Pageable pageable = PageRequest.of(0,999,sort);
|
||||||
Page<Comment> comments = commentService.findCommentsByPostAndCommentStatus(post,pageable,0);
|
Page<Comment> comments = commentService.findCommentsByPostAndCommentStatus(post,pageable,0);
|
||||||
model.addAttribute("post", post);
|
model.addAttribute("post", post);
|
||||||
model.addAttribute("comments",comments);
|
model.addAttribute("comments", CommentUtil.getComments(comments.getContent()));
|
||||||
postService.updatePostView(post);
|
postService.updatePostView(post);
|
||||||
return this.render("post");
|
return this.render("post");
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import cc.ryanc.halo.service.CommentService;
|
||||||
import cc.ryanc.halo.service.MailService;
|
import cc.ryanc.halo.service.MailService;
|
||||||
import cc.ryanc.halo.service.PostService;
|
import cc.ryanc.halo.service.PostService;
|
||||||
import cc.ryanc.halo.service.UserService;
|
import cc.ryanc.halo.service.UserService;
|
||||||
|
import cc.ryanc.halo.utils.CommentUtil;
|
||||||
import cc.ryanc.halo.utils.OwoUtil;
|
import cc.ryanc.halo.utils.OwoUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.lang.Validator;
|
import cn.hutool.core.lang.Validator;
|
||||||
|
@ -30,8 +31,6 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author : RYAN0UP
|
* @author : RYAN0UP
|
||||||
|
@ -64,12 +63,12 @@ public class FrontCommentController {
|
||||||
public List<Comment> getComment(@PathVariable Long postId) {
|
public List<Comment> getComment(@PathVariable Long postId) {
|
||||||
Optional<Post> post = postService.findByPostId(postId);
|
Optional<Post> post = postService.findByPostId(postId);
|
||||||
Sort sort = new Sort(Sort.Direction.DESC, "commentDate");
|
Sort sort = new Sort(Sort.Direction.DESC, "commentDate");
|
||||||
Pageable pageable = PageRequest.of(0, 10, sort);
|
Pageable pageable = PageRequest.of(0, 999, sort);
|
||||||
List<Comment> comments = commentService.findCommentsByPostAndCommentStatus(post.get(), pageable, 2).getContent();
|
List<Comment> comments = commentService.findCommentsByPostAndCommentStatus(post.get(), pageable, 0).getContent();
|
||||||
if (null == comments) {
|
if (null == comments) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return comments;
|
return CommentUtil.getComments(comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,8 +112,8 @@ public class FrontCommentController {
|
||||||
comment.setCommentAuthor(HtmlUtil.encode(comment.getCommentAuthor()));
|
comment.setCommentAuthor(HtmlUtil.encode(comment.getCommentAuthor()));
|
||||||
if(comment.getCommentParent()>0){
|
if(comment.getCommentParent()>0){
|
||||||
lastComment = commentService.findCommentById(comment.getCommentParent()).get();
|
lastComment = commentService.findCommentById(comment.getCommentParent()).get();
|
||||||
String lastContent = " //<a href='#comment-id-"+lastComment.getCommentId()+"'>@"+lastComment.getCommentAuthor()+"</a>:"+lastComment.getCommentContent();
|
String lastContent = "<a href='#comment-id-" + lastComment.getCommentId() + "'>@" + lastComment.getCommentAuthor() + "</a>";
|
||||||
comment.setCommentContent(StringUtils.substringAfter(OwoUtil.markToImg(HtmlUtil.encode(comment.getCommentContent())),":")+lastContent);
|
comment.setCommentContent(lastContent + StringUtils.substringAfter(OwoUtil.markToImg(HtmlUtil.encode(comment.getCommentContent())), ":"));
|
||||||
}else{
|
}else{
|
||||||
//将评论内容的字符专为安全字符
|
//将评论内容的字符专为安全字符
|
||||||
comment.setCommentContent(OwoUtil.markToImg(HtmlUtil.encode(comment.getCommentContent())));
|
comment.setCommentContent(OwoUtil.markToImg(HtmlUtil.encode(comment.getCommentContent())));
|
||||||
|
|
|
@ -7,6 +7,7 @@ import cc.ryanc.halo.model.enums.PostType;
|
||||||
import cc.ryanc.halo.service.CommentService;
|
import cc.ryanc.halo.service.CommentService;
|
||||||
import cc.ryanc.halo.service.GalleryService;
|
import cc.ryanc.halo.service.GalleryService;
|
||||||
import cc.ryanc.halo.service.PostService;
|
import cc.ryanc.halo.service.PostService;
|
||||||
|
import cc.ryanc.halo.utils.CommentUtil;
|
||||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
@ -75,7 +76,7 @@ public class FrontPageController extends BaseController {
|
||||||
if(null==post){
|
if(null==post){
|
||||||
return this.renderNotFound();
|
return this.renderNotFound();
|
||||||
}
|
}
|
||||||
model.addAttribute("comments",comments);
|
model.addAttribute("comments", CommentUtil.getComments(comments.getContent()));
|
||||||
model.addAttribute("post", post);
|
model.addAttribute("post", post);
|
||||||
postService.updatePostView(post);
|
postService.updatePostView(post);
|
||||||
return this.render("page");
|
return this.render("page");
|
||||||
|
|
|
@ -130,7 +130,8 @@
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="/admin/comments/reply">
|
<form method="post" action="/admin/comments/reply">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<textarea class="form-control" rows="5" id="commentContent" name="commentContent" style="resize: none"></textarea>
|
<textarea class="form-control comment-input-content" rows="5" id="commentContent" name="commentContent" style="resize: none"></textarea>
|
||||||
|
<div class="OwO"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<input type="hidden" id="commentId" name="commentId" value=""/>
|
<input type="hidden" id="commentId" name="commentId" value=""/>
|
||||||
|
@ -144,6 +145,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
var s = new OwO({
|
||||||
|
container: document.getElementsByClassName('OwO')[0],
|
||||||
|
target: document.getElementsByClassName('comment-input-content')[0],
|
||||||
|
position: 'down',
|
||||||
|
width: '100%',
|
||||||
|
maxHeight: '210px',
|
||||||
|
api:"/static/plugins/OwO/OwO.min.json"
|
||||||
|
});
|
||||||
function modelShow(url,message) {
|
function modelShow(url,message) {
|
||||||
$('#url').val(url);
|
$('#url').val(url);
|
||||||
$('#message').html(message);
|
$('#message').html(message);
|
||||||
|
|
|
@ -15,12 +15,14 @@
|
||||||
<link rel="stylesheet" href="/static/css/loader.css">
|
<link rel="stylesheet" href="/static/css/loader.css">
|
||||||
<link rel="stylesheet" href="/static/plugins/toast/css/jquery.toast.min.css">
|
<link rel="stylesheet" href="/static/plugins/toast/css/jquery.toast.min.css">
|
||||||
<link rel="stylesheet" href="/static/plugins/fileinput/fileinput.min.css">
|
<link rel="stylesheet" href="/static/plugins/fileinput/fileinput.min.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="/static/plugins/OwO/OwO.min.css">
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
<script src="//oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
<script src="//oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||||
<script src="//oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
<script src="//oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<script src="/static/plugins/jquery/jquery.min.js"></script>
|
<script src="/static/plugins/jquery/jquery.min.js"></script>
|
||||||
<script src="/static/plugins/bootstrap/js/bootstrap.min.js"></script>
|
<script src="/static/plugins/bootstrap/js/bootstrap.min.js"></script>
|
||||||
|
<script src="/static/plugins/OwO/OwO.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="hold-transition sidebar-mini ${options.admin_theme?default('skin-blue')} ${options.admin_layout?default('')} ${options.sidebar_style?default('')}">
|
<body class="hold-transition sidebar-mini ${options.admin_theme?default('skin-blue')} ${options.admin_layout?default('')} ${options.sidebar_style?default('')}">
|
||||||
<#if options.admin_loading?default("false") == "true">
|
<#if options.admin_loading?default("false") == "true">
|
||||||
|
|
|
@ -223,6 +223,12 @@
|
||||||
.comment-input-who, .comment-input-email, .comment-input-website {
|
.comment-input-who, .comment-input-email, .comment-input-website {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
.ua{
|
||||||
|
display: none!important;
|
||||||
|
}
|
||||||
|
.native-list{
|
||||||
|
margin-left: 5px!important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="native-comment">
|
<div class="native-comment">
|
||||||
|
@ -248,11 +254,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="native-message" style="text-align: center;padding: 20px;display: none"></div>
|
<div class="native-message" style="text-align: center;padding: 20px;display: none"></div>
|
||||||
<div class="native-info">
|
<div class="native-info">
|
||||||
<span id="native-info-total" style="font-weight: 600">${comments.getTotalElements()}</span>评论
|
<#--<span id="native-info-total" style="font-weight: 600">${comments.getTotalElements()}</span>评论-->
|
||||||
</div>
|
</div>
|
||||||
<ul class="native-list">
|
<#macro childComments comments>
|
||||||
<#if comments.content?? && comments.content?size gt 0>
|
<ul class="native-list" style="margin-left: 20px; border-left: 1px solid #f1f1f1">
|
||||||
<#list comments.content as comment>
|
<#if comments?? && comments?size gt 0>
|
||||||
|
<#list comments as comment>
|
||||||
<li class="native-list-one" id="comment-id-${comment.commentId?c}">
|
<li class="native-list-one" id="comment-id-${comment.commentId?c}">
|
||||||
<img class="native-list-one-img" src="//www.gravatar.com/avatar/${comment.commentAuthorAvatarMd5?if_exists}?s=256&d=${options.native_comment_avatar?default('mm')}">
|
<img class="native-list-one-img" src="//www.gravatar.com/avatar/${comment.commentAuthorAvatarMd5?if_exists}?s=256&d=${options.native_comment_avatar?default('mm')}">
|
||||||
<section>
|
<section>
|
||||||
|
@ -271,6 +278,38 @@
|
||||||
<span at="${comment.commentId?c}" class="native-list-one-footer-reback">回复</span>
|
<span at="${comment.commentId?c}" class="native-list-one-footer-reback">回复</span>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<#if comment.childComments?? && comment.childComments?size gt 0>
|
||||||
|
<@childComments comment.childComments></@childComments>
|
||||||
|
</#if>
|
||||||
|
</li>
|
||||||
|
</#list>
|
||||||
|
</#if>
|
||||||
|
</ul>
|
||||||
|
</#macro>
|
||||||
|
<ul class="native-list">
|
||||||
|
<#if comments?? && comments?size gt 0>
|
||||||
|
<#list comments as comment>
|
||||||
|
<li class="native-list-one" id="comment-id-${comment.commentId?c}">
|
||||||
|
<img class="native-list-one-img" src="//www.gravatar.com/avatar/${comment.commentAuthorAvatarMd5?if_exists}?s=256&d=${options.native_comment_avatar?default('mm')}">
|
||||||
|
<section>
|
||||||
|
<div class="native-list-one-head">
|
||||||
|
<a class="native-list-one-head-name" rel="nofollow" href="${comment.commentAuthorUrl?if_exists}">${comment.commentAuthor?if_exists}</a>
|
||||||
|
<span class="native-comment-ua-info" style="display: none">${comment.commentAgent?if_exists}</span>
|
||||||
|
<#if comment.isAdmin==1>
|
||||||
|
<label class="native-list-one-head-admin">博主</label>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
<div class="native-list-one-content">
|
||||||
|
<p>${comment.commentContent?if_exists}</p>
|
||||||
|
</div>
|
||||||
|
<div class="native-list-one-footer">
|
||||||
|
<span class="native-list-one-footer-time">${comment.commentDate?string("yyyy-MM-dd HH:mm")}</span>
|
||||||
|
<span at="${comment.commentId?c}" class="native-list-one-footer-reback">回复</span>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<#if comment.childComments?? && comment.childComments?size gt 0>
|
||||||
|
<@childComments comment.childComments></@childComments>
|
||||||
|
</#if>
|
||||||
</li>
|
</li>
|
||||||
</#list>
|
</#list>
|
||||||
</#if>
|
</#if>
|
||||||
|
@ -376,4 +415,4 @@
|
||||||
return '<span class="ua">'+browser+'</span><span class="ua">'+os+'</span>';
|
return '<span class="ua">'+browser+'</span><span class="ua">'+os+'</span>';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</@compress>
|
</@compress>
|
||||||
|
|
Loading…
Reference in New Issue