diff --git a/src/main/java/cc/ryanc/halo/model/params/CategoryParam.java b/src/main/java/cc/ryanc/halo/model/params/CategoryParam.java new file mode 100644 index 000000000..1e2154637 --- /dev/null +++ b/src/main/java/cc/ryanc/halo/model/params/CategoryParam.java @@ -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 { + + /** + * 分类名称 + */ + @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(); + } +} diff --git a/src/main/java/cc/ryanc/halo/repository/CategoryRepository.java b/src/main/java/cc/ryanc/halo/repository/CategoryRepository.java index ab6f545a5..87d4ca13a 100644 --- a/src/main/java/cc/ryanc/halo/repository/CategoryRepository.java +++ b/src/main/java/cc/ryanc/halo/repository/CategoryRepository.java @@ -2,6 +2,7 @@ package cc.ryanc.halo.repository; import cc.ryanc.halo.model.entity.Category; import cc.ryanc.halo.repository.base.BaseRepository; +import org.springframework.lang.NonNull; /** * Category repository. @@ -9,4 +10,20 @@ import cc.ryanc.halo.repository.base.BaseRepository; * @author johnniang */ public interface CategoryRepository extends BaseRepository { + + /** + * 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); } diff --git a/src/main/java/cc/ryanc/halo/service/CategoryService.java b/src/main/java/cc/ryanc/halo/service/CategoryService.java index 15b9b22bb..528cca9fd 100755 --- a/src/main/java/cc/ryanc/halo/service/CategoryService.java +++ b/src/main/java/cc/ryanc/halo/service/CategoryService.java @@ -24,7 +24,7 @@ public interface CategoryService extends CrudService { void remove(@NonNull Integer id); /** - * List as category tree. + * Lists as category tree. * * @param sort sort info must not be null * @return a category tree diff --git a/src/main/java/cc/ryanc/halo/service/impl/CategoryServiceImpl.java b/src/main/java/cc/ryanc/halo/service/impl/CategoryServiceImpl.java index 827bb0ef0..ac4d3f130 100644 --- a/src/main/java/cc/ryanc/halo/service/impl/CategoryServiceImpl.java +++ b/src/main/java/cc/ryanc/halo/service/impl/CategoryServiceImpl.java @@ -1,10 +1,13 @@ 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.vo.CategoryVO; import cc.ryanc.halo.repository.CategoryRepository; import cc.ryanc.halo.service.CategoryService; import cc.ryanc.halo.service.base.AbstractCrudService; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Sort; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; @@ -14,7 +17,6 @@ import org.springframework.util.CollectionUtils; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.Optional; /** * CategoryService implementation class @@ -22,6 +24,7 @@ import java.util.Optional; * @author : RYAN0UP * @date : 2019-03-14 */ +@Slf4j @Service public class CategoryServiceImpl extends AbstractCrudService implements CategoryService { @@ -42,6 +45,32 @@ public class CategoryServiceImpl extends AbstractCrudService // 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 public List listAsTree(Sort sort) { Assert.notNull(sort, "Sort info must not be null"); @@ -87,7 +116,10 @@ public class CategoryServiceImpl extends AbstractCrudService CategoryVO child = new CategoryVO().convertFrom(category); // 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); } }); diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/api/CategoryController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/api/CategoryController.java index c08224111..e4108d62e 100644 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/api/CategoryController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/api/CategoryController.java @@ -1,17 +1,19 @@ 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.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 org.springframework.web.bind.annotation.*; +import javax.validation.Valid; import java.util.List; -import static org.springframework.data.domain.Sort.Direction.DESC; +import static org.springframework.data.domain.Sort.Direction.ASC; /** * Category controller. @@ -31,7 +33,16 @@ public class CategoryController { @GetMapping("tree") @ApiOperation("List as category tree") - public List listAsTree(@SortDefault(sort = "name", direction = DESC) Sort sort) { + public List listAsTree(@SortDefault(sort = "name", direction = ASC) Sort 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)); + } }