Add category post count support

pull/146/head
johnniang 2019-04-23 18:39:03 +08:00
parent 36c8a21af4
commit a5b016ef19
11 changed files with 131 additions and 14 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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<PostCategory, Int
*/
@NonNull
List<PostCategory> 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<CategoryPostCountProjection> findPostCount();
}

View File

@ -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<PostTag, Integer> {
* @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<TagPostCountProjection> findPostCountByTagIds(@NonNull Iterable<Integer> tagIds);
List<TagPostPostCountProjection> findPostCountByTagIds(@NonNull Iterable<Integer> 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<TagPostCountProjection> findPostCount();
List<TagPostPostCountProjection> findPostCount();
}

View File

@ -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<Category, Integer> {
*/
@Transactional
void removeCategoryAndPostCategoryBy(Integer categoryId);
/**
* Converts to category dto.
*
* @param categories category list
* @return a list of category dto
*/
@NonNull
List<CategoryDTO> convertTo(@Nullable List<Category> categories);
}

View File

@ -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<PostCategory, Integer>
@NonNull
@Transactional
List<PostCategory> removeByCategoryId(@NonNull Integer categoryId);
/**
* Lists category with post count.
*
* @param sort sort info
* @return a list of category dto
*/
@NonNull
List<CategoryWithPostCountDTO> listCategoryWithPostCountDto(@NonNull Sort sort);
}

View File

@ -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<Category, Integer>
// Remove post categories
postCategoryService.removeByCategoryId(categoryId);
}
@Override
public List<CategoryDTO> convertTo(List<Category> categories) {
if (CollectionUtils.isEmpty(categories)) {
return Collections.emptyList();
}
return categories
.stream()
.map(category -> new CategoryDTO().<CategoryDTO>convertFrom(category))
.collect(Collectors.toList());
}
}

View File

@ -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<PostCategory, I
return postCategoryRepository.deleteByCategoryId(categoryId);
}
@Override
public List<CategoryWithPostCountDTO> listCategoryWithPostCountDto(Sort sort) {
Assert.notNull(sort, "Sort info must not be null");
List<Category> categories = categoryRepository.findAll(sort);
// Query category post count
Map<Integer, Long> 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());
}
}

View File

@ -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<PostTag, Integer> im
List<Tag> tags = tagRepository.findAll(sort);
// Find all post count
Map<Integer, Long> tagPostCountMap = ServiceUtils.convertToMap(postTagRepository.findPostCount(), TagPostCountProjection::getTagId, TagPostCountProjection::getCount);
Map<Integer, Long> tagPostCountMap = ServiceUtils.convertToMap(postTagRepository.findPostCount(), TagPostPostCountProjection::getTagId, TagPostPostCountProjection::getPostCount);
// Find post count
return tags.stream().map(

View File

@ -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<Category> listAll() {
return categoryService.listAll();
public List<? extends CategoryDTO> 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")