mirror of https://github.com/halo-dev/halo
				
				
				
			Add category post count support
							parent
							
								
									36c8a21af4
								
							
						
					
					
						commit
						a5b016ef19
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue