mirror of https://github.com/halo-dev/halo
Complete category tree view api
parent
3ffecd84e4
commit
72eca3a5b5
|
@ -13,6 +13,8 @@ import lombok.Data;
|
||||||
@Data
|
@Data
|
||||||
public class CategoryOutputDTO implements OutputConverter<CategoryOutputDTO, Category> {
|
public class CategoryOutputDTO implements OutputConverter<CategoryOutputDTO, Category> {
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private String slugName;
|
private String slugName;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package cc.ryanc.halo.model.vo;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.model.dto.CategoryOutputDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Category vo.
|
||||||
|
*
|
||||||
|
* @author johnniang
|
||||||
|
* @date 3/21/19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CategoryVO extends CategoryOutputDTO {
|
||||||
|
|
||||||
|
private List<CategoryVO> children;
|
||||||
|
}
|
|
@ -1,7 +1,12 @@
|
||||||
package cc.ryanc.halo.service;
|
package cc.ryanc.halo.service;
|
||||||
|
|
||||||
import cc.ryanc.halo.model.entity.Category;
|
import cc.ryanc.halo.model.entity.Category;
|
||||||
|
import cc.ryanc.halo.model.vo.CategoryVO;
|
||||||
import cc.ryanc.halo.service.base.CrudService;
|
import cc.ryanc.halo.service.base.CrudService;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Category service.
|
* Category service.
|
||||||
|
@ -15,5 +20,15 @@ public interface CategoryService extends CrudService<Category, Integer> {
|
||||||
*
|
*
|
||||||
* @param id id
|
* @param id id
|
||||||
*/
|
*/
|
||||||
void remove(Integer id);
|
@Deprecated
|
||||||
|
void remove(@NonNull Integer id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List as category tree.
|
||||||
|
*
|
||||||
|
* @param sort sort info must not be null
|
||||||
|
* @return a category tree
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
List<CategoryVO> listAsTree(@NonNull Sort sort);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
package cc.ryanc.halo.service.impl;
|
package cc.ryanc.halo.service.impl;
|
||||||
|
|
||||||
import cc.ryanc.halo.model.entity.Category;
|
import cc.ryanc.halo.model.entity.Category;
|
||||||
|
import cc.ryanc.halo.model.vo.CategoryVO;
|
||||||
import cc.ryanc.halo.repository.CategoryRepository;
|
import cc.ryanc.halo.repository.CategoryRepository;
|
||||||
import cc.ryanc.halo.service.CategoryService;
|
import cc.ryanc.halo.service.CategoryService;
|
||||||
import cc.ryanc.halo.service.base.AbstractCrudService;
|
import cc.ryanc.halo.service.base.AbstractCrudService;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CategoryService implementation class
|
* CategoryService implementation class
|
||||||
|
@ -31,4 +41,78 @@ public class CategoryServiceImpl extends AbstractCrudService<Category, Integer>
|
||||||
public void remove(Integer id) {
|
public void remove(Integer id) {
|
||||||
// TODO 删除分类,以及和文章的对应关系
|
// TODO 删除分类,以及和文章的对应关系
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CategoryVO> listAsTree(Sort sort) {
|
||||||
|
Assert.notNull(sort, "Sort info must not be null");
|
||||||
|
|
||||||
|
// List all category
|
||||||
|
List<Category> categories = listAll(sort);
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(categories)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create top category
|
||||||
|
CategoryVO topLevelCategory = createTopLevelCategory();
|
||||||
|
|
||||||
|
// Concrete the tree
|
||||||
|
concreteTree(topLevelCategory, categories);
|
||||||
|
|
||||||
|
return topLevelCategory.getChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete category tree.
|
||||||
|
*
|
||||||
|
* @param parentCategory parent category vo must not be null
|
||||||
|
* @param categories a list of category
|
||||||
|
*/
|
||||||
|
private void concreteTree(CategoryVO parentCategory, List<Category> categories) {
|
||||||
|
Assert.notNull(parentCategory, "Parent category must not be null");
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(categories)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create children container for removing after
|
||||||
|
List<Category> children = new LinkedList<>();
|
||||||
|
|
||||||
|
categories.forEach(category -> {
|
||||||
|
if (parentCategory.getId().equals(category.getParentId())) {
|
||||||
|
// Save child category
|
||||||
|
children.add(category);
|
||||||
|
|
||||||
|
// Convert to child category vo
|
||||||
|
CategoryVO child = new CategoryVO().convertFrom(category);
|
||||||
|
|
||||||
|
// Init children if absent
|
||||||
|
Optional.ofNullable(parentCategory.getChildren()).orElseGet(LinkedList::new).add(child);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove all child categories
|
||||||
|
categories.removeAll(children);
|
||||||
|
|
||||||
|
// Foreach children vos
|
||||||
|
if (!CollectionUtils.isEmpty(parentCategory.getChildren())) {
|
||||||
|
parentCategory.getChildren().forEach(childCategory -> concreteTree(childCategory, categories));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a top level category.
|
||||||
|
*
|
||||||
|
* @return top level category with id 0
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private CategoryVO createTopLevelCategory() {
|
||||||
|
CategoryVO topCategory = new CategoryVO();
|
||||||
|
// Set default value
|
||||||
|
topCategory.setId(0);
|
||||||
|
topCategory.setChildren(new LinkedList<>());
|
||||||
|
topCategory.setParentId(-1);
|
||||||
|
|
||||||
|
return topCategory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package cc.ryanc.halo.web.controller.admin.api;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.model.vo.CategoryVO;
|
||||||
|
import cc.ryanc.halo.service.CategoryService;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.web.SortDefault;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.springframework.data.domain.Sort.Direction.DESC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Category controller.
|
||||||
|
*
|
||||||
|
* @author johnniang
|
||||||
|
* @date 3/21/19
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/admin/api/categories")
|
||||||
|
public class CategoryController {
|
||||||
|
|
||||||
|
private final CategoryService categoryService;
|
||||||
|
|
||||||
|
public CategoryController(CategoryService categoryService) {
|
||||||
|
this.categoryService = categoryService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("tree")
|
||||||
|
@ApiOperation("List as category tree")
|
||||||
|
public List<CategoryVO> listAsTree(@SortDefault(sort = "name", direction = DESC) Sort sort) {
|
||||||
|
return categoryService.listAsTree(sort);
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ public class PostController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("status/{status}")
|
@GetMapping("status/{status}")
|
||||||
@ApiOperation("")
|
@ApiOperation("Gets a page of post by post status")
|
||||||
public Page<PostSimpleOutputDTO> pageByStatus(@PathVariable(name = "status") PostStatus status,
|
public Page<PostSimpleOutputDTO> pageByStatus(@PathVariable(name = "status") PostStatus status,
|
||||||
@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable) {
|
@PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable) {
|
||||||
return postService.pageSimpleDtoByStatus(status, PostType.POST, pageable);
|
return postService.pageSimpleDtoByStatus(status, PostType.POST, pageable);
|
||||||
|
|
Loading…
Reference in New Issue