mirror of https://github.com/halo-dev/halo
Complete comment creation api
parent
ee2bc1c5ed
commit
42fced1c02
|
@ -103,6 +103,10 @@ public class Comment extends BaseEntity {
|
||||||
public void prePersist() {
|
public void prePersist() {
|
||||||
super.prePersist();
|
super.prePersist();
|
||||||
id = null;
|
id = null;
|
||||||
|
|
||||||
|
if (parentId == null || parentId < 0) {
|
||||||
|
parentId = 0L;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ public enum BlogProperties implements ValueEnum<String> {
|
||||||
private Class<?> type;
|
private Class<?> type;
|
||||||
|
|
||||||
BlogProperties(String value, Class<?> type) {
|
BlogProperties(String value, Class<?> type) {
|
||||||
if (!supportType(type)) {
|
if (!isSupportedType(type)) {
|
||||||
throw new IllegalArgumentException("Unsupported blog property type: " + type);
|
throw new IllegalArgumentException("Unsupported blog property type: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ public enum BlogProperties implements ValueEnum<String> {
|
||||||
public static <T> T convertTo(@NonNull String value, @NonNull Class<T> type) {
|
public static <T> T convertTo(@NonNull String value, @NonNull Class<T> type) {
|
||||||
Assert.hasText(value, "Property value must not be blank");
|
Assert.hasText(value, "Property value must not be blank");
|
||||||
|
|
||||||
if (!supportType(type)) {
|
if (!isSupportedType(type)) {
|
||||||
throw new IllegalArgumentException("Unsupported blog property type: " + type);
|
throw new IllegalArgumentException("Unsupported blog property type: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +245,7 @@ public enum BlogProperties implements ValueEnum<String> {
|
||||||
* @param type type to check
|
* @param type type to check
|
||||||
* @return true if supports; false else
|
* @return true if supports; false else
|
||||||
*/
|
*/
|
||||||
public static boolean supportType(Class<?> type) {
|
public static boolean isSupportedType(Class<?> type) {
|
||||||
return type != null && (
|
return type != null && (
|
||||||
type.isAssignableFrom(String.class)
|
type.isAssignableFrom(String.class)
|
||||||
|| type.isAssignableFrom(Number.class)
|
|| type.isAssignableFrom(Number.class)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package cc.ryanc.halo.service;
|
||||||
|
|
||||||
import cc.ryanc.halo.model.entity.Comment;
|
import cc.ryanc.halo.model.entity.Comment;
|
||||||
import cc.ryanc.halo.model.enums.CommentStatus;
|
import cc.ryanc.halo.model.enums.CommentStatus;
|
||||||
|
import cc.ryanc.halo.model.params.CommentParam;
|
||||||
import cc.ryanc.halo.model.vo.CommentVO;
|
import cc.ryanc.halo.model.vo.CommentVO;
|
||||||
import cc.ryanc.halo.service.base.CrudService;
|
import cc.ryanc.halo.service.base.CrudService;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
@ -9,6 +10,7 @@ import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -20,6 +22,13 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public interface CommentService extends CrudService<Comment, Long> {
|
public interface CommentService extends CrudService<Comment, Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* %d: parent commentator id
|
||||||
|
* %s: parent commentator author name
|
||||||
|
* %s: comment content
|
||||||
|
*/
|
||||||
|
String COMMENT_TEMPLATE = "<a href='#comment-id-%d>@%s</a> %s";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists latest comments.
|
* Lists latest comments.
|
||||||
*
|
*
|
||||||
|
@ -49,11 +58,21 @@ public interface CommentService extends CrudService<Comment, Long> {
|
||||||
List<Comment> listBy(@NonNull Integer postId);
|
List<Comment> listBy(@NonNull Integer postId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count by post id collection.
|
* Counts by post id collection.
|
||||||
*
|
*
|
||||||
* @param postIds post id collection
|
* @param postIds post id collection
|
||||||
* @return a count map, key: post id, value: comment count
|
* @return a count map, key: post id, value: comment count
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
Map<Integer, Long> countByPostIds(@Nullable Collection<Integer> postIds);
|
Map<Integer, Long> countByPostIds(@Nullable Collection<Integer> postIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a comment by comment param.
|
||||||
|
*
|
||||||
|
* @param commentParam comment param must not be null and should be validated
|
||||||
|
* @param request http servlet request must not be null
|
||||||
|
* @return created comment
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
Comment createBy(@NonNull CommentParam commentParam, @NonNull HttpServletRequest request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,35 @@
|
||||||
package cc.ryanc.halo.service.impl;
|
package cc.ryanc.halo.service.impl;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.exception.NotFoundException;
|
||||||
import cc.ryanc.halo.model.dto.post.PostMinimalOutputDTO;
|
import cc.ryanc.halo.model.dto.post.PostMinimalOutputDTO;
|
||||||
import cc.ryanc.halo.model.entity.Comment;
|
import cc.ryanc.halo.model.entity.Comment;
|
||||||
import cc.ryanc.halo.model.entity.Post;
|
import cc.ryanc.halo.model.entity.Post;
|
||||||
|
import cc.ryanc.halo.model.enums.BlogProperties;
|
||||||
import cc.ryanc.halo.model.enums.CommentStatus;
|
import cc.ryanc.halo.model.enums.CommentStatus;
|
||||||
|
import cc.ryanc.halo.model.params.CommentParam;
|
||||||
import cc.ryanc.halo.model.projection.CommentCountProjection;
|
import cc.ryanc.halo.model.projection.CommentCountProjection;
|
||||||
import cc.ryanc.halo.model.vo.CommentVO;
|
import cc.ryanc.halo.model.vo.CommentVO;
|
||||||
import cc.ryanc.halo.repository.CommentRepository;
|
import cc.ryanc.halo.repository.CommentRepository;
|
||||||
import cc.ryanc.halo.repository.PostRepository;
|
import cc.ryanc.halo.repository.PostRepository;
|
||||||
import cc.ryanc.halo.service.CommentService;
|
import cc.ryanc.halo.service.CommentService;
|
||||||
|
import cc.ryanc.halo.service.OptionService;
|
||||||
import cc.ryanc.halo.service.base.AbstractCrudService;
|
import cc.ryanc.halo.service.base.AbstractCrudService;
|
||||||
|
import cc.ryanc.halo.utils.OwoUtil;
|
||||||
import cc.ryanc.halo.utils.ServiceUtils;
|
import cc.ryanc.halo.utils.ServiceUtils;
|
||||||
|
import cn.hutool.core.util.URLUtil;
|
||||||
|
import cn.hutool.crypto.SecureUtil;
|
||||||
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.data.domain.*;
|
import org.springframework.data.domain.*;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.web.util.HtmlUtils;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -27,6 +39,7 @@ import java.util.stream.Collectors;
|
||||||
* @author : RYAN0UP
|
* @author : RYAN0UP
|
||||||
* @date : 2019-03-14
|
* @date : 2019-03-14
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class CommentServiceImpl extends AbstractCrudService<Comment, Long> implements CommentService {
|
public class CommentServiceImpl extends AbstractCrudService<Comment, Long> implements CommentService {
|
||||||
|
|
||||||
|
@ -34,11 +47,15 @@ public class CommentServiceImpl extends AbstractCrudService<Comment, Long> imple
|
||||||
|
|
||||||
private final PostRepository postRepository;
|
private final PostRepository postRepository;
|
||||||
|
|
||||||
|
private final OptionService optionService;
|
||||||
|
|
||||||
public CommentServiceImpl(CommentRepository commentRepository,
|
public CommentServiceImpl(CommentRepository commentRepository,
|
||||||
PostRepository postRepository) {
|
PostRepository postRepository,
|
||||||
|
OptionService optionService) {
|
||||||
super(commentRepository);
|
super(commentRepository);
|
||||||
this.commentRepository = commentRepository;
|
this.commentRepository = commentRepository;
|
||||||
this.postRepository = postRepository;
|
this.postRepository = postRepository;
|
||||||
|
this.optionService = optionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,6 +98,64 @@ public class CommentServiceImpl extends AbstractCrudService<Comment, Long> imple
|
||||||
return ServiceUtils.convertToMap(commentCountProjections, CommentCountProjection::getPostId, CommentCountProjection::getCount);
|
return ServiceUtils.convertToMap(commentCountProjections, CommentCountProjection::getPostId, CommentCountProjection::getCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Comment createBy(CommentParam commentParam, HttpServletRequest request) {
|
||||||
|
Assert.notNull(commentParam, "Comment param must not be null");
|
||||||
|
Assert.notNull(request, "Http servlet request must not be null");
|
||||||
|
|
||||||
|
// Post id must exist
|
||||||
|
boolean postExist = postRepository.existsById(commentParam.getPostId());
|
||||||
|
if (!postExist) {
|
||||||
|
log.error("Post: [{}] was not found", commentParam.getPostId());
|
||||||
|
throw new NotFoundException("The post was not found").setErrorData(commentParam.getPostId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to comment
|
||||||
|
Comment comment = commentParam.convertTo();
|
||||||
|
|
||||||
|
// Set some default value
|
||||||
|
comment.setIpAddress(ServletUtil.getClientIP(request));
|
||||||
|
// TODO Check user login status and set this field
|
||||||
|
comment.setIsAdmin(false);
|
||||||
|
comment.setAuthor(HtmlUtils.htmlEscape(comment.getAuthor()));
|
||||||
|
comment.setGavatarMd5(SecureUtil.md5(comment.getEmail()));
|
||||||
|
|
||||||
|
if (comment.getParentId() != null && comment.getParentId() > 0) {
|
||||||
|
// Validate the comment parent id
|
||||||
|
Comment parentComment = getById(comment.getParentId());
|
||||||
|
|
||||||
|
// Format content and set it
|
||||||
|
String formattedContent = String.format(COMMENT_TEMPLATE,
|
||||||
|
parentComment.getId(),
|
||||||
|
parentComment.getAuthor(),
|
||||||
|
OwoUtil.parseOwo(formatContent(comment.getContent())));
|
||||||
|
comment.setContent(formattedContent);
|
||||||
|
} else {
|
||||||
|
comment.setParentId(0L);
|
||||||
|
// Top comment
|
||||||
|
comment.setContent(OwoUtil.parseOwo(formatContent(comment.getContent())));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(comment.getAuthorUrl())) {
|
||||||
|
// Normalize the author url and set it
|
||||||
|
comment.setAuthorUrl(URLUtil.normalize(comment.getAuthorUrl()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle comment status
|
||||||
|
Boolean needAudit = optionService.getByProperty(BlogProperties.NEW_COMMENT_NEED_CHECK, Boolean.class, true);
|
||||||
|
if (needAudit) {
|
||||||
|
comment.setStatus(CommentStatus.AUDITING);
|
||||||
|
} else {
|
||||||
|
comment.setStatus(CommentStatus.PUBLISHED);
|
||||||
|
}
|
||||||
|
|
||||||
|
Comment createdComment = create(comment);
|
||||||
|
|
||||||
|
// TODO Handle email sending
|
||||||
|
|
||||||
|
return createdComment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts to comment vo page.
|
* Converts to comment vo page.
|
||||||
*
|
*
|
||||||
|
@ -122,4 +197,9 @@ public class CommentServiceImpl extends AbstractCrudService<Comment, Long> imple
|
||||||
return commentVO;
|
return commentVO;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String formatContent(@NonNull String content) {
|
||||||
|
return HtmlUtils.htmlEscape(content).replace("<br/>", "<br/>");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
package cc.ryanc.halo.web.controller.admin.api;
|
package cc.ryanc.halo.web.controller.admin.api;
|
||||||
|
|
||||||
import cc.ryanc.halo.model.dto.CommentOutputDTO;
|
import cc.ryanc.halo.model.dto.CommentOutputDTO;
|
||||||
import cc.ryanc.halo.model.entity.Comment;
|
|
||||||
import cc.ryanc.halo.model.enums.BlogProperties;
|
|
||||||
import cc.ryanc.halo.model.enums.CommentStatus;
|
import cc.ryanc.halo.model.enums.CommentStatus;
|
||||||
import cc.ryanc.halo.model.params.CommentParam;
|
import cc.ryanc.halo.model.params.CommentParam;
|
||||||
import cc.ryanc.halo.model.support.HaloConst;
|
|
||||||
import cc.ryanc.halo.model.vo.CommentVO;
|
import cc.ryanc.halo.model.vo.CommentVO;
|
||||||
import cc.ryanc.halo.service.CommentService;
|
import cc.ryanc.halo.service.CommentService;
|
||||||
import cc.ryanc.halo.utils.HaloUtils;
|
import cc.ryanc.halo.service.OptionService;
|
||||||
import cn.hutool.crypto.SecureUtil;
|
import cc.ryanc.halo.service.PostService;
|
||||||
import cn.hutool.extra.servlet.ServletUtil;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.web.PageableDefault;
|
import org.springframework.data.web.PageableDefault;
|
||||||
import org.springframework.web.bind.ServletRequestUtils;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -36,8 +31,16 @@ public class CommentController {
|
||||||
|
|
||||||
private final CommentService commentService;
|
private final CommentService commentService;
|
||||||
|
|
||||||
public CommentController(CommentService commentService) {
|
private final PostService postService;
|
||||||
|
|
||||||
|
private final OptionService optionService;
|
||||||
|
|
||||||
|
public CommentController(CommentService commentService,
|
||||||
|
PostService postService,
|
||||||
|
OptionService optionService) {
|
||||||
this.commentService = commentService;
|
this.commentService = commentService;
|
||||||
|
this.postService = postService;
|
||||||
|
this.optionService = optionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("latest")
|
@GetMapping("latest")
|
||||||
|
@ -54,14 +57,6 @@ public class CommentController {
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public CommentOutputDTO createBy(@Valid @RequestBody CommentParam commentParam, HttpServletRequest request) {
|
public CommentOutputDTO createBy(@Valid @RequestBody CommentParam commentParam, HttpServletRequest request) {
|
||||||
Comment comment = commentParam.convertTo();
|
return new CommentOutputDTO().convertFrom(commentService.createBy(commentParam, request));
|
||||||
|
|
||||||
// Set some default value
|
|
||||||
comment.setGavatarMd5(SecureUtil.md5(comment.getEmail()));
|
|
||||||
comment.setIpAddress(ServletUtil.getClientIP(request));
|
|
||||||
|
|
||||||
|
|
||||||
// commentService.createBy(comment)
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue