From a5b016ef19f032a8f3f2f0ffae58b676d0c82999 Mon Sep 17 00:00:00 2001 From: johnniang Date: Tue, 23 Apr 2019 18:39:03 +0800 Subject: [PATCH] Add category post count support --- .../model/dto/CategoryWithPostCountDTO.java | 19 ++++++++++++++ .../CategoryPostCountProjection.java | 21 ++++++++++++++++ ...n.java => TagPostPostCountProjection.java} | 4 +-- .../repository/PostCategoryRepository.java | 8 ++++-- .../app/repository/PostTagRepository.java | 10 ++++---- .../run/halo/app/service/CategoryService.java | 11 ++++++++ .../halo/app/service/PostCategoryService.java | 11 ++++++++ .../app/service/impl/CategoryServiceImpl.java | 14 +++++++++++ .../service/impl/PostCategoryServiceImpl.java | 25 +++++++++++++++++++ .../app/service/impl/PostTagServiceImpl.java | 4 +-- .../admin/api/CategoryController.java | 18 ++++++++++--- 11 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 src/main/java/run/halo/app/model/dto/CategoryWithPostCountDTO.java create mode 100644 src/main/java/run/halo/app/model/projection/CategoryPostCountProjection.java rename src/main/java/run/halo/app/model/projection/{TagPostCountProjection.java => TagPostPostCountProjection.java} (83%) diff --git a/src/main/java/run/halo/app/model/dto/CategoryWithPostCountDTO.java b/src/main/java/run/halo/app/model/dto/CategoryWithPostCountDTO.java new file mode 100644 index 000000000..ff49781c7 --- /dev/null +++ b/src/main/java/run/halo/app/model/dto/CategoryWithPostCountDTO.java @@ -0,0 +1,19 @@ +package run.halo.app.model.dto; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * Category with post count dto. + * + * @author johnniang + * @date 19-4-23 + */ +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +public class CategoryWithPostCountDTO extends CategoryDTO { + + private Long postCount; +} diff --git a/src/main/java/run/halo/app/model/projection/CategoryPostCountProjection.java b/src/main/java/run/halo/app/model/projection/CategoryPostCountProjection.java new file mode 100644 index 000000000..f1acc3d97 --- /dev/null +++ b/src/main/java/run/halo/app/model/projection/CategoryPostCountProjection.java @@ -0,0 +1,21 @@ +package run.halo.app.model.projection; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Category post count projection. + * + * @author johnniang + * @date 19-4-23 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CategoryPostCountProjection { + + private Long postCount; + + private Integer categoryId; +} diff --git a/src/main/java/run/halo/app/model/projection/TagPostCountProjection.java b/src/main/java/run/halo/app/model/projection/TagPostPostCountProjection.java similarity index 83% rename from src/main/java/run/halo/app/model/projection/TagPostCountProjection.java rename to src/main/java/run/halo/app/model/projection/TagPostPostCountProjection.java index 2df512efe..40459ed8a 100644 --- a/src/main/java/run/halo/app/model/projection/TagPostCountProjection.java +++ b/src/main/java/run/halo/app/model/projection/TagPostPostCountProjection.java @@ -13,12 +13,12 @@ import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor -public class TagPostCountProjection { +public class TagPostPostCountProjection { /** * Post count. */ - private Long count; + private Long postCount; /** * Tag id diff --git a/src/main/java/run/halo/app/repository/PostCategoryRepository.java b/src/main/java/run/halo/app/repository/PostCategoryRepository.java index 2e381c5d8..2055c666c 100644 --- a/src/main/java/run/halo/app/repository/PostCategoryRepository.java +++ b/src/main/java/run/halo/app/repository/PostCategoryRepository.java @@ -1,9 +1,9 @@ package run.halo.app.repository; -import run.halo.app.model.entity.PostCategory; -import run.halo.app.repository.base.BaseRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.lang.NonNull; +import run.halo.app.model.entity.PostCategory; +import run.halo.app.model.projection.CategoryPostCountProjection; import run.halo.app.repository.base.BaseRepository; import java.util.List; @@ -81,4 +81,8 @@ public interface PostCategoryRepository extends BaseRepository deleteByCategoryId(@NonNull Integer categoryId); + + @Query("select new run.halo.app.model.projection.CategoryPostCountProjection(count(pc.postId), pc.categoryId) from PostCategory pc group by pc.categoryId") + @NonNull + List findPostCount(); } diff --git a/src/main/java/run/halo/app/repository/PostTagRepository.java b/src/main/java/run/halo/app/repository/PostTagRepository.java index 6ca67f106..69e858a7e 100644 --- a/src/main/java/run/halo/app/repository/PostTagRepository.java +++ b/src/main/java/run/halo/app/repository/PostTagRepository.java @@ -1,7 +1,7 @@ package run.halo.app.repository; import run.halo.app.model.entity.PostTag; -import run.halo.app.model.projection.TagPostCountProjection; +import run.halo.app.model.projection.TagPostPostCountProjection; import run.halo.app.repository.base.BaseRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.lang.NonNull; @@ -88,16 +88,16 @@ public interface PostTagRepository extends BaseRepository { * @param tagIds tag id collection must not be null * @return a list of tag post count projection */ - @Query("select new run.halo.app.model.projection.TagPostCountProjection(count(pt.postId), pt.tagId) from PostTag pt where pt.tagId in ?1 group by pt.tagId") + @Query("select new run.halo.app.model.projection.TagPostPostCountProjection(count(pt.postId), pt.tagId) from PostTag pt where pt.tagId in ?1 group by pt.tagId") @NonNull - List findPostCountByTagIds(@NonNull Iterable tagIds); + List findPostCountByTagIds(@NonNull Iterable tagIds); /** * Finds post count of tag. * * @return a list of tag post count projection */ - @Query("select new run.halo.app.model.projection.TagPostCountProjection(count(pt.postId), pt.tagId) from PostTag pt group by pt.tagId") + @Query("select new run.halo.app.model.projection.TagPostPostCountProjection(count(pt.postId), pt.tagId) from PostTag pt group by pt.tagId") @NonNull - List findPostCount(); + List findPostCount(); } diff --git a/src/main/java/run/halo/app/service/CategoryService.java b/src/main/java/run/halo/app/service/CategoryService.java index 3bf9167f7..418663d57 100755 --- a/src/main/java/run/halo/app/service/CategoryService.java +++ b/src/main/java/run/halo/app/service/CategoryService.java @@ -2,7 +2,9 @@ package run.halo.app.service; import org.springframework.data.domain.Sort; import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; import org.springframework.transaction.annotation.Transactional; +import run.halo.app.model.dto.CategoryDTO; import run.halo.app.model.entity.Category; import run.halo.app.model.vo.CategoryVO; import run.halo.app.service.base.CrudService; @@ -49,4 +51,13 @@ public interface CategoryService extends CrudService { */ @Transactional void removeCategoryAndPostCategoryBy(Integer categoryId); + + /** + * Converts to category dto. + * + * @param categories category list + * @return a list of category dto + */ + @NonNull + List convertTo(@Nullable List categories); } diff --git a/src/main/java/run/halo/app/service/PostCategoryService.java b/src/main/java/run/halo/app/service/PostCategoryService.java index c07acfb6c..9fb73b584 100644 --- a/src/main/java/run/halo/app/service/PostCategoryService.java +++ b/src/main/java/run/halo/app/service/PostCategoryService.java @@ -2,9 +2,11 @@ package run.halo.app.service; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.transaction.annotation.Transactional; +import run.halo.app.model.dto.CategoryWithPostCountDTO; import run.halo.app.model.entity.Category; import run.halo.app.model.entity.Post; import run.halo.app.model.entity.PostCategory; @@ -116,4 +118,13 @@ public interface PostCategoryService extends CrudService @NonNull @Transactional List removeByCategoryId(@NonNull Integer categoryId); + + /** + * Lists category with post count. + * + * @param sort sort info + * @return a list of category dto + */ + @NonNull + List listCategoryWithPostCountDto(@NonNull Sort sort); } diff --git a/src/main/java/run/halo/app/service/impl/CategoryServiceImpl.java b/src/main/java/run/halo/app/service/impl/CategoryServiceImpl.java index 3dfea1943..37502bb3a 100644 --- a/src/main/java/run/halo/app/service/impl/CategoryServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/CategoryServiceImpl.java @@ -2,6 +2,7 @@ package run.halo.app.service.impl; import run.halo.app.exception.AlreadyExistsException; import run.halo.app.exception.NotFoundException; +import run.halo.app.model.dto.CategoryDTO; import run.halo.app.model.entity.Category; import run.halo.app.model.vo.CategoryVO; import run.halo.app.repository.CategoryRepository; @@ -18,6 +19,7 @@ import org.springframework.util.CollectionUtils; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; /** * CategoryService implementation class @@ -171,4 +173,16 @@ public class CategoryServiceImpl extends AbstractCrudService // Remove post categories postCategoryService.removeByCategoryId(categoryId); } + + @Override + public List convertTo(List categories) { + if (CollectionUtils.isEmpty(categories)) { + return Collections.emptyList(); + } + + return categories + .stream() + .map(category -> new CategoryDTO().convertFrom(category)) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/run/halo/app/service/impl/PostCategoryServiceImpl.java b/src/main/java/run/halo/app/service/impl/PostCategoryServiceImpl.java index 2ae3771a0..47c0939f8 100644 --- a/src/main/java/run/halo/app/service/impl/PostCategoryServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/PostCategoryServiceImpl.java @@ -2,12 +2,16 @@ package run.halo.app.service.impl; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; +import run.halo.app.model.dto.CategoryDTO; +import run.halo.app.model.dto.CategoryWithPostCountDTO; import run.halo.app.model.entity.Category; import run.halo.app.model.entity.Post; import run.halo.app.model.entity.PostCategory; +import run.halo.app.model.projection.CategoryPostCountProjection; import run.halo.app.repository.CategoryRepository; import run.halo.app.repository.PostCategoryRepository; import run.halo.app.repository.PostRepository; @@ -182,4 +186,25 @@ public class PostCategoryServiceImpl extends AbstractCrudService listCategoryWithPostCountDto(Sort sort) { + Assert.notNull(sort, "Sort info must not be null"); + + List categories = categoryRepository.findAll(sort); + + // Query category post count + Map categoryPostCountMap = ServiceUtils.convertToMap(postCategoryRepository.findPostCount(), CategoryPostCountProjection::getCategoryId, CategoryPostCountProjection::getPostCount); + + // Convert and return + return categories.stream() + .map(category -> { + // Create category post count dto + CategoryWithPostCountDTO categoryWithPostCountDTO = new CategoryWithPostCountDTO().convertFrom(category); + // Set post count + categoryWithPostCountDTO.setPostCount(categoryPostCountMap.getOrDefault(category.getId(), 0L)); + return categoryWithPostCountDTO; + }) + .collect(Collectors.toList()); + } } diff --git a/src/main/java/run/halo/app/service/impl/PostTagServiceImpl.java b/src/main/java/run/halo/app/service/impl/PostTagServiceImpl.java index c0287d70b..89edea875 100644 --- a/src/main/java/run/halo/app/service/impl/PostTagServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/PostTagServiceImpl.java @@ -4,7 +4,7 @@ import run.halo.app.model.dto.TagWithPostCountDTO; import run.halo.app.model.entity.Post; import run.halo.app.model.entity.PostTag; import run.halo.app.model.entity.Tag; -import run.halo.app.model.projection.TagPostCountProjection; +import run.halo.app.model.projection.TagPostPostCountProjection; import run.halo.app.repository.PostRepository; import run.halo.app.repository.PostTagRepository; import run.halo.app.repository.TagRepository; @@ -63,7 +63,7 @@ public class PostTagServiceImpl extends AbstractCrudService im List tags = tagRepository.findAll(sort); // Find all post count - Map tagPostCountMap = ServiceUtils.convertToMap(postTagRepository.findPostCount(), TagPostCountProjection::getTagId, TagPostCountProjection::getCount); + Map tagPostCountMap = ServiceUtils.convertToMap(postTagRepository.findPostCount(), TagPostPostCountProjection::getTagId, TagPostPostCountProjection::getPostCount); // Find post count return tags.stream().map( diff --git a/src/main/java/run/halo/app/web/controller/admin/api/CategoryController.java b/src/main/java/run/halo/app/web/controller/admin/api/CategoryController.java index 0ac0b9852..d221174b9 100644 --- a/src/main/java/run/halo/app/web/controller/admin/api/CategoryController.java +++ b/src/main/java/run/halo/app/web/controller/admin/api/CategoryController.java @@ -9,11 +9,13 @@ import run.halo.app.model.entity.Category; import run.halo.app.model.params.CategoryParam; import run.halo.app.model.vo.CategoryVO; import run.halo.app.service.CategoryService; +import run.halo.app.service.PostCategoryService; import javax.validation.Valid; import java.util.List; import static org.springframework.data.domain.Sort.Direction.ASC; +import static org.springframework.data.domain.Sort.Direction.DESC; /** * Category controller. @@ -27,14 +29,24 @@ public class CategoryController { private final CategoryService categoryService; - public CategoryController(CategoryService categoryService) { + private final PostCategoryService postCategoryService; + + public CategoryController(CategoryService categoryService, + PostCategoryService postCategoryService) { this.categoryService = categoryService; + this.postCategoryService = postCategoryService; } @GetMapping @ApiOperation("List all categories") - public List listAll() { - return categoryService.listAll(); + public List listAll( + @SortDefault(sort = "updateTime", direction = DESC) Sort sort, + @RequestParam(name = "more", required = false, defaultValue = "false") boolean more) { + if (more) { + return postCategoryService.listCategoryWithPostCountDto(sort); + } + + return categoryService.convertTo(categoryService.listAll(sort)); } @GetMapping("tree_view")