Commit db39464b authored by RYAN0UP_'s avatar RYAN0UP_
Browse files

0.0.3

parent 41c98758
Showing with 240 additions and 110 deletions
+240 -110
......@@ -111,6 +111,7 @@ public class CommentController extends BaseController{
public String moveToPublish(@PathParam("commentId") Long commentId,
@PathParam("status") Integer status){
Comment comment = commentService.updateCommentStatus(commentId,0);
Post post = comment.getPost();
//判断评论者的邮箱是否符合规则
Pattern patternEmail = Pattern.compile("\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}");
......@@ -121,8 +122,12 @@ public class CommentController extends BaseController{
try {
if (status == 1 && matcher.find()) {
Map<String, Object> map = new HashMap<>();
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url")+"/archives/"+comment.getPost().getPostUrl()+"#comment-id-"+comment.getCommentId());
map.put("pageName", comment.getPost().getPostTitle());
if (StringUtils.equals(post.getPostType(), HaloConst.POST_TYPE_POST)) {
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
} else {
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/p/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
}
map.put("pageName", post.getPostTitle());
map.put("commentContent", comment.getCommentContent());
map.put("blogUrl", HaloConst.OPTIONS.get("blog_url"));
map.put("blogTitle", HaloConst.OPTIONS.get("blog_title"));
......@@ -213,7 +218,11 @@ public class CommentController extends BaseController{
map.put("blogTitle",HaloConst.OPTIONS.get("blog_title"));
map.put("commentAuthor",lastComment.getCommentAuthor());
map.put("pageName",lastComment.getPost().getPostTitle());
map.put("pageUrl",HaloConst.OPTIONS.get("blog_url")+"/archives/"+post.getPostUrl()+"#comment-id-"+comment.getCommentId());
if (StringUtils.equals(post.getPostType(), HaloConst.POST_TYPE_POST)) {
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
} else {
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/p/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
}
map.put("commentContent",lastComment.getCommentContent());
map.put("replyAuthor",user.getUserDisplayName());
map.put("replyContent",commentContent);
......
......@@ -178,7 +178,7 @@ public class PostController extends BaseController{
List<Category> categories = categoryService.strListToCateList(cateList);
post.setCategories(categories);
if(StringUtils.isNotEmpty(tagList)){
List<Tag> tags = tagService.strListToTagList(StringUtils.trim(tagList));
List<Tag> tags = tagService.strListToTagList(StringUtils.deleteWhitespace(tagList));
post.setTags(tags);
}
post.setPostUrl(urlFilter(post.getPostUrl()));
......
......@@ -8,6 +8,7 @@ import cc.ryanc.halo.service.MailService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.service.UserService;
import cc.ryanc.halo.utils.HaloUtils;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -20,6 +21,8 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author : RYAN0UP
......@@ -61,6 +64,23 @@ public class FrontCommentController {
return comments;
}
/**
* 加载评论
*
* @param page 页码
* @param post 当前文章
* @return List<Comment></>
*/
@GetMapping(value = "/loadComment")
@ResponseBody
public List<Comment> loadComment(@RequestParam(value = "page") Integer page,
@RequestParam(value = "post") Post post){
Sort sort = new Sort(Sort.Direction.DESC,"commentDate");
Pageable pageable = PageRequest.of(page-1,10,sort);
List<Comment> comments = commentService.findCommentsByPostAndCommentStatus(post,pageable,2).getContent();
return comments;
}
/**
* 提交新评论
*
......@@ -74,31 +94,104 @@ public class FrontCommentController {
public boolean newComment(@ModelAttribute("comment") Comment comment,
@ModelAttribute("post") Post post,
HttpServletRequest request) {
Comment lastComment = null;
post = postService.findByPostId(post.getPostId()).get();
if (StringUtils.isBlank(comment.getCommentAuthor())) {
comment.setCommentAuthor("小猪佩琪");
}
comment.setCommentAuthorEmail(comment.getCommentAuthorEmail().toLowerCase());
comment.setPost(post);
comment.setCommentDate(new Date());
comment.setCommentAuthorIp(HaloUtils.getIpAddr(request));
comment.setIsAdmin(0);
if(comment.getCommentParent()>0){
lastComment = commentService.findCommentById(comment.getCommentParent()).get();
String lastContent = " //<a href='#comment-id-"+lastComment.getCommentId()+"'>@"+lastComment.getCommentAuthor()+"</a>:"+lastComment.getCommentContent();
comment.setCommentContent(StringUtils.substringAfter(comment.getCommentContent(),":")+lastContent);
}
if(StringUtils.isNotEmpty(comment.getCommentAuthorUrl())){
if(!StringUtils.containsAny(comment.getCommentAuthorUrl(),"https://") || !StringUtils.containsAny(comment.getCommentAuthorUrl(),"http://")){
comment.setCommentAuthorUrl("http://"+comment.getCommentAuthorUrl());
}
}
commentService.saveByComment(comment);
if(comment.getCommentParent()>0){
//new EmailToParent(comment,lastComment,post).start();
}else{
new EmailToAdmin(comment,post).start();
}
return true;
}
if (StringUtils.equals(HaloConst.OPTIONS.get("smtp_email_enable"), "true") && StringUtils.equals(HaloConst.OPTIONS.get("new_comment_notice"), "true")) {
try {
//发送邮件到博主
Map<String, Object> map = new HashMap<>();
map.put("author", userService.findUser().getUserDisplayName());
map.put("pageName", post.getPostTitle());
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url")+"/archives/"+post.getPostUrl()+"#comment-id-"+comment.getCommentId());
map.put("visitor", comment.getCommentAuthor());
map.put("commentContent", comment.getCommentContent());
mailService.sendTemplateMail(userService.findUser().getUserEmail(), "有新的评论", map, "common/mail/mail_admin.ftl");
} catch (Exception e) {
log.error("邮件服务器未配置:{0}", e.getMessage());
/**
* 发送邮件给博主
*/
class EmailToAdmin extends Thread{
private Comment comment;
private Post post;
public EmailToAdmin(Comment comment,Post post){
this.comment = comment;
this.post = post;
}
@Override
public void run(){
if (StringUtils.equals(HaloConst.OPTIONS.get("smtp_email_enable"), "true") && StringUtils.equals(HaloConst.OPTIONS.get("new_comment_notice"), "true")) {
try {
//发送邮件到博主
Map<String, Object> map = new HashMap<>();
map.put("author", userService.findUser().getUserDisplayName());
map.put("pageName", post.getPostTitle());
if (StringUtils.equals(post.getPostType(), HaloConst.POST_TYPE_POST)) {
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
} else {
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/p/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
}
map.put("visitor", comment.getCommentAuthor());
map.put("commentContent", comment.getCommentContent());
mailService.sendTemplateMail(userService.findUser().getUserEmail(), "有新的评论", map, "common/mail/mail_admin.ftl");
} catch (Exception e) {
log.error("邮件服务器未配置:", e.getMessage());
}
}
}
}
/**
* 发送邮件给被评论方
*/
class EmailToParent extends Thread{
private Comment comment;
private Comment lastComment;
private Post post;
public EmailToParent(Comment comment,Comment lastComment,Post post){
this.comment = comment;
this.lastComment = lastComment;
this.post = post;
}
Pattern patternEmail = Pattern.compile("\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}");
Matcher matcher = patternEmail.matcher(lastComment.getCommentAuthorEmail());
@Override
public void run() {
//发送通知给对方
if(StringUtils.equals(HaloConst.OPTIONS.get("smtp_email_enable"),"true") && StringUtils.equals(HaloConst.OPTIONS.get("comment_reply_notice"),"true")) {
if(matcher.find()){
Map<String, Object> map = new HashMap<>();
map.put("blogTitle",HaloConst.OPTIONS.get("blog_title"));
map.put("commentAuthor",lastComment.getCommentAuthor());
map.put("pageName",lastComment.getPost().getPostTitle());
if (StringUtils.equals(post.getPostType(), HaloConst.POST_TYPE_POST)) {
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/archives/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
} else {
map.put("pageUrl", HaloConst.OPTIONS.get("blog_url") + "/p/" + post.getPostUrl() + "#comment-id-" + comment.getCommentId());
}
map.put("commentContent",lastComment.getCommentContent());
map.put("replyAuthor",comment.getCommentAuthor());
map.put("replyContent",comment.getCommentContent());
map.put("blogUrl",HaloConst.OPTIONS.get("blog_url"));
mailService.sendTemplateMail(
lastComment.getCommentAuthorEmail(),"您在"+HaloConst.OPTIONS.get("blog_title")+"的评论有了新回复",map,"common/mail/mail_reply.ftl");
}
}
}
return true;
}
}
......@@ -51,14 +51,18 @@
<td><a href="${comment.commentAuthorUrl}" target="_blank">${comment.commentAuthor}</a></td>
<td>${comment.commentContent}</td>
<td>
<a target="_blank" href="/archives/${comment.post.postUrl}">${comment.post.postTitle}</a>
<#if comment.post.postType == "post">
<a target="_blank" href="/archives/${comment.post.postUrl}">${comment.post.postTitle}</a>
<#else >
<a target="_blank" href="/p/${comment.post.postUrl}">${comment.post.postTitle}</a>
</#if>
</td>
<td>${comment.commentDate}</td>
<td>
<#switch comment.commentStatus>
<#case 0>
<button class="btn btn-primary btn-xs " onclick="replyShow('${comment.commentId?c}','${comment.post.postId?c}')" <#if comment.isAdmin==1>disabled</#if>>回复</button>
<button class="btn btn-danger btn-xs " onclick="modelShow('/admin/comments/throw?commentId=${comment.commentId}&status=1','确定移动到回收站?')">丢弃</button>
<button class="btn btn-danger btn-xs " onclick="modelShow('/admin/comments/throw?commentId=${comment.commentId?c}&status=1','确定移动到回收站?')">丢弃</button>
<#break >
<#case 1>
<a data-pjax="true" class="btn btn-primary btn-xs " href="/admin/comments/revert?commentId=${comment.commentId?c}&status=1">通过</a>
......
......@@ -229,7 +229,7 @@
<tr>
<th>评论者</th>
<th>评论页面</th>
<th>内容</th>
<th width="30%">内容</th>
<th>状态</th>
<th>时间</th>
</tr>
......@@ -240,7 +240,11 @@
<tr>
<td>${comment.commentAuthor}</td>
<td>
<a target="_blank" href="/archives/${comment.post.getPostUrl()}">${comment.post.postTitle}</a>
<#if comment.post.postType=="post">
<a target="_blank" href="/archives/${comment.post.getPostUrl()}">${comment.post.postTitle}</a>
<#else>
<a target="_blank" href="/p/${comment.post.getPostUrl()}">${comment.post.postTitle}</a>
</#if>
</td>
<td>
<#switch comment.commentStatus>
......
......@@ -265,7 +265,12 @@
</label>
</div>
</div>
<div class="form-group">
<label for="nativeCommentPlaceholder" class="col-sm-2 control-label">占位提示:</label>
<div class="col-sm-4">
<input type="url" class="form-control" id="nativeCommentPlaceholder" name="native_comment_placeholder" value="${options.native_comment_placeholder?default('赶快评论一个吧!')}">
</div>
</div>
<div class="form-group">
<label for="nativeCss" class="col-sm-2 control-label">自定义CSS:
<span data-toggle="tooltip" data-placement="top" title="对评论框自定义样式,如边距等" style="cursor: pointer">
......
<footer class="main-footer">
<div class="pull-right hidden-xs"><a target="_blank" href="https://github.com/ruibaby/halo">0.0.2</a></div>
<div class="pull-right hidden-xs"><a target="_blank" href="https://github.com/ruibaby/halo">0.0.3</a></div>
Thanks for using <strong><a data-pjax="true" href="/admin/halo">Halo</a>.</strong>
</footer>
\ No newline at end of file
......@@ -19,46 +19,63 @@
outline: none;
}
.comment-submit,.native-list-one-img,.native-list-one-footer-time,.native-list-one-footer-reback,.native-info,.native-nav,.ua{
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.comment-header {
width: 100%;
line-height: 1.8;
}
.comment-input-who, .comment-input-email, .comment-input-website {
width: 33.33%;
padding: 10px 0;
font-size: .8rem;
float: left;
border: none;
border-bottom: 1px dashed #dedede;
width: 33.33% !important;
padding: 10px 0 !important;
font-size: .9rem !important;
float: left !important;
border: none !important;
border-bottom: 1px dashed #dedede !important;
}
.comment-input:focus {
border-bottom: 1px dashed red;
border-bottom: 1px dashed red !important;
}
.comment-input-content {
width: 100%;
min-height: 120px;
resize: vertical;
border: none;
padding: 10px 0;
width: 100% !important;
min-height: 120px !important;
resize: vertical!important;
border: none!important;
font-size: .9rem !important;
padding: 10px 0!important;
}
.comment-footer {
text-align: right;
vertical-align: middle;
padding-top: 10px;
}
.comment-submit {
border-radius: 0;
vertical-align: middle;
padding: 7px 14px;
font-size: .9rem;
cursor: pointer;
border: 1px solid #ededed;
background: #ededed;
color: #313131;
border-radius: 0 !important;
vertical-align: middle!important;
padding: 7px 14px!important;
font-size: .9rem!important;
cursor: pointer!important;
border: 1px solid #ededed!important;
background: #ededed!important;
color: #313131!important;
transition: all .3s ease-in-out;
}
.comment-submit:hover{
background-color: #fff !important;
border-radius: 1.9rem !important;
border-color: #859cff !important;
color: #859cff !important;
}
.native-list {
......@@ -141,121 +158,100 @@
color: #ef2f11;
cursor: pointer;
}
.native-info{
padding-top: 10px;
font-size: 12px;
color: #555;
}
.native-load{
text-align: center;
.native-nav{
padding: 10px 0;
}
.native-load-btn{
.page-nav{
margin: 20px 0;
padding: 0 10px;
list-style: none;
text-align: center;
border: none;
border-radius: 25%;
}
.page-nav li{
display: inline-block;
}
${options.native_css?if_exists}
@media screen and (max-width: 560px) {
.comment-input-who, .comment-input-email, .comment-input-website {
width: 100%;
width: 100% !important;
}
}
</style>
<div class="native-comment">
<div class="native-wrap">
<div class="comment-header">
<input type="hidden" name="postId" value="${post.postId}">
<input type="text" class="comment-input comment-input-who" name="commentAuthor" id="commentAuthor"
placeholder="昵称">
<input type="text" class="comment-input comment-input-email" name="commentAuthorEmail" placeholder="邮箱">
<input type="text" class="comment-input comment-input-website" name="commentAuthorUrl"
placeholder="网址(https/http)">
<input type="hidden" name="postId" value="${post.postId?c}">
<input type="hidden" name="commentParent" id="commentParent" value="0">
<input type="text" class="comment-input comment-input-who" name="commentAuthor" id="commentAuthor" placeholder="昵称(必填)">
<input type="text" class="comment-input comment-input-email" name="commentAuthorEmail" placeholder="邮箱(选填)">
<input type="text" class="comment-input comment-input-website" name="commentAuthorUrl" placeholder="网址(选填)">
</div>
<div class="comment-content">
<textarea class="comment-input comment-input-content" name="commentContent" id="commentContent"
placeholder="come on"></textarea>
<textarea class="comment-input-content" name="commentContent" id="commentContent"
placeholder="${options.native_comment_placeholder?default('赶快评论一个吧!')}"></textarea>
</div>
<div class="comment-footer">
<button type="button" class="comment-submit" id="btn-push">提交</button>
</div>
</div>
<div class="native-info" style="padding-top: 5px;font-size: 12px;color: #0F192A;">
<span id="native-info-total">${comments.getTotalElements()}</span>评论
<div class="native-info">
<span id="native-info-total" style="font-weight: 600">${comments.getTotalElements()}</span>评论
</div>
<ul class="native-list">
<#list comments.content as comment>
<li class="native-list-one" id="comment-id-${comment.commentId}">
<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>
<#--<span class="ua"></span>-->
<#--<span class="ua"></span>-->
</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 rid="" at="@${comment.commentAuthor?if_exists}" class="native-list-one-footer-reback">回复</span>
<span at="${comment.commentId?c}" class="native-list-one-footer-reback">回复</span>
</div>
</section>
</li>
</#list>
</ul>
<#--<div class="loader" style="background-color: #0a001f">-->
<#--<div class="loader-inner ball-pulse-sync">-->
<#--<div></div>-->
<#--<div></div>-->
<#--<div></div>-->
<#--</div>-->
<#--</div>-->
<#--<div class="native-load">-->
<#--<button type="button" class="native-load-btn">加载更多</button>-->
<#--<div class="native-nav">-->
<#--<ol class="page-nav">-->
<#--<li>←</li>-->
<#--<li>1</li>-->
<#--<li>→</li>-->
<#--</ol>-->
<#--</div>-->
</div>
<script src="//cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
<script src="//cdn.bootcss.com/UAParser.js/0.7.17/ua-parser.min.js"></script>
<script>
<#--$(document).ready(function () {-->
<#--$.ajax({-->
<#--type: "get",-->
<#--async: true,-->
<#--url: "/getComment/${post.postId}",-->
<#--dataType: "json",-->
<#--success: function (data) {-->
<#--setTimeout(function () {-->
<#--$('.native-loading').hide();-->
<#--}, 1000);-->
<#--var parser = new UAParser();-->
<#--$.each(data, function (i, element) {-->
<#--parser.setUA(element.commentAgent);-->
<#--var result = parser.getResult();-->
<#--var browser = result.browser.name + ' ' + result.browser.version;-->
<#--var os = result.os.name + ' ' + result.os.version;-->
<#--var author = element.commentAuthor;-->
<#--var authorEmail = element.commentAuthorEmail;-->
<#--var authorUrl = element.commentAuthorUrl;-->
<#--var timestamp = element.commentDate;-->
<#--var date = new Date(timestamp).toLocaleDateString();-->
<#--var content = element.commentContent;-->
<#--var authorPic = md5(authorEmail);-->
<#--$('.native-list').append("<li class=\"native-list-one\"><img class=\"native-list-one-img\" src=\"//www.gravatar.com/avatar/" + authorPic + "?s=256&d=${options.native_comment_avatar?default('default')}\"><section><div class=\"native-list-one-head\"><a class=\"native-list-one-head-name\" rel=\"nofollow\" href=\"" + authorUrl + "\" target=\"_blank\">" + author + "</a> <span class=\"ua\">" + browser + "</span> <span class=\"ua\">" + os + "</span></div><div class=\"native-list-one-content\"><p>" + content + "</p></div><div class=\"native-list-one-footer\"><span class=\"native-list-one-footer-time\">" + date + "</span> <span rid=\"\" at=\"@" + author + "\" mail=\"" + authorEmail + "\" class=\"native-list-one-footer-reback\">回复</span></div></section></li>");-->
<#--});-->
<#--}-->
<#--});-->
<#--});-->
$(document).ready(function () {
$(".native-list-one-head").each(function (i) {
var uaInfo = $(this).children(".native-comment-ua-info").html();
$(this).append(show_ua(uaInfo));
});
});
$('#btn-push').click(function () {
var author = $("#commentAuthor");
if (author.val() == '') {
$(author).css("border-bottom", "1px dashed red");
return;
}
var content = $("#commentContent");
if (content.val() == '') {
$(content).css("border-bottom", "1px dashed red");
if (author.val() == '' || content.val() == '') {
return;
}
$(this).attr("disabled","disabled");
$(this).html("提交中...");
$.ajax({
type: 'POST',
url: '/newComment',
......@@ -267,7 +263,8 @@
'commentAuthorEmail': $('input[name=commentAuthorEmail]').val(),
'commentAuthorUrl': $('input[name=commentAuthorUrl]').val(),
'commentAgent': navigator.userAgent,
'commentAuthorAvatarMd5': md5($('input[name=commentAuthorEmail]').val())
'commentAuthorAvatarMd5': md5($('input[name=commentAuthorEmail]').val()),
'commentParent': $('input[name=commentParent]').val()
},
success: function (data) {
if (data == true) {
......@@ -276,4 +273,22 @@
}
});
});
$('.native-list-one-footer-reback').click(function () {
var at = $(this).attr("at");
var commentParentAuthor = $('#comment-id-'+at).find(".native-list-one-head-name").html();
$('#commentParent').val(at);
$('#commentContent').val("@"+commentParentAuthor+": ");
$('#commentContent').focus();
});
var parser = new UAParser();
function show_ua(string){
parser.setUA(string);
var uua = parser.getResult();
if(uua.os.version=='x86_64') {
uua.os.version = 'x64';
}
var browser = uua.browser.name+' '+uua.browser.version;
var os = uua.os.name + ' ' + uua.os.version;
return '<span class="ua">'+browser+'</span><span class="ua">'+os+'</span>';
}
</script>
\ No newline at end of file
src/main/resources/templates/themes/anatole/screenshot.png

193 KB | W: | H:

src/main/resources/templates/themes/anatole/screenshot.png

64.3 KB | W: | H:

src/main/resources/templates/themes/anatole/screenshot.png
src/main/resources/templates/themes/anatole/screenshot.png
src/main/resources/templates/themes/anatole/screenshot.png
src/main/resources/templates/themes/anatole/screenshot.png
  • 2-up
  • Swipe
  • Onion skin
src/main/resources/templates/themes/material/screenshot.png

539 KB | W: | H:

src/main/resources/templates/themes/material/screenshot.png

151 KB | W: | H:

src/main/resources/templates/themes/material/screenshot.png
src/main/resources/templates/themes/material/screenshot.png
src/main/resources/templates/themes/material/screenshot.png
src/main/resources/templates/themes/material/screenshot.png
  • 2-up
  • Swipe
  • Onion skin
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment