Complete post query api

pull/146/head
johnniang 2019-04-10 16:52:40 +08:00
parent 4b486ae099
commit 3d8579cb13
4 changed files with 127 additions and 12 deletions

View File

@ -0,0 +1,30 @@
package run.halo.app.model.params;
import lombok.Data;
import run.halo.app.model.enums.PostStatus;
/**
* Post query.
*
* @author johnniang
* @date 4/10/19
*/
@Data
public class PostQuery {
/**
* Keyword.
*/
private String keyword;
/**
* Post status.
*/
private PostStatus status;
/**
* Category id.
*/
private Integer categoryId;
}

View File

@ -1,18 +1,18 @@
package run.halo.app.service;
import run.halo.app.model.dto.post.PostMinimalOutputDTO;
import run.halo.app.model.dto.post.PostSimpleOutputDTO;
import run.halo.app.model.entity.Post;
import run.halo.app.model.enums.PostStatus;
import run.halo.app.model.vo.ArchiveMonthVO;
import run.halo.app.model.vo.ArchiveYearVO;
import run.halo.app.model.vo.PostDetailVO;
import run.halo.app.model.vo.PostListVO;
import run.halo.app.service.base.CrudService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.lang.NonNull;
import org.springframework.transaction.annotation.Transactional;
import run.halo.app.model.dto.post.PostMinimalOutputDTO;
import run.halo.app.model.dto.post.PostSimpleOutputDTO;
import run.halo.app.model.entity.Post;
import run.halo.app.model.enums.PostStatus;
import run.halo.app.model.params.PostQuery;
import run.halo.app.model.vo.ArchiveMonthVO;
import run.halo.app.model.vo.ArchiveYearVO;
import run.halo.app.model.vo.PostDetailVO;
import run.halo.app.model.vo.PostListVO;
import run.halo.app.service.base.CrudService;
import java.util.List;
@ -56,18 +56,28 @@ public interface PostService extends CrudService<Post, Integer> {
Page<Post> pageLatest(int top);
/**
* List by status and type
* Lists by status and type
*
* @param status post status must not be null
* @param pageable page info must not be null
* @return Page<PostSimpleOutputDTO>
* @return a page of post
*/
@NonNull
Page<Post> pageBy(@NonNull PostStatus status, @NonNull Pageable pageable);
/**
* Pages posts.
*
* @param postQuery post query must not be null
* @param pageable page info must not be null
* @return a page of post
*/
@NonNull
Page<Post> pageBy(@NonNull PostQuery postQuery, @NonNull Pageable pageable);
/**
* List simple output dto by status and type
* Lists simple output dto by status and type
*
* @param status post status must not be null
* @param pageable page info must not be null
@ -165,4 +175,13 @@ public interface PostService extends CrudService<Post, Integer> {
*/
@NonNull
List<ArchiveMonthVO> listMonthArchives();
/**
* Converts to a page of post simple output dto.
*
* @param postPage post page must not be null
* @return a page of post simple output dto
*/
@NonNull
Page<PostSimpleOutputDTO> convertTo(@NonNull Page<Post> postPage);
}

View File

@ -1,10 +1,12 @@
package run.halo.app.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
@ -19,6 +21,7 @@ import run.halo.app.model.dto.post.PostMinimalOutputDTO;
import run.halo.app.model.dto.post.PostSimpleOutputDTO;
import run.halo.app.model.entity.*;
import run.halo.app.model.enums.PostStatus;
import run.halo.app.model.params.PostQuery;
import run.halo.app.model.vo.ArchiveMonthVO;
import run.halo.app.model.vo.ArchiveYearVO;
import run.halo.app.model.vo.PostDetailVO;
@ -30,6 +33,9 @@ import run.halo.app.utils.DateUtils;
import run.halo.app.utils.MarkdownUtils;
import run.halo.app.utils.ServiceUtils;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
@ -101,6 +107,50 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
return postRepository.findAllByStatus(status, pageable);
}
@Override
public Page<Post> pageBy(PostQuery postQuery, Pageable pageable) {
Assert.notNull(postQuery, "Post query must not be null");
Assert.notNull(pageable, "Page info must not be null");
// Build specification and find all
return postRepository.findAll(buildSpecByQuery(postQuery), pageable);
}
private Specification<Post> buildSpecByQuery(@NonNull PostQuery postQuery) {
Assert.notNull(postQuery, "Post query must not be null");
return (Specification<Post>) (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new LinkedList<>();
if (postQuery.getStatus() != null) {
predicates.add(criteriaBuilder.equal(root.get("status"), postQuery.getStatus()));
}
if (postQuery.getCategoryId() != null) {
Subquery<Post> postSubquery = query.subquery(Post.class);
Root<PostCategory> postCategoryRoot = postSubquery.from(PostCategory.class);
postSubquery.select(postCategoryRoot.get("postId"));
postSubquery.where(
criteriaBuilder.equal(root.get("id"), postCategoryRoot.get("postId")),
criteriaBuilder.equal(postCategoryRoot.get("categoryId"), postQuery.getCategoryId()));
predicates.add(criteriaBuilder.exists(postSubquery));
}
if (postQuery.getKeyword() != null) {
// Format like condition
String likeCondition = String.format("%%%s%%", StringUtils.strip(postQuery.getKeyword()));
// Build like predicate
Predicate titleLike = criteriaBuilder.like(root.get("title"), likeCondition);
Predicate originalContentLike = criteriaBuilder.like(root.get("originalContent"), likeCondition);
predicates.add(criteriaBuilder.or(titleLike, originalContentLike));
}
return query.where(predicates.toArray(new Predicate[0])).getRestriction();
};
}
/**
* List by status and type
*
@ -361,6 +411,13 @@ public class PostServiceImpl extends AbstractCrudService<Post, Integer> implemen
.collect(Collectors.toList());
}
@Override
public Page<PostSimpleOutputDTO> convertTo(@NonNull Page<Post> postPage) {
Assert.notNull(postPage, "Post page must not be null");
return postPage.map(post -> new PostSimpleOutputDTO().convertFrom(post));
}
/**
* Converts to post detail vo.
*

View File

@ -10,6 +10,7 @@ import run.halo.app.model.dto.post.PostSimpleOutputDTO;
import run.halo.app.model.entity.Post;
import run.halo.app.model.enums.PostStatus;
import run.halo.app.model.params.PostParam;
import run.halo.app.model.params.PostQuery;
import run.halo.app.model.vo.PostDetailVO;
import run.halo.app.service.*;
@ -50,6 +51,14 @@ public class PostController {
this.optionService = optionService;
}
@GetMapping
@ApiOperation("Lists posts")
public Page<PostSimpleOutputDTO> pageBy(@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable,
PostQuery postQuery) {
Page<Post> postPage = postService.pageBy(postQuery, pageable);
return postService.convertTo(postPage);
}
@GetMapping("latest")
@ApiOperation("Pages latest post")
public List<PostMinimalOutputDTO> pageLatest(@RequestParam(name = "top", defaultValue = "10") int top) {