mirror of https://github.com/halo-dev/halo
Complete category creation and enhance category tree view api
parent
72eca3a5b5
commit
8d120e7927
|
@ -0,0 +1,58 @@
|
||||||
|
package cc.ryanc.halo.model.params;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.model.dto.base.InputConverter;
|
||||||
|
import cc.ryanc.halo.model.entity.Category;
|
||||||
|
import cc.ryanc.halo.utils.SlugUtils;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Category param.
|
||||||
|
*
|
||||||
|
* @author johnniang
|
||||||
|
* @date 3/21/19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CategoryParam implements InputConverter<Category> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类名称
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "Category name must not be blank")
|
||||||
|
@Size(max = 50, message = "Length of category name must not be more than {max}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缩略名
|
||||||
|
*/
|
||||||
|
@Size(max = 50, message = "Length of category slug name must not be more than {max}")
|
||||||
|
private String slugName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
@Size(max = 100, message = "Length of category description must not be more than {max}")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上级目录
|
||||||
|
*/
|
||||||
|
private Integer parentId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Category convertTo() {
|
||||||
|
// Handle default value
|
||||||
|
if (StringUtils.isBlank(slugName)) {
|
||||||
|
slugName = SlugUtils.slugify(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parentId == null || parentId < 0) {
|
||||||
|
parentId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return InputConverter.super.convertTo();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package cc.ryanc.halo.repository;
|
||||||
|
|
||||||
import cc.ryanc.halo.model.entity.Category;
|
import cc.ryanc.halo.model.entity.Category;
|
||||||
import cc.ryanc.halo.repository.base.BaseRepository;
|
import cc.ryanc.halo.repository.base.BaseRepository;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Category repository.
|
* Category repository.
|
||||||
|
@ -9,4 +10,20 @@ import cc.ryanc.halo.repository.base.BaseRepository;
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
*/
|
*/
|
||||||
public interface CategoryRepository extends BaseRepository<Category, Integer> {
|
public interface CategoryRepository extends BaseRepository<Category, Integer> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts by category name.
|
||||||
|
*
|
||||||
|
* @param name category name must not be blank
|
||||||
|
* @return the count
|
||||||
|
*/
|
||||||
|
long countByName(@NonNull String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts by category id.
|
||||||
|
*
|
||||||
|
* @param id category id must not be null
|
||||||
|
* @return the count
|
||||||
|
*/
|
||||||
|
long countById(@NonNull Integer id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public interface CategoryService extends CrudService<Category, Integer> {
|
||||||
void remove(@NonNull Integer id);
|
void remove(@NonNull Integer id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List as category tree.
|
* Lists as category tree.
|
||||||
*
|
*
|
||||||
* @param sort sort info must not be null
|
* @param sort sort info must not be null
|
||||||
* @return a category tree
|
* @return a category tree
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package cc.ryanc.halo.service.impl;
|
package cc.ryanc.halo.service.impl;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.exception.AlreadyExistsException;
|
||||||
|
import cc.ryanc.halo.exception.NotFoundException;
|
||||||
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.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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
@ -14,7 +17,6 @@ import org.springframework.util.CollectionUtils;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CategoryService implementation class
|
* CategoryService implementation class
|
||||||
|
@ -22,6 +24,7 @@ import java.util.Optional;
|
||||||
* @author : RYAN0UP
|
* @author : RYAN0UP
|
||||||
* @date : 2019-03-14
|
* @date : 2019-03-14
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class CategoryServiceImpl extends AbstractCrudService<Category, Integer> implements CategoryService {
|
public class CategoryServiceImpl extends AbstractCrudService<Category, Integer> implements CategoryService {
|
||||||
|
|
||||||
|
@ -42,6 +45,32 @@ public class CategoryServiceImpl extends AbstractCrudService<Category, Integer>
|
||||||
// TODO 删除分类,以及和文章的对应关系
|
// TODO 删除分类,以及和文章的对应关系
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Category create(Category category) {
|
||||||
|
Assert.notNull(category, "Category to create must not be null");
|
||||||
|
|
||||||
|
// Check the category name
|
||||||
|
long count = categoryRepository.countByName(category.getName());
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
log.error("Category has exist already: [{}]", category);
|
||||||
|
throw new AlreadyExistsException("The category has exist already");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check parent id
|
||||||
|
if (category.getParentId() > 0) {
|
||||||
|
count = categoryRepository.countById(category.getParentId());
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
log.error("Parent category with id: [{}] was not found, category: [{}]", category.getParentId(), category);
|
||||||
|
throw new NotFoundException("Parent category with id = " + category.getParentId() + " was not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create it
|
||||||
|
return super.create(category);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<CategoryVO> listAsTree(Sort sort) {
|
public List<CategoryVO> listAsTree(Sort sort) {
|
||||||
Assert.notNull(sort, "Sort info must not be null");
|
Assert.notNull(sort, "Sort info must not be null");
|
||||||
|
@ -87,7 +116,10 @@ public class CategoryServiceImpl extends AbstractCrudService<Category, Integer>
|
||||||
CategoryVO child = new CategoryVO().convertFrom(category);
|
CategoryVO child = new CategoryVO().convertFrom(category);
|
||||||
|
|
||||||
// Init children if absent
|
// Init children if absent
|
||||||
Optional.ofNullable(parentCategory.getChildren()).orElseGet(LinkedList::new).add(child);
|
if (parentCategory.getChildren() == null) {
|
||||||
|
parentCategory.setChildren(new LinkedList<>());
|
||||||
|
}
|
||||||
|
parentCategory.getChildren().add(child);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
package cc.ryanc.halo.web.controller.admin.api;
|
package cc.ryanc.halo.web.controller.admin.api;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.model.dto.CategoryOutputDTO;
|
||||||
|
import cc.ryanc.halo.model.entity.Category;
|
||||||
|
import cc.ryanc.halo.model.params.CategoryParam;
|
||||||
import cc.ryanc.halo.model.vo.CategoryVO;
|
import cc.ryanc.halo.model.vo.CategoryVO;
|
||||||
import cc.ryanc.halo.service.CategoryService;
|
import cc.ryanc.halo.service.CategoryService;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.web.SortDefault;
|
import org.springframework.data.web.SortDefault;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.springframework.data.domain.Sort.Direction.DESC;
|
import static org.springframework.data.domain.Sort.Direction.ASC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Category controller.
|
* Category controller.
|
||||||
|
@ -31,7 +33,16 @@ public class CategoryController {
|
||||||
|
|
||||||
@GetMapping("tree")
|
@GetMapping("tree")
|
||||||
@ApiOperation("List as category tree")
|
@ApiOperation("List as category tree")
|
||||||
public List<CategoryVO> listAsTree(@SortDefault(sort = "name", direction = DESC) Sort sort) {
|
public List<CategoryVO> listAsTree(@SortDefault(sort = "name", direction = ASC) Sort sort) {
|
||||||
return categoryService.listAsTree(sort);
|
return categoryService.listAsTree(sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public CategoryOutputDTO createBy(@Valid @RequestBody CategoryParam categoryParam) {
|
||||||
|
// Convert to category
|
||||||
|
Category category = categoryParam.convertTo();
|
||||||
|
|
||||||
|
// Save it
|
||||||
|
return new CategoryOutputDTO().convertFrom(categoryService.create(category));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue