mirror of https://github.com/halo-dev/halo
Refactor repo, service related comment
parent
511b952b00
commit
e77d5449d0
|
@ -37,19 +37,22 @@ public class CommentController {
|
|||
@ApiOperation("Lists comments")
|
||||
public Page<CommentWithPostVO> pageBy(@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable,
|
||||
CommentQuery commentQuery) {
|
||||
return commentService.pageBy(commentQuery, pageable);
|
||||
Page<Comment> commentPage = commentService.pageBy(commentQuery, pageable);
|
||||
return commentService.convertToWithPostVo(commentPage);
|
||||
}
|
||||
|
||||
@GetMapping("latest")
|
||||
@ApiOperation("Pages latest comments")
|
||||
public List<CommentWithPostVO> pageLatest(@RequestParam(name = "top", defaultValue = "10") int top) {
|
||||
return commentService.pageLatest(top).getContent();
|
||||
List<Comment> content = commentService.pageLatest(top).getContent();
|
||||
return commentService.convertToWithPostVo(content);
|
||||
}
|
||||
|
||||
@GetMapping("status/{status}")
|
||||
public Page<CommentWithPostVO> pageBy(@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable,
|
||||
@PathVariable("status") CommentStatus status) {
|
||||
return commentService.pageBy(status, pageable);
|
||||
Page<Comment> commentPage = commentService.pageBy(status, pageable);
|
||||
return commentService.convertToWithPostVo(commentPage);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
|
|
|
@ -17,7 +17,7 @@ import run.halo.app.model.entity.Category;
|
|||
import run.halo.app.model.entity.Post;
|
||||
import run.halo.app.model.entity.Tag;
|
||||
import run.halo.app.model.enums.PostStatus;
|
||||
import run.halo.app.model.vo.CommentVO;
|
||||
import run.halo.app.model.vo.BaseCommentVO;
|
||||
import run.halo.app.model.vo.PostListVO;
|
||||
import run.halo.app.service.*;
|
||||
|
||||
|
@ -116,7 +116,7 @@ public class ContentArchiveController {
|
|||
List<Category> categories = postCategoryService.listCategoryBy(post.getId());
|
||||
List<Tag> tags = postTagService.listTagsBy(post.getId());
|
||||
|
||||
Page<CommentVO> comments = commentService.pageVosBy(post.getId(), PageRequest.of(cp, optionService.getCommentPageSize(), sort));
|
||||
Page<BaseCommentVO> comments = commentService.pageVosBy(post.getId(), PageRequest.of(cp, optionService.getCommentPageSize(), sort));
|
||||
final int[] pageRainbow = PageUtil.rainbow(cp, comments.getTotalPages(), 3);
|
||||
|
||||
model.addAttribute("is_post", true);
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
package run.halo.app.controller.content.api;
|
||||
|
||||
import run.halo.app.model.dto.post.PostDetailDTO;
|
||||
import run.halo.app.model.dto.post.PostSimpleDTO;
|
||||
import run.halo.app.model.enums.PostStatus;
|
||||
import run.halo.app.model.vo.CommentVO;
|
||||
import run.halo.app.model.vo.CommentWithParentVO;
|
||||
import run.halo.app.service.CommentService;
|
||||
import run.halo.app.service.OptionService;
|
||||
import run.halo.app.service.PostService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
@ -16,6 +8,14 @@ import org.springframework.data.domain.Sort;
|
|||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.data.web.SortDefault;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import run.halo.app.model.dto.post.PostDetailDTO;
|
||||
import run.halo.app.model.dto.post.PostSimpleDTO;
|
||||
import run.halo.app.model.enums.PostStatus;
|
||||
import run.halo.app.model.vo.BaseCommentVO;
|
||||
import run.halo.app.model.vo.BaseCommentWithParentVO;
|
||||
import run.halo.app.service.CommentService;
|
||||
import run.halo.app.service.OptionService;
|
||||
import run.halo.app.service.PostService;
|
||||
|
||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||
|
||||
|
@ -71,17 +71,17 @@ public class PostController {
|
|||
|
||||
@GetMapping("{postId:\\d+}/comments/tree_view")
|
||||
@ApiOperation("Lists comments with tree view")
|
||||
public Page<CommentVO> listCommentsTree(@PathVariable("postId") Integer postId,
|
||||
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
|
||||
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
|
||||
public Page<BaseCommentVO> listCommentsTree(@PathVariable("postId") Integer postId,
|
||||
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
|
||||
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
|
||||
return commentService.pageVosBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
|
||||
}
|
||||
|
||||
@GetMapping("{postId:\\d+}/comments/list_view")
|
||||
@ApiOperation("Lists comment with list view")
|
||||
public Page<CommentWithParentVO> listComments(@PathVariable("postId") Integer postId,
|
||||
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
|
||||
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
|
||||
public Page<BaseCommentWithParentVO> listComments(@PathVariable("postId") Integer postId,
|
||||
@RequestParam(name = "page", required = false, defaultValue = "0") int page,
|
||||
@SortDefault(sort = "createTime", direction = DESC) Sort sort) {
|
||||
return commentService.pageWithParentVoBy(postId, PageRequest.of(page, optionService.getCommentPageSize(), sort));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package run.halo.app.model.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import run.halo.app.model.dto.base.OutputConverter;
|
||||
import run.halo.app.model.entity.BaseComment;
|
||||
import run.halo.app.model.enums.CommentStatus;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Base comment output dto.
|
||||
*
|
||||
* @author johnniang
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class BaseCommentDTO implements OutputConverter<BaseCommentDTO, BaseComment> {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String author;
|
||||
|
||||
private String email;
|
||||
|
||||
private String ipAddress;
|
||||
|
||||
private String gavatarMd5;
|
||||
|
||||
private String content;
|
||||
|
||||
private CommentStatus status;
|
||||
|
||||
private String userAgent;
|
||||
|
||||
private Long parentId;
|
||||
|
||||
private Boolean isAdmin;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -1,14 +1,9 @@
|
|||
package run.halo.app.model.dto;
|
||||
|
||||
import run.halo.app.model.dto.base.OutputConverter;
|
||||
import run.halo.app.model.entity.Comment;
|
||||
import run.halo.app.model.enums.CommentStatus;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Comment output dto.
|
||||
*
|
||||
|
@ -17,28 +12,6 @@ import java.util.Date;
|
|||
@Data
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
public class CommentDTO implements OutputConverter<CommentDTO, Comment> {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String author;
|
||||
|
||||
private String email;
|
||||
|
||||
private String ipAddress;
|
||||
|
||||
private String gavatarMd5;
|
||||
|
||||
private String content;
|
||||
|
||||
private CommentStatus status;
|
||||
|
||||
private String userAgent;
|
||||
|
||||
private Long parentId;
|
||||
|
||||
private Boolean isAdmin;
|
||||
|
||||
private Date createTime;
|
||||
public class CommentDTO extends BaseCommentDTO {
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package run.halo.app.model.dto;
|
||||
|
||||
/**
|
||||
* Journal dto.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 19-4-24
|
||||
*/
|
||||
public class JournalDTO extends BaseCommentDTO {
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package run.halo.app.model.dto.post;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* Sheet list dto.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 19-4-24
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SheetListDTO extends SheetSimpleDTO {
|
||||
|
||||
private Long commentCount;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package run.halo.app.model.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import run.halo.app.model.dto.BaseCommentDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base comment vo.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 19-4-24
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class BaseCommentVO extends BaseCommentDTO {
|
||||
|
||||
List<BaseCommentVO> children;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package run.halo.app.model.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import run.halo.app.model.dto.BaseCommentDTO;
|
||||
|
||||
/**
|
||||
* Base comment with parent comment vo.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 3/31/19
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Slf4j
|
||||
public class BaseCommentWithParentVO extends BaseCommentDTO implements Cloneable {
|
||||
|
||||
/**
|
||||
* Parent comment.
|
||||
*/
|
||||
private BaseCommentWithParentVO parent;
|
||||
|
||||
public BaseCommentWithParentVO clone() {
|
||||
try {
|
||||
return (BaseCommentWithParentVO) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
log.error("Clone not support exception", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package run.halo.app.model.vo;
|
||||
|
||||
import run.halo.app.model.dto.CommentDTO;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import run.halo.app.model.dto.CommentDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -14,6 +14,7 @@ import java.util.List;
|
|||
*/
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@Deprecated
|
||||
public class CommentVO extends CommentDTO {
|
||||
|
||||
private List<CommentVO> children;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package run.halo.app.model.vo;
|
||||
|
||||
import run.halo.app.model.dto.CommentDTO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import run.halo.app.model.dto.CommentDTO;
|
||||
|
||||
/**
|
||||
* Comment list with parent comment vo.
|
||||
|
@ -16,6 +16,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Slf4j
|
||||
@Deprecated
|
||||
public class CommentWithParentVO extends CommentDTO implements Cloneable {
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
package run.halo.app.repository;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.lang.NonNull;
|
||||
import run.halo.app.model.entity.Comment;
|
||||
import run.halo.app.model.enums.CommentStatus;
|
||||
import run.halo.app.model.projection.CommentCountProjection;
|
||||
import run.halo.app.repository.base.BaseCommentRepository;
|
||||
|
||||
|
@ -19,50 +16,9 @@ import java.util.List;
|
|||
*/
|
||||
public interface CommentRepository extends BaseCommentRepository<Comment> {
|
||||
|
||||
/**
|
||||
* Finds all comments by post ids.
|
||||
*
|
||||
* @param postIds post ids must not be null
|
||||
* @return a list of comment
|
||||
*/
|
||||
@NonNull
|
||||
List<Comment> findAllByPostIdIn(@NonNull Iterable<Integer> postIds);
|
||||
|
||||
/**
|
||||
* Finds all comments by post id.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @return a list of comment
|
||||
*/
|
||||
@NonNull
|
||||
List<Comment> findAllByPostId(@NonNull Integer postId);
|
||||
|
||||
/**
|
||||
* Counts comment count by post id collection.
|
||||
*
|
||||
* @param postIds post id collection must not be null
|
||||
* @return a list of comment count
|
||||
*/
|
||||
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from Comment comment where comment.postId in ?1 group by comment.postId")
|
||||
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from BaseComment comment where comment.postId in ?1 group by comment.postId")
|
||||
@NonNull
|
||||
@Override
|
||||
List<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> postIds);
|
||||
|
||||
/**
|
||||
* Finds comments by post id, comment status.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @param status comment status must not be null
|
||||
* @return a list of comment
|
||||
*/
|
||||
List<Comment> findAllByPostIdAndStatus(Integer postId, CommentStatus status);
|
||||
|
||||
/**
|
||||
* Finds comments by post id, comment status.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @param status comment status must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment
|
||||
*/
|
||||
Page<Comment> findAllByPostIdAndStatus(Integer postId, CommentStatus status, Pageable pageable);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package run.halo.app.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.lang.NonNull;
|
||||
import run.halo.app.model.entity.Journal;
|
||||
import run.halo.app.model.projection.CommentCountProjection;
|
||||
import run.halo.app.repository.base.BaseCommentRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Journal repository.
|
||||
*
|
||||
|
@ -11,4 +16,13 @@ import run.halo.app.repository.base.BaseCommentRepository;
|
|||
*/
|
||||
public interface JournalRepository extends BaseCommentRepository<Journal> {
|
||||
|
||||
/**
|
||||
* Counts comment count by post id collection.
|
||||
*
|
||||
* @param postIds post id collection must not be null
|
||||
* @return a list of comment count
|
||||
*/
|
||||
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from Journal comment where comment.postId in ?1 group by comment.postId")
|
||||
@NonNull
|
||||
List<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> postIds);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
package run.halo.app.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.lang.NonNull;
|
||||
import run.halo.app.model.entity.SheetComment;
|
||||
import run.halo.app.model.projection.CommentCountProjection;
|
||||
import run.halo.app.repository.base.BaseCommentRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sheet comment repository.
|
||||
*
|
||||
|
@ -11,4 +16,8 @@ import run.halo.app.repository.base.BaseCommentRepository;
|
|||
*/
|
||||
public interface SheetCommentRepository extends BaseCommentRepository<SheetComment> {
|
||||
|
||||
@Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from SheetComment comment where comment.postId in ?1 group by comment.postId")
|
||||
@NonNull
|
||||
@Override
|
||||
List<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> postIds);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,14 @@ package run.halo.app.repository.base;
|
|||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.repository.NoRepositoryBean;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import run.halo.app.model.entity.BaseComment;
|
||||
import run.halo.app.model.enums.CommentStatus;
|
||||
import run.halo.app.model.projection.CommentCountProjection;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base comment repository.
|
||||
|
@ -14,7 +18,8 @@ import run.halo.app.model.enums.CommentStatus;
|
|||
* @author johnniang
|
||||
* @date 19-4-24
|
||||
*/
|
||||
public interface BaseCommentRepository<DOMAIN extends BaseComment> extends BaseRepository<DOMAIN, Long>, JpaSpecificationExecutor<DOMAIN> {
|
||||
@NoRepositoryBean
|
||||
public interface BaseCommentRepository<COMMENT extends BaseComment> extends BaseRepository<COMMENT, Long>, JpaSpecificationExecutor<COMMENT> {
|
||||
|
||||
/**
|
||||
* Finds all comments by status.
|
||||
|
@ -24,7 +29,55 @@ public interface BaseCommentRepository<DOMAIN extends BaseComment> extends BaseR
|
|||
* @return a page of comment
|
||||
*/
|
||||
@NonNull
|
||||
Page<DOMAIN> findAllByStatus(@Nullable CommentStatus status, @NonNull Pageable pageable);
|
||||
Page<COMMENT> findAllByStatus(@Nullable CommentStatus status, @NonNull Pageable pageable);
|
||||
|
||||
|
||||
/**
|
||||
* Finds all comments by post ids.
|
||||
*
|
||||
* @param postIds post ids must not be null
|
||||
* @return a list of comment
|
||||
*/
|
||||
@NonNull
|
||||
List<COMMENT> findAllByPostIdIn(@NonNull Iterable<Integer> postIds);
|
||||
|
||||
/**
|
||||
* Finds all comments by post id.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @return a list of comment
|
||||
*/
|
||||
@NonNull
|
||||
List<COMMENT> findAllByPostId(@NonNull Integer postId);
|
||||
|
||||
/**
|
||||
* Counts comment count by post id collection.
|
||||
*
|
||||
* @param postIds post id collection must not be null
|
||||
* @return a list of comment count
|
||||
*/
|
||||
// @Query("select new run.halo.app.model.projection.CommentCountProjection(count(comment.id), comment.postId) from BaseComment comment where comment.postId in ?1 group by comment.postId")
|
||||
@NonNull
|
||||
List<CommentCountProjection> countByPostIds(@NonNull Iterable<Integer> postIds);
|
||||
|
||||
/**
|
||||
* Finds comments by post id, comment status.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @param status comment status must not be null
|
||||
* @return a list of comment
|
||||
*/
|
||||
@NonNull
|
||||
List<COMMENT> findAllByPostIdAndStatus(Integer postId, CommentStatus status);
|
||||
|
||||
/**
|
||||
* Finds comments by post id, comment status.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @param status comment status must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment
|
||||
*/
|
||||
@NonNull
|
||||
Page<COMMENT> findAllByPostIdAndStatus(Integer postId, CommentStatus status, Pageable pageable);
|
||||
}
|
||||
|
|
|
@ -1,82 +1,21 @@
|
|||
package run.halo.app.service;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import run.halo.app.model.entity.Comment;
|
||||
import run.halo.app.model.enums.CommentStatus;
|
||||
import run.halo.app.model.params.CommentParam;
|
||||
import run.halo.app.model.params.CommentQuery;
|
||||
import run.halo.app.model.vo.CommentVO;
|
||||
import run.halo.app.model.vo.CommentWithParentVO;
|
||||
import run.halo.app.model.vo.CommentWithPostVO;
|
||||
import run.halo.app.service.base.CrudService;
|
||||
import run.halo.app.service.base.BaseCommentService;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Comment service.
|
||||
*
|
||||
* @author johnniang
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param top top number must not be less than 0
|
||||
* @return a page of comments
|
||||
*/
|
||||
@NonNull
|
||||
Page<CommentWithPostVO> pageLatest(int top);
|
||||
|
||||
/**
|
||||
* Pages comments.
|
||||
*
|
||||
* @param status comment status must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment
|
||||
*/
|
||||
@NonNull
|
||||
Page<CommentWithPostVO> pageBy(@NonNull CommentStatus status, @NonNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Pages comments.
|
||||
*
|
||||
* @param commentQuery comment query must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment
|
||||
*/
|
||||
@NonNull
|
||||
Page<CommentWithPostVO> pageBy(@NonNull CommentQuery commentQuery, @NonNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Lists comments by post id.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @return a list of comment
|
||||
*/
|
||||
@NonNull
|
||||
List<Comment> listBy(@NonNull Integer postId);
|
||||
|
||||
/**
|
||||
* Counts by post id collection.
|
||||
*
|
||||
* @param postIds post id collection
|
||||
* @return a count map, key: post id, value: comment count
|
||||
*/
|
||||
@NonNull
|
||||
Map<Integer, Long> countByPostIds(@Nullable Collection<Integer> postIds);
|
||||
public interface CommentService extends BaseCommentService<Comment> {
|
||||
|
||||
/**
|
||||
* Creates a comment by comment param.
|
||||
|
@ -88,32 +27,20 @@ public interface CommentService extends CrudService<Comment, Long> {
|
|||
Comment createBy(@NonNull CommentParam commentParam);
|
||||
|
||||
/**
|
||||
* Lists comment vos by post id.
|
||||
* Converts to with post vo.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment vo
|
||||
* @param commentPage comment page must not be null
|
||||
* @return a page of comment with post vo
|
||||
*/
|
||||
@NonNull
|
||||
Page<CommentVO> pageVosBy(@NonNull Integer postId, @NonNull Pageable pageable);
|
||||
Page<CommentWithPostVO> convertToWithPostVo(@NonNull Page<Comment> commentPage);
|
||||
|
||||
/**
|
||||
* Lists comment with parent vo.
|
||||
* Converts to with post vo
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment with parent vo.
|
||||
* @param comments comment list
|
||||
* @return a list of comment with post vo
|
||||
*/
|
||||
@NonNull
|
||||
Page<CommentWithParentVO> pageWithParentVoBy(@NonNull Integer postId, @NonNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Updates comment status.
|
||||
*
|
||||
* @param commentId comment id must not be null
|
||||
* @param status comment status must not be null
|
||||
* @return updated comment
|
||||
*/
|
||||
@NonNull
|
||||
Comment updateStatus(@NonNull Long commentId, @NonNull CommentStatus status);
|
||||
List<CommentWithPostVO> convertToWithPostVo(@Nullable List<Comment> comments);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.springframework.data.domain.Page;
|
|||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.lang.NonNull;
|
||||
import run.halo.app.model.dto.post.SheetDetailDTO;
|
||||
import run.halo.app.model.dto.post.SheetListDTO;
|
||||
import run.halo.app.model.entity.Sheet;
|
||||
import run.halo.app.model.enums.PostStatus;
|
||||
import run.halo.app.service.base.CrudService;
|
||||
|
@ -61,4 +62,13 @@ public interface SheetService extends CrudService<Sheet, Integer> {
|
|||
*/
|
||||
@NonNull
|
||||
Sheet getBy(@NonNull PostStatus status, @NonNull String url);
|
||||
|
||||
/**
|
||||
* Converts to list dto page.
|
||||
*
|
||||
* @param sheetPage sheet page must not be nulls
|
||||
* @return a page of sheet list dto
|
||||
*/
|
||||
@NonNull
|
||||
Page<SheetListDTO> convertToListDto(@NonNull Page<Sheet> sheetPage);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
package run.halo.app.service.base;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import run.halo.app.model.entity.BaseComment;
|
||||
import run.halo.app.model.enums.CommentStatus;
|
||||
import run.halo.app.model.params.CommentQuery;
|
||||
import run.halo.app.model.vo.BaseCommentVO;
|
||||
import run.halo.app.model.vo.BaseCommentWithParentVO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Base comment service interface.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 19-4-24
|
||||
*/
|
||||
public interface BaseCommentService<COMMENT extends BaseComment> extends CrudService<COMMENT, Long> {
|
||||
|
||||
/**
|
||||
* %d: parent commentator id
|
||||
* %s: parent commentator author name
|
||||
* %s: comment content
|
||||
*/
|
||||
@Deprecated
|
||||
String COMMENT_TEMPLATE = "<a href='#comment-id-%d'>@%s</a> %s";
|
||||
|
||||
/**
|
||||
* Lists comments by post id.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @return a list of comment
|
||||
*/
|
||||
@NonNull
|
||||
List<COMMENT> listBy(@NonNull Integer postId);
|
||||
|
||||
/**
|
||||
* Lists latest comments.
|
||||
*
|
||||
* @param top top number must not be less than 0
|
||||
* @return a page of comments
|
||||
*/
|
||||
@NonNull
|
||||
Page<COMMENT> pageLatest(int top);
|
||||
|
||||
/**
|
||||
* Pages comments.
|
||||
*
|
||||
* @param status comment status must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment
|
||||
*/
|
||||
@NonNull
|
||||
Page<COMMENT> pageBy(@NonNull CommentStatus status, @NonNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Pages comments.
|
||||
*
|
||||
* @param commentQuery comment query must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment
|
||||
*/
|
||||
@NonNull
|
||||
Page<COMMENT> pageBy(@NonNull CommentQuery commentQuery, @NonNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Lists comment vos by post id.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment vo
|
||||
*/
|
||||
@NonNull
|
||||
Page<BaseCommentVO> pageVosBy(@NonNull Integer postId, @NonNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Lists comment with parent vo.
|
||||
*
|
||||
* @param postId post id must not be null
|
||||
* @param pageable page info must not be null
|
||||
* @return a page of comment with parent vo.
|
||||
*/
|
||||
@NonNull
|
||||
Page<BaseCommentWithParentVO> pageWithParentVoBy(@NonNull Integer postId, @NonNull Pageable pageable);
|
||||
|
||||
/**
|
||||
* Counts by post id collection.
|
||||
*
|
||||
* @param postIds post id collection
|
||||
* @return a count map, key: post id, value: comment count
|
||||
*/
|
||||
@NonNull
|
||||
Map<Integer, Long> countByPostIds(@Nullable Collection<Integer> postIds);
|
||||
|
||||
/**
|
||||
* Creates a comment by comment param.
|
||||
*
|
||||
* @param COMMENT comment must not be null
|
||||
* @return created comment
|
||||
*/
|
||||
@NonNull
|
||||
COMMENT createBy(@NonNull COMMENT COMMENT);
|
||||
|
||||
/**
|
||||
* Updates comment status.
|
||||
*
|
||||
* @param commentId comment id must not be null
|
||||
* @param status comment status must not be null
|
||||
* @return updated comment
|
||||
*/
|
||||
@NonNull
|
||||
COMMENT updateStatus(@NonNull Long commentId, @NonNull CommentStatus status);
|
||||
}
|
|
@ -0,0 +1,386 @@
|
|||
package run.halo.app.service.base;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import run.halo.app.event.comment.CommentNewEvent;
|
||||
import run.halo.app.event.comment.CommentPassEvent;
|
||||
import run.halo.app.event.comment.CommentReplyEvent;
|
||||
import run.halo.app.exception.NotFoundException;
|
||||
import run.halo.app.model.entity.BaseComment;
|
||||
import run.halo.app.model.enums.CommentStatus;
|
||||
import run.halo.app.model.params.CommentQuery;
|
||||
import run.halo.app.model.projection.CommentCountProjection;
|
||||
import run.halo.app.model.properties.CommentProperties;
|
||||
import run.halo.app.model.support.CommentPage;
|
||||
import run.halo.app.model.vo.BaseCommentVO;
|
||||
import run.halo.app.model.vo.BaseCommentWithParentVO;
|
||||
import run.halo.app.model.vo.CommentWithParentVO;
|
||||
import run.halo.app.repository.PostRepository;
|
||||
import run.halo.app.repository.base.BaseCommentRepository;
|
||||
import run.halo.app.security.authentication.Authentication;
|
||||
import run.halo.app.security.context.SecurityContextHolder;
|
||||
import run.halo.app.service.OptionService;
|
||||
import run.halo.app.utils.ServiceUtils;
|
||||
import run.halo.app.utils.ServletUtils;
|
||||
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Base comment service implementation.
|
||||
*
|
||||
* @author johnniang
|
||||
* @date 19-4-24
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseCommentServiceImpl<COMMENT extends BaseComment> extends AbstractCrudService<COMMENT, Long> implements BaseCommentService<COMMENT> {
|
||||
|
||||
private final BaseCommentRepository<COMMENT> baseCommentRepository;
|
||||
|
||||
protected final PostRepository postRepository;
|
||||
|
||||
protected final OptionService optionService;
|
||||
|
||||
protected final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public BaseCommentServiceImpl(BaseCommentRepository<COMMENT> baseCommentRepository,
|
||||
PostRepository postRepository,
|
||||
OptionService optionService,
|
||||
ApplicationEventPublisher eventPublisher) {
|
||||
super(baseCommentRepository);
|
||||
this.baseCommentRepository = baseCommentRepository;
|
||||
this.postRepository = postRepository;
|
||||
this.optionService = optionService;
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<COMMENT> listBy(Integer postId) {
|
||||
Assert.notNull(postId, "Post id must not be null");
|
||||
|
||||
return baseCommentRepository.findAllByPostId(postId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<COMMENT> pageLatest(int top) {
|
||||
Assert.isTrue(top > 0, "Top number must not be less than 0");
|
||||
|
||||
// Build page request
|
||||
PageRequest latestPageable = PageRequest.of(0, top, Sort.by(Sort.Direction.DESC, "createTime"));
|
||||
|
||||
return listAll(latestPageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<COMMENT> pageBy(CommentStatus status, Pageable pageable) {
|
||||
|
||||
Assert.notNull(status, "Comment status must not be null");
|
||||
Assert.notNull(pageable, "Page info must not be null");
|
||||
|
||||
// Find all
|
||||
return baseCommentRepository.findAllByStatus(status, pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<COMMENT> pageBy(CommentQuery commentQuery, Pageable pageable) {
|
||||
Assert.notNull(pageable, "Page info must not be null");
|
||||
|
||||
return baseCommentRepository.findAll(buildSpecByQuery(commentQuery), pageable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BaseCommentVO> pageVosBy(Integer postId, Pageable pageable) {
|
||||
Assert.notNull(postId, "Post id must not be null");
|
||||
Assert.notNull(pageable, "Page info must not be null");
|
||||
|
||||
log.debug("Getting comment tree view of post: [{}], page info: [{}]", postId, pageable);
|
||||
|
||||
// List all the top comments (Caution: This list will be cleared)
|
||||
List<COMMENT> comments = baseCommentRepository.findAllByPostIdAndStatus(postId, CommentStatus.PUBLISHED);
|
||||
|
||||
// Init the top virtual comment
|
||||
BaseCommentVO topVirtualComment = new BaseCommentVO();
|
||||
topVirtualComment.setId(0L);
|
||||
topVirtualComment.setChildren(new LinkedList<>());
|
||||
|
||||
Comparator<BaseCommentVO> commentVOComparator = buildCommentComparator(pageable.getSortOr(Sort.by(Sort.Direction.DESC, "createTime")));
|
||||
|
||||
// Concrete the comment tree
|
||||
concreteTree(topVirtualComment, new LinkedList<>(comments), commentVOComparator);
|
||||
|
||||
List<BaseCommentVO> topComments = topVirtualComment.getChildren();
|
||||
|
||||
List<BaseCommentVO> pageContent;
|
||||
|
||||
// Calc the shear index
|
||||
int startIndex = pageable.getPageNumber() * pageable.getPageSize();
|
||||
if (startIndex >= topComments.size() || startIndex < 0) {
|
||||
pageContent = Collections.emptyList();
|
||||
} else {
|
||||
int endIndex = startIndex + pageable.getPageSize();
|
||||
if (endIndex > topComments.size()) {
|
||||
endIndex = topComments.size();
|
||||
}
|
||||
|
||||
log.debug("Top comments size: [{}]", topComments.size());
|
||||
log.debug("Start index: [{}]", startIndex);
|
||||
log.debug("End index: [{}]", endIndex);
|
||||
|
||||
pageContent = topComments.subList(startIndex, endIndex);
|
||||
}
|
||||
|
||||
return new CommentPage<>(pageContent, pageable, topComments.size(), comments.size());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<BaseCommentWithParentVO> pageWithParentVoBy(Integer postId, Pageable pageable) {
|
||||
Assert.notNull(postId, "Post id must not be null");
|
||||
Assert.notNull(pageable, "Page info must not be null");
|
||||
|
||||
log.debug("Getting comment list view of post: [{}], page info: [{}]", postId, pageable);
|
||||
|
||||
// List all the top comments (Caution: This list will be cleared)
|
||||
Page<COMMENT> commentPage = baseCommentRepository.findAllByPostIdAndStatus(postId, CommentStatus.PUBLISHED, pageable);
|
||||
|
||||
// Get all comments
|
||||
List<COMMENT> comments = commentPage.getContent();
|
||||
|
||||
// Get all comment parent ids
|
||||
Set<Long> parentIds = ServiceUtils.fetchProperty(comments, COMMENT::getParentId);
|
||||
|
||||
// Get all parent comments
|
||||
List<COMMENT> parentComments = baseCommentRepository.findAllByIdIn(parentIds, pageable.getSort());
|
||||
|
||||
// Convert to comment map (Key: comment id, value: comment)
|
||||
Map<Long, COMMENT> parentCommentMap = ServiceUtils.convertToMap(parentComments, COMMENT::getId);
|
||||
|
||||
Map<Long, BaseCommentWithParentVO> parentCommentVoMap = new HashMap<>(parentCommentMap.size());
|
||||
|
||||
// Convert to comment page
|
||||
return commentPage.map(comment -> {
|
||||
// Convert to with parent vo
|
||||
BaseCommentWithParentVO commentWithParentVO = new BaseCommentWithParentVO().convertFrom(comment);
|
||||
|
||||
// Get parent comment vo from cache
|
||||
BaseCommentWithParentVO parentCommentVo = parentCommentVoMap.get(comment.getParentId());
|
||||
|
||||
if (parentCommentVo == null) {
|
||||
// Get parent comment
|
||||
COMMENT parentComment = parentCommentMap.get(comment.getParentId());
|
||||
|
||||
if (parentComment != null) {
|
||||
// Convert to parent comment vo
|
||||
parentCommentVo = new CommentWithParentVO().convertFrom(parentComment);
|
||||
// Cache the parent comment vo
|
||||
parentCommentVoMap.put(parentComment.getId(), parentCommentVo);
|
||||
}
|
||||
}
|
||||
|
||||
// Set parent
|
||||
commentWithParentVO.setParent(parentCommentVo == null ? null : parentCommentVo.clone());
|
||||
|
||||
return commentWithParentVO;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Long> countByPostIds(Collection<Integer> postIds) {
|
||||
if (CollectionUtils.isEmpty(postIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
// Get all comment counts
|
||||
List<CommentCountProjection> commentCountProjections = baseCommentRepository.countByPostIds(postIds);
|
||||
|
||||
return ServiceUtils.convertToMap(commentCountProjections, CommentCountProjection::getPostId, CommentCountProjection::getCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public COMMENT createBy(COMMENT COMMENT) {
|
||||
Assert.notNull(COMMENT, "Domain must not be null");
|
||||
|
||||
// Check post id
|
||||
boolean isPostExist = postRepository.existsById(COMMENT.getPostId());
|
||||
if (!isPostExist) {
|
||||
throw new NotFoundException("The post with id " + COMMENT.getPostId() + " was not found");
|
||||
}
|
||||
|
||||
// Check parent id
|
||||
if (!ServiceUtils.isEmptyId(COMMENT.getParentId())) {
|
||||
mustExistById(COMMENT.getParentId());
|
||||
}
|
||||
|
||||
// Check user login status and set this field
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
// Set some default values
|
||||
COMMENT.setIpAddress(ServletUtils.getRequestIp());
|
||||
COMMENT.setUserAgent(ServletUtils.getHeaderIgnoreCase(HttpHeaders.USER_AGENT));
|
||||
COMMENT.setGavatarMd5(DigestUtils.md5Hex(COMMENT.getEmail()));
|
||||
|
||||
if (authentication != null) {
|
||||
// Comment of blogger
|
||||
COMMENT.setIsAdmin(true);
|
||||
COMMENT.setStatus(CommentStatus.PUBLISHED);
|
||||
} else {
|
||||
// Comment of guest
|
||||
// Handle comment status
|
||||
Boolean needAudit = optionService.getByPropertyOrDefault(CommentProperties.NEW_NEED_CHECK, Boolean.class, true);
|
||||
COMMENT.setStatus(needAudit ? CommentStatus.AUDITING : CommentStatus.PUBLISHED);
|
||||
}
|
||||
|
||||
// Create comment
|
||||
COMMENT createdComment = create(COMMENT);
|
||||
|
||||
if (ServiceUtils.isEmptyId(createdComment.getParentId())) {
|
||||
if (authentication == null) {
|
||||
// New comment of guest
|
||||
eventPublisher.publishEvent(new CommentNewEvent(this, createdComment.getId()));
|
||||
}
|
||||
} else {
|
||||
// Reply comment
|
||||
eventPublisher.publishEvent(new CommentReplyEvent(this, createdComment.getId()));
|
||||
}
|
||||
|
||||
return createdComment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public COMMENT updateStatus(Long commentId, CommentStatus status) {
|
||||
Assert.notNull(commentId, "Comment id must not be null");
|
||||
Assert.notNull(status, "Comment status must not be null");
|
||||
|
||||
// Get comment by id
|
||||
COMMENT comment = getById(commentId);
|
||||
|
||||
// Set comment status
|
||||
comment.setStatus(status);
|
||||
|
||||
// Update comment
|
||||
COMMENT updatedComment = update(comment);
|
||||
|
||||
if (CommentStatus.PUBLISHED.equals(status)) {
|
||||
// Pass a comment
|
||||
eventPublisher.publishEvent(new CommentPassEvent(this, commentId));
|
||||
}
|
||||
|
||||
return updatedComment;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Specification<COMMENT> buildSpecByQuery(@NonNull CommentQuery commentQuery) {
|
||||
Assert.notNull(commentQuery, "Comment query must not be null");
|
||||
|
||||
return (Specification<COMMENT>) (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> predicates = new LinkedList<>();
|
||||
|
||||
if (commentQuery.getStatus() != null) {
|
||||
predicates.add(criteriaBuilder.equal(root.get("status"), commentQuery.getStatus()));
|
||||
}
|
||||
|
||||
if (commentQuery.getKeyword() != null) {
|
||||
|
||||
String likeCondition = String.format("%%%s%%", StringUtils.strip(commentQuery.getKeyword()));
|
||||
|
||||
Predicate authorLike = criteriaBuilder.like(root.get("author"), likeCondition);
|
||||
Predicate contentLike = criteriaBuilder.like(root.get("content"), likeCondition);
|
||||
Predicate emailLike = criteriaBuilder.like(root.get("email"), likeCondition);
|
||||
|
||||
predicates.add(criteriaBuilder.or(authorLike, contentLike, emailLike));
|
||||
}
|
||||
|
||||
return query.where(predicates.toArray(new Predicate[0])).getRestriction();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a comment comparator.
|
||||
*
|
||||
* @param sort sort info
|
||||
* @return comment comparator
|
||||
*/
|
||||
private Comparator<BaseCommentVO> buildCommentComparator(Sort sort) {
|
||||
return (currentComment, toCompareComment) -> {
|
||||
Assert.notNull(currentComment, "Current comment must not be null");
|
||||
Assert.notNull(toCompareComment, "Comment to compare must not be null");
|
||||
|
||||
// Get sort order
|
||||
Sort.Order order = sort.filter(anOrder -> anOrder.getProperty().equals("createTime"))
|
||||
.get()
|
||||
.findFirst()
|
||||
.orElseGet(() -> Sort.Order.desc("createTime"));
|
||||
|
||||
// Init sign
|
||||
int sign = order.getDirection().isAscending() ? 1 : -1;
|
||||
|
||||
// Compare createTime property
|
||||
return sign * currentComment.getCreateTime().compareTo(toCompareComment.getCreateTime());
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Concretes comment tree.
|
||||
*
|
||||
* @param parentComment parent comment vo must not be null
|
||||
* @param comments comment list must not null
|
||||
* @param commentComparator comment vo comparator
|
||||
*/
|
||||
private void concreteTree(@NonNull BaseCommentVO parentComment,
|
||||
@Nullable Collection<COMMENT> comments,
|
||||
@NonNull Comparator<BaseCommentVO> commentComparator) {
|
||||
Assert.notNull(parentComment, "Parent comment must not be null");
|
||||
Assert.notNull(commentComparator, "Comment comparator must not be null");
|
||||
|
||||
if (CollectionUtils.isEmpty(comments)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<COMMENT> children = new LinkedList<>();
|
||||
|
||||
comments.forEach(comment -> {
|
||||
if (parentComment.getId().equals(comment.getParentId())) {
|
||||
// Stage the child comment
|
||||
children.add(comment);
|
||||
|
||||
// Convert to comment vo
|
||||
BaseCommentVO commentVO = new BaseCommentVO().convertFrom(comment);
|
||||
|
||||
// Add additional content
|
||||
if (commentVO.getParentId() > 0) {
|
||||
// TODO Provide an optional additional content
|
||||
commentVO.setContent(String.format(COMMENT_TEMPLATE, parentComment.getId(), parentComment.getAuthor(), commentVO.getContent()));
|
||||
}
|
||||
|
||||
// Init children container
|
||||
if (parentComment.getChildren() == null) {
|
||||
parentComment.setChildren(new LinkedList<>());
|
||||
}
|
||||
|
||||
parentComment.getChildren().add(commentVO);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove all children
|
||||
comments.removeAll(children);
|
||||
|
||||
if (!CollectionUtils.isEmpty(parentComment.getChildren())) {
|
||||
// Recursively concrete the children
|
||||
parentComment.getChildren().forEach(childComment -> concreteTree(childComment, comments, commentComparator));
|
||||
// Sort the children
|
||||
parentComment.getChildren().sort(commentComparator);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +1,19 @@
|
|||
package run.halo.app.service.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.*;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
import run.halo.app.event.comment.CommentNewEvent;
|
||||
import run.halo.app.event.comment.CommentPassEvent;
|
||||
import run.halo.app.event.comment.CommentReplyEvent;
|
||||
import run.halo.app.exception.NotFoundException;
|
||||
import run.halo.app.model.dto.post.PostMinimalDTO;
|
||||
import run.halo.app.model.entity.Comment;
|
||||
import run.halo.app.model.entity.Post;
|
||||
import run.halo.app.model.entity.User;
|
||||
import run.halo.app.model.enums.CommentStatus;
|
||||
import run.halo.app.model.params.CommentParam;
|
||||
import run.halo.app.model.params.CommentQuery;
|
||||
import run.halo.app.model.projection.CommentCountProjection;
|
||||
import run.halo.app.model.properties.BlogProperties;
|
||||
import run.halo.app.model.properties.CommentProperties;
|
||||
import run.halo.app.model.support.CommentPage;
|
||||
import run.halo.app.model.vo.CommentVO;
|
||||
import run.halo.app.model.vo.CommentWithParentVO;
|
||||
import run.halo.app.model.vo.CommentWithPostVO;
|
||||
import run.halo.app.repository.CommentRepository;
|
||||
import run.halo.app.repository.PostRepository;
|
||||
|
@ -38,13 +21,14 @@ import run.halo.app.security.authentication.Authentication;
|
|||
import run.halo.app.security.context.SecurityContextHolder;
|
||||
import run.halo.app.service.CommentService;
|
||||
import run.halo.app.service.OptionService;
|
||||
import run.halo.app.service.base.AbstractCrudService;
|
||||
import run.halo.app.service.base.BaseCommentServiceImpl;
|
||||
import run.halo.app.utils.ServiceUtils;
|
||||
import run.halo.app.utils.ServletUtils;
|
||||
import run.halo.app.utils.ValidationUtils;
|
||||
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -55,99 +39,16 @@ import java.util.stream.Collectors;
|
|||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CommentServiceImpl extends AbstractCrudService<Comment, Long> implements CommentService {
|
||||
public class CommentServiceImpl extends BaseCommentServiceImpl<Comment> implements CommentService {
|
||||
|
||||
private final CommentRepository commentRepository;
|
||||
|
||||
private final PostRepository postRepository;
|
||||
|
||||
private final OptionService optionService;
|
||||
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public CommentServiceImpl(CommentRepository commentRepository,
|
||||
PostRepository postRepository,
|
||||
OptionService optionService,
|
||||
ApplicationEventPublisher eventPublisher) {
|
||||
super(commentRepository);
|
||||
super(commentRepository, postRepository, optionService, eventPublisher);
|
||||
this.commentRepository = commentRepository;
|
||||
this.postRepository = postRepository;
|
||||
this.optionService = optionService;
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<CommentWithPostVO> pageLatest(int top) {
|
||||
Assert.isTrue(top > 0, "Top number must not be less than 0");
|
||||
|
||||
// Build page request
|
||||
PageRequest latestPageable = PageRequest.of(0, top, Sort.by(Sort.Direction.DESC, "createTime"));
|
||||
|
||||
return convertBy(listAll(latestPageable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<CommentWithPostVO> pageBy(CommentStatus status, Pageable pageable) {
|
||||
Assert.notNull(status, "Comment status must not be null");
|
||||
Assert.notNull(pageable, "Page info must not be null");
|
||||
|
||||
// Find all
|
||||
Page<Comment> commentPage = commentRepository.findAllByStatus(status, pageable);
|
||||
|
||||
return convertBy(commentPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<CommentWithPostVO> pageBy(CommentQuery commentQuery, Pageable pageable) {
|
||||
Assert.notNull(commentQuery, "Comment query must not be null");
|
||||
Assert.notNull(pageable, "Page info must not be null");
|
||||
Page<Comment> commentPage = commentRepository.findAll(buildSpecByQuery(commentQuery), pageable);
|
||||
return convertBy(commentPage);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Specification<Comment> buildSpecByQuery(@NonNull CommentQuery commentQuery) {
|
||||
Assert.notNull(commentQuery, "Comment query must not be null");
|
||||
|
||||
return (Specification<Comment>) (root, query, criteriaBuilder) -> {
|
||||
List<Predicate> predicates = new LinkedList<>();
|
||||
|
||||
if (commentQuery.getStatus() != null) {
|
||||
predicates.add(criteriaBuilder.equal(root.get("status"), commentQuery.getStatus()));
|
||||
}
|
||||
|
||||
if (commentQuery.getKeyword() != null) {
|
||||
|
||||
String likeCondition = String.format("%%%s%%", StringUtils.strip(commentQuery.getKeyword()));
|
||||
|
||||
Predicate authorLike = criteriaBuilder.like(root.get("author"), likeCondition);
|
||||
Predicate contentLike = criteriaBuilder.like(root.get("content"), likeCondition);
|
||||
Predicate emailLike = criteriaBuilder.like(root.get("email"), likeCondition);
|
||||
|
||||
predicates.add(criteriaBuilder.or(authorLike, contentLike, emailLike));
|
||||
}
|
||||
|
||||
return query.where(predicates.toArray(new Predicate[0])).getRestriction();
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Comment> listBy(Integer postId) {
|
||||
Assert.notNull(postId, "Post id must not be null");
|
||||
|
||||
return commentRepository.findAllByPostId(postId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, Long> countByPostIds(Collection<Integer> postIds) {
|
||||
if (CollectionUtils.isEmpty(postIds)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
// Get all comment counts
|
||||
List<CommentCountProjection> commentCountProjections = commentRepository.countByPostIds(postIds);
|
||||
|
||||
return ServiceUtils.convertToMap(commentCountProjections, CommentCountProjection::getPostId, CommentCountProjection::getCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -167,264 +68,20 @@ public class CommentServiceImpl extends AbstractCrudService<Comment, Long> imple
|
|||
// Validate the comment param manually
|
||||
ValidationUtils.validate(commentParam);
|
||||
|
||||
// Check post id
|
||||
boolean isPostExist = postRepository.existsById(commentParam.getPostId());
|
||||
if (!isPostExist) {
|
||||
throw new NotFoundException("The post with id " + commentParam.getPostId() + " was not found");
|
||||
}
|
||||
|
||||
// Check parent id
|
||||
if (!ServiceUtils.isEmptyId(commentParam.getParentId())) {
|
||||
mustExistById(commentParam.getParentId());
|
||||
}
|
||||
|
||||
// Convert to comment
|
||||
Comment comment = commentParam.convertTo();
|
||||
|
||||
// Set some default values
|
||||
comment.setIpAddress(ServletUtils.getRequestIp());
|
||||
comment.setUserAgent(ServletUtils.getHeaderIgnoreCase(HttpHeaders.USER_AGENT));
|
||||
comment.setGavatarMd5(DigestUtils.md5Hex(comment.getEmail()));
|
||||
|
||||
if (authentication != null) {
|
||||
// Comment of blogger
|
||||
comment.setIsAdmin(true);
|
||||
comment.setStatus(CommentStatus.PUBLISHED);
|
||||
} else {
|
||||
// Comment of guest
|
||||
// Handle comment status
|
||||
Boolean needAudit = optionService.getByPropertyOrDefault(CommentProperties.NEW_NEED_CHECK, Boolean.class, true);
|
||||
comment.setStatus(needAudit ? CommentStatus.AUDITING : CommentStatus.PUBLISHED);
|
||||
}
|
||||
|
||||
// Create comment
|
||||
Comment createdComment = create(comment);
|
||||
|
||||
if (ServiceUtils.isEmptyId(createdComment.getParentId())) {
|
||||
if (authentication == null) {
|
||||
// New comment of guest
|
||||
eventPublisher.publishEvent(new CommentNewEvent(this, createdComment.getId()));
|
||||
}
|
||||
} else {
|
||||
// Reply comment
|
||||
eventPublisher.publishEvent(new CommentReplyEvent(this, createdComment.getId()));
|
||||
}
|
||||
|
||||
return createdComment;
|
||||
return createBy(commentParam.convertTo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<CommentVO> pageVosBy(Integer postId, Pageable pageable) {
|
||||
Assert.notNull(postId, "Post id must not be null");
|
||||
Assert.notNull(pageable, "Page info must not be null");
|
||||
|
||||
log.debug("Getting comment tree view of post: [{}], page info: [{}]", postId, pageable);
|
||||
|
||||
// List all the top comments (Caution: This list will be cleared)
|
||||
List<Comment> comments = commentRepository.findAllByPostIdAndStatus(postId, CommentStatus.PUBLISHED);
|
||||
|
||||
// Init the top virtual comment
|
||||
CommentVO topVirtualComment = new CommentVO();
|
||||
topVirtualComment.setId(0L);
|
||||
topVirtualComment.setChildren(new LinkedList<>());
|
||||
|
||||
// Concrete the comment tree
|
||||
concreteTree(topVirtualComment, new LinkedList<>(comments), buildCommentComparator(pageable.getSortOr(Sort.by(Sort.Direction.DESC, "createTime"))));
|
||||
|
||||
List<CommentVO> topComments = topVirtualComment.getChildren();
|
||||
|
||||
List<CommentVO> pageContent;
|
||||
|
||||
// Calc the shear index
|
||||
int startIndex = pageable.getPageNumber() * pageable.getPageSize();
|
||||
if (startIndex >= topComments.size() || startIndex < 0) {
|
||||
pageContent = Collections.emptyList();
|
||||
} else {
|
||||
int endIndex = startIndex + pageable.getPageSize();
|
||||
if (endIndex > topComments.size()) {
|
||||
endIndex = topComments.size();
|
||||
}
|
||||
|
||||
log.debug("Top comments size: [{}]", topComments.size());
|
||||
log.debug("Start index: [{}]", startIndex);
|
||||
log.debug("End index: [{}]", endIndex);
|
||||
|
||||
pageContent = topComments.subList(startIndex, endIndex);
|
||||
}
|
||||
|
||||
return new CommentPage<>(pageContent, pageable, topComments.size(), comments.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<CommentWithParentVO> pageWithParentVoBy(Integer postId, Pageable pageable) {
|
||||
Assert.notNull(postId, "Post id must not be null");
|
||||
Assert.notNull(pageable, "Page info must not be null");
|
||||
|
||||
log.debug("Getting comment list view of post: [{}], page info: [{}]", postId, pageable);
|
||||
|
||||
// List all the top comments (Caution: This list will be cleared)
|
||||
Page<Comment> commentPage = commentRepository.findAllByPostIdAndStatus(postId, CommentStatus.PUBLISHED, pageable);
|
||||
|
||||
// Get all comments
|
||||
List<Comment> comments = commentPage.getContent();
|
||||
|
||||
// Get all comment parent ids
|
||||
Set<Long> parentIds = ServiceUtils.fetchProperty(comments, Comment::getParentId);
|
||||
|
||||
// Get all parent comments
|
||||
List<Comment> parentComments = commentRepository.findAllByIdIn(parentIds, pageable.getSort());
|
||||
|
||||
// Convert to comment map (Key: comment id, value: comment)
|
||||
Map<Long, Comment> parentCommentMap = ServiceUtils.convertToMap(parentComments, Comment::getId);
|
||||
|
||||
Map<Long, CommentWithParentVO> parentCommentVoMap = new HashMap<>(parentCommentMap.size());
|
||||
|
||||
// Convert to comment page
|
||||
return commentPage.map(comment -> {
|
||||
// Convert to with parent vo
|
||||
CommentWithParentVO commentWithParentVO = new CommentWithParentVO().convertFrom(comment);
|
||||
|
||||
// Get parent comment vo from cache
|
||||
CommentWithParentVO parentCommentVo = parentCommentVoMap.get(comment.getParentId());
|
||||
|
||||
if (parentCommentVo == null) {
|
||||
// Get parent comment
|
||||
Comment parentComment = parentCommentMap.get(comment.getParentId());
|
||||
|
||||
if (parentComment != null) {
|
||||
// Convert to parent comment vo
|
||||
parentCommentVo = new CommentWithParentVO().convertFrom(parentComment);
|
||||
// Cache the parent comment vo
|
||||
parentCommentVoMap.put(parentComment.getId(), parentCommentVo);
|
||||
}
|
||||
}
|
||||
|
||||
// Set parent
|
||||
commentWithParentVO.setParent(parentCommentVo == null ? null : parentCommentVo.clone());
|
||||
|
||||
return commentWithParentVO;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comment updateStatus(Long commentId, CommentStatus status) {
|
||||
Assert.notNull(commentId, "Comment id must not be null");
|
||||
Assert.notNull(status, "Comment status must not be null");
|
||||
|
||||
// Get comment by id
|
||||
Comment comment = getById(commentId);
|
||||
|
||||
// Set comment status
|
||||
comment.setStatus(status);
|
||||
|
||||
// Update comment
|
||||
Comment updatedComment = update(comment);
|
||||
|
||||
if (CommentStatus.PUBLISHED.equals(status)) {
|
||||
// Pass a comment
|
||||
eventPublisher.publishEvent(new CommentPassEvent(this, commentId));
|
||||
}
|
||||
|
||||
return updatedComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a comment comparator.
|
||||
*
|
||||
* @param sort sort info
|
||||
* @return comment comparator
|
||||
*/
|
||||
private Comparator<CommentVO> buildCommentComparator(Sort sort) {
|
||||
return (currentComment, toCompareComment) -> {
|
||||
Assert.notNull(currentComment, "Current comment must not be null");
|
||||
Assert.notNull(toCompareComment, "Comment to compare must not be null");
|
||||
|
||||
// Get sort order
|
||||
Order order = sort.filter(anOrder -> anOrder.getProperty().equals("createTime"))
|
||||
.get()
|
||||
.findFirst()
|
||||
.orElseGet(() -> Order.desc("createTime"));
|
||||
|
||||
// Init sign
|
||||
int sign = order.getDirection().isAscending() ? 1 : -1;
|
||||
|
||||
// Compare createTime property
|
||||
return sign * currentComment.getCreateTime().compareTo(toCompareComment.getCreateTime());
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Concretes comment tree.
|
||||
*
|
||||
* @param parentComment parent comment vo must not be null
|
||||
* @param comments comment list must not null
|
||||
* @param commentComparator comment vo comparator
|
||||
*/
|
||||
private void concreteTree(@NonNull CommentVO parentComment, Collection<Comment> comments, @NonNull Comparator<CommentVO> commentComparator) {
|
||||
Assert.notNull(parentComment, "Parent comment must not be null");
|
||||
Assert.notNull(commentComparator, "Comment comparator must not be null");
|
||||
|
||||
if (CollectionUtils.isEmpty(comments)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Comment> children = new LinkedList<>();
|
||||
|
||||
comments.forEach(comment -> {
|
||||
if (parentComment.getId().equals(comment.getParentId())) {
|
||||
// Stage the child comment
|
||||
children.add(comment);
|
||||
|
||||
// Convert to comment vo
|
||||
CommentVO commentVO = new CommentVO().convertFrom(comment);
|
||||
|
||||
// Add additional content
|
||||
if (commentVO.getParentId() > 0) {
|
||||
// TODO Provide an optional additional content
|
||||
commentVO.setContent(String.format(COMMENT_TEMPLATE, parentComment.getId(), parentComment.getAuthor(), commentVO.getContent()));
|
||||
}
|
||||
|
||||
// Init children container
|
||||
if (parentComment.getChildren() == null) {
|
||||
parentComment.setChildren(new LinkedList<>());
|
||||
}
|
||||
|
||||
parentComment.getChildren().add(commentVO);
|
||||
}
|
||||
});
|
||||
|
||||
// Remove all children
|
||||
comments.removeAll(children);
|
||||
|
||||
if (!CollectionUtils.isEmpty(parentComment.getChildren())) {
|
||||
// Recursively concrete the children
|
||||
parentComment.getChildren().forEach(childComment -> concreteTree(childComment, comments, commentComparator));
|
||||
// Sort the children
|
||||
parentComment.getChildren().sort(commentComparator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to comment vo page.
|
||||
*
|
||||
* @param commentPage comment page must not be null
|
||||
* @return a page of comment vo
|
||||
*/
|
||||
@NonNull
|
||||
private Page<CommentWithPostVO> convertBy(@NonNull Page<Comment> commentPage) {
|
||||
public Page<CommentWithPostVO> convertToWithPostVo(Page<Comment> commentPage) {
|
||||
Assert.notNull(commentPage, "Comment page must not be null");
|
||||
|
||||
return new PageImpl<>(convertBy(commentPage.getContent()), commentPage.getPageable(), commentPage.getTotalElements());
|
||||
return new PageImpl<>(convertToWithPostVo(commentPage.getContent()), commentPage.getPageable(), commentPage.getTotalElements());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to comment vo list.
|
||||
*
|
||||
* @param comments comment list
|
||||
* @return a list of comment vo
|
||||
*/
|
||||
@NonNull
|
||||
private List<CommentWithPostVO> convertBy(@Nullable List<Comment> comments) {
|
||||
@Override
|
||||
public List<CommentWithPostVO> convertToWithPostVo(List<Comment> comments) {
|
||||
if (CollectionUtils.isEmpty(comments)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -446,8 +103,4 @@ public class CommentServiceImpl extends AbstractCrudService<Comment, Long> imple
|
|||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String formatContent(@NonNull String content) {
|
||||
return HtmlUtils.htmlEscape(content).replace("<br/>", "<br/>");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package run.halo.app.service.impl;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import run.halo.app.model.entity.SheetComment;
|
||||
import run.halo.app.repository.SheetCommentRepository;
|
||||
import run.halo.app.service.SheetCommentService;
|
||||
|
@ -11,6 +12,7 @@ import run.halo.app.service.base.AbstractCrudService;
|
|||
* @author johnniang
|
||||
* @date 19-4-24
|
||||
*/
|
||||
@Service
|
||||
public class SheetCommentServiceImpl extends AbstractCrudService<SheetComment, Long> implements SheetCommentService {
|
||||
|
||||
private final SheetCommentRepository sheetCommentRepository;
|
||||
|
|
|
@ -10,10 +10,12 @@ import run.halo.app.event.post.VisitEvent;
|
|||
import run.halo.app.exception.AlreadyExistsException;
|
||||
import run.halo.app.exception.NotFoundException;
|
||||
import run.halo.app.model.dto.post.SheetDetailDTO;
|
||||
import run.halo.app.model.dto.post.SheetListDTO;
|
||||
import run.halo.app.model.entity.Post;
|
||||
import run.halo.app.model.entity.Sheet;
|
||||
import run.halo.app.model.enums.PostStatus;
|
||||
import run.halo.app.repository.SheetRepository;
|
||||
import run.halo.app.service.SheetCommentService;
|
||||
import run.halo.app.service.SheetService;
|
||||
import run.halo.app.service.base.AbstractCrudService;
|
||||
import run.halo.app.utils.DateUtils;
|
||||
|
@ -22,6 +24,9 @@ import run.halo.app.utils.ServiceUtils;
|
|||
|
||||
import java.util.Optional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Sheet service implementation.
|
||||
*
|
||||
|
@ -36,9 +41,14 @@ public class SheetServiceImpl extends AbstractCrudService<Sheet, Integer> implem
|
|||
|
||||
public SheetServiceImpl(SheetRepository sheetRepository,
|
||||
ApplicationEventPublisher eventPublisher) {
|
||||
private final SheetCommentService sheetCommentService;
|
||||
|
||||
public SheetServiceImpl(SheetRepository sheetRepository,
|
||||
SheetCommentService sheetCommentService) {
|
||||
super(sheetRepository);
|
||||
this.sheetRepository = sheetRepository;
|
||||
this.eventPublisher = eventPublisher;
|
||||
this.sheetCommentService = sheetCommentService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -90,6 +100,21 @@ public class SheetServiceImpl extends AbstractCrudService<Sheet, Integer> implem
|
|||
return new SheetDetailDTO().convertFrom(sheet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<SheetListDTO> convertToListDto(Page<Sheet> sheetPage) {
|
||||
Assert.notNull(sheetPage, "Sheet page must not be null");
|
||||
|
||||
// Get all sheet id
|
||||
List<Sheet> sheets = sheetPage.getContent();
|
||||
|
||||
Set<Integer> sheetIds = ServiceUtils.fetchProperty(sheets, Sheet::getId);
|
||||
|
||||
|
||||
return sheetPage.map(sheet -> {
|
||||
return new SheetListDTO().convertFrom(sheet);
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Sheet createOrUpdateBy(@NonNull Sheet sheet) {
|
||||
Assert.notNull(sheet, "Sheet must not be null");
|
||||
|
|
Loading…
Reference in New Issue