diff --git a/pom.xml b/pom.xml
index 9fdc639c3..c95dbbe22 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,7 +14,7 @@
onemall
1.0-SNAPSHOT
-
+ product
common
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/category/ProductCategoryAddBO.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/category/ProductCategoryAddBO.java
new file mode 100644
index 000000000..5aa2cf611
--- /dev/null
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/category/ProductCategoryAddBO.java
@@ -0,0 +1,55 @@
+package cn.iocoder.mall.product.biz.bo.category;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 创建商品分类BO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductCategoryAddBO implements Serializable {
+
+ /**
+ * 分类编号
+ */
+ private Integer id;
+ /**
+ * 父分类编号
+ *
+ * 如果不存在父级,则 pid = 0 。
+ */
+ private Integer pid;
+ /**
+ * 名称
+ */
+ private String name;
+ /**
+ * 描述
+ */
+ private String description;
+ /**
+ * 分类图片
+ */
+ private String picUrl;
+ /**
+ * 排序值
+ */
+ private Integer sort;
+ /**
+ * 状态
+ *
+ * 1-开启
+ * 2-关闭
+ */
+ private Integer status;
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/category/ProductCategoryAllListBO.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/category/ProductCategoryAllListBO.java
new file mode 100644
index 000000000..8b568fb51
--- /dev/null
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/category/ProductCategoryAllListBO.java
@@ -0,0 +1,55 @@
+package cn.iocoder.mall.product.biz.bo.category;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 商品分类列表BO
+ */
+@Data
+@Accessors(chain = true)
+public class ProductCategoryAllListBO implements Serializable {
+
+ /**
+ * 分类编号
+ */
+ private Integer id;
+ /**
+ * 父分类编号
+ *
+ * 如果不存在父级,则 pid = 0 。
+ */
+ private Integer pid;
+ /**
+ * 名称
+ */
+ private String name;
+ /**
+ * 描述
+ */
+ private String description;
+ /**
+ * 分类图片
+ */
+ private String picUrl;
+ /**
+ * 排序值
+ */
+ private Integer sort;
+ /**
+ * 状态
+ *
+ * 1-开启
+ * 2-关闭
+ */
+ private Integer status;
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/product/ProductCategoryBO.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/product/ProductCategoryBO.java
index 6d4feb567..75e9e17c7 100644
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/product/ProductCategoryBO.java
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/bo/product/ProductCategoryBO.java
@@ -11,6 +11,7 @@ import java.util.Date;
*/
@Data
@Accessors(chain = true)
+@Deprecated // TODO jiangweifan 后面确认无使用后删除
public class ProductCategoryBO implements Serializable {
/**
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/category/ProductCategoryConvert.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/category/ProductCategoryConvert.java
new file mode 100644
index 000000000..f71f38a9b
--- /dev/null
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/category/ProductCategoryConvert.java
@@ -0,0 +1,56 @@
+package cn.iocoder.mall.product.biz.convert.category;
+
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAddBO;
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAllListBO;
+import cn.iocoder.mall.product.biz.dataobject.product.ProductCategoryDO;
+import cn.iocoder.mall.product.biz.dto.category.ProductCategoryAddDTO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+import java.util.List;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 服务层数据转换
+ */
+@Mapper
+public interface ProductCategoryConvert {
+
+ ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
+
+ /**
+ * 商品分类列表 - DO转换BO 单实体
+ * @param category
+ * @return
+ */
+ @Mappings({})
+ ProductCategoryAllListBO convertToAllListBO(ProductCategoryDO category);
+
+
+ /**
+ * 商品分类列表 - DO转换BO {@link #convertToAllListBO(ProductCategoryDO)}
+ * @param category
+ * @return
+ */
+ @Mappings({})
+ List convertToAllListBO(List category);
+
+ /**
+ * 商品分类新增 - DTO转换DO
+ * @param productCategoryAddDTO
+ * @return
+ */
+ @Mappings({})
+ ProductCategoryDO convertToDO(ProductCategoryAddDTO productCategoryAddDTO);
+
+ /**
+ * 商品分类新增 - DO转换BO
+ * @param category
+ * @return
+ */
+ @Mappings({})
+ ProductCategoryAddBO convertToAddBO(ProductCategoryDO category);
+
+
+}
\ No newline at end of file
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/product/ProductCategoryConvert.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/product/ProductCategoryConvert.java
deleted file mode 100644
index 45d074f41..000000000
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/convert/product/ProductCategoryConvert.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package cn.iocoder.mall.product.biz.convert.product;
-
-import cn.iocoder.mall.product.biz.bo.product.ProductCategoryBO;
-import cn.iocoder.mall.product.biz.dataobject.product.ProductCategoryDO;
-import cn.iocoder.mall.product.biz.dto.product.ProductCategoryAddDTO;
-import cn.iocoder.mall.product.biz.dto.product.ProductCategoryUpdateDTO;
-import org.mapstruct.Mapper;
-import org.mapstruct.Mappings;
-import org.mapstruct.factory.Mappers;
-
-import java.util.List;
-
-@Mapper
-public interface ProductCategoryConvert {
-
- ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
-
- @Mappings({})
- ProductCategoryBO convertToBO(ProductCategoryDO category);
-
- @Mappings({})
- List convertToBO(List categoryList);
-
- @Mappings({})
- ProductCategoryDO convert(ProductCategoryAddDTO productCategoryAddDTO);
-
- @Mappings({})
- ProductCategoryDO convert(ProductCategoryUpdateDTO productCategoryUpdateDTO);
-
-}
\ No newline at end of file
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dao/product/ProductCategoryMapper.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dao/product/ProductCategoryMapper.java
index 8ede5d1e6..7c9ac8fae 100644
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dao/product/ProductCategoryMapper.java
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dao/product/ProductCategoryMapper.java
@@ -1,10 +1,16 @@
package cn.iocoder.mall.product.biz.dao.product;
import cn.iocoder.mall.product.biz.dataobject.product.ProductBrandDO;
+import cn.iocoder.mall.product.biz.dataobject.product.ProductCategoryDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类数据持久层
+ */
@Repository
-public interface ProductCategoryMapper extends BaseMapper {
+public interface ProductCategoryMapper extends BaseMapper {
}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/product/ProductCategoryAddDTO.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/category/ProductCategoryAddDTO.java
similarity index 54%
rename from product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/product/ProductCategoryAddDTO.java
rename to product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/category/ProductCategoryAddDTO.java
index a05dd5653..237aab09d 100644
--- a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/product/ProductCategoryAddDTO.java
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/dto/category/ProductCategoryAddDTO.java
@@ -1,41 +1,41 @@
-package cn.iocoder.mall.product.biz.dto.product;
+package cn.iocoder.mall.product.biz.dto.category;
import lombok.Data;
import lombok.experimental.Accessors;
-import javax.validation.constraints.NotNull;
-
/**
- * 商品分类添加 DTO
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 创建商品分类DTO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryAddDTO {
+ /**
+ * 管理员id
+ */
+ private Integer adminId;
+
/**
* 父分类编号
*/
- @NotNull(message = "父分类编号不能为空")
private Integer pid;
/**
* 名称
*/
- @NotNull(message = "名称不能为空")
private String name;
/**
* 描述
*/
- @NotNull(message = "描述不能为空")
private String description;
/**
* 分类图片
*/
-// @NotNull(message = "分类图片不能为空")
private String picUrl;
/**
* 排序值
*/
- @NotNull(message = "排序值不能为空")
private Integer sort;
}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/product/ProductCategoryService.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/product/ProductCategoryService.java
new file mode 100644
index 000000000..988c30397
--- /dev/null
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/product/ProductCategoryService.java
@@ -0,0 +1,28 @@
+package cn.iocoder.mall.product.biz.service.product;
+
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAddBO;
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAllListBO;
+import cn.iocoder.mall.product.biz.dto.category.ProductCategoryAddDTO;
+import java.util.List;
+
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 服务层
+ */
+public interface ProductCategoryService {
+
+ /**
+ * 获取所有商品分类
+ * @return
+ */
+ List getAllProductCategory();
+
+ /**
+ * 新增商品分类
+ * @param productCategoryAddDTO
+ * @return
+ */
+ ProductCategoryAddBO addProductCategory(ProductCategoryAddDTO productCategoryAddDTO);
+}
diff --git a/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/product/impl/ProductCategoryServiceImpl.java b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/product/impl/ProductCategoryServiceImpl.java
new file mode 100644
index 000000000..c973f1239
--- /dev/null
+++ b/product/product-biz/src/main/java/cn/iocoder/mall/product/biz/service/product/impl/ProductCategoryServiceImpl.java
@@ -0,0 +1,77 @@
+package cn.iocoder.mall.product.biz.service.product.impl;
+
+import cn.iocoder.common.framework.util.ServiceExceptionUtil;
+import cn.iocoder.mall.mybatis.enums.DeletedStatusEnum;
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAddBO;
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAllListBO;
+import cn.iocoder.mall.product.biz.convert.category.ProductCategoryConvert;
+import cn.iocoder.mall.product.biz.dao.product.ProductCategoryMapper;
+import cn.iocoder.mall.product.biz.dataobject.product.ProductCategoryDO;
+import cn.iocoder.mall.product.biz.dto.category.ProductCategoryAddDTO;
+import cn.iocoder.mall.product.biz.enums.ProductErrorCodeEnum;
+import cn.iocoder.mall.product.biz.enums.product.ProductCategoryConstants;
+import cn.iocoder.mall.product.biz.service.product.ProductCategoryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.*;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 服务实现层
+ */
+@Service
+public class ProductCategoryServiceImpl implements ProductCategoryService {
+
+ @Autowired
+ private ProductCategoryMapper productCategoryMapper;
+
+ /**
+ * 获取所有商品分类
+ * @return
+ */
+ @Override
+ public List getAllProductCategory() {
+ List categoryList = productCategoryMapper.selectList(null);
+ return ProductCategoryConvert.INSTANCE.convertToAllListBO(categoryList);
+ }
+
+ /**
+ * 新增商品分类
+ * @param productCategoryAddDTO
+ * @return
+ */
+ @Override
+ public ProductCategoryAddBO addProductCategory(ProductCategoryAddDTO productCategoryAddDTO) {
+ // 校验父分类
+ validParent(productCategoryAddDTO.getPid());
+ // 保存到数据库
+ ProductCategoryDO productCategory = ProductCategoryConvert.INSTANCE.convertToDO(productCategoryAddDTO)
+ .setStatus(ProductCategoryConstants.STATUS_ENABLE);
+ productCategory.setCreateTime(new Date());
+ productCategory.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
+ productCategoryMapper.insert(productCategory);
+ // TODO jiangweifan 操作日志
+ // 返回成功
+ return ProductCategoryConvert.INSTANCE.convertToAddBO(productCategory);
+ }
+
+ /**
+ * 校验商品分类的父分类
+ * @param pid
+ */
+ private void validParent(Integer pid) {
+ if (!ProductCategoryConstants.PID_ROOT.equals(pid)) {
+ ProductCategoryDO parentCategory = productCategoryMapper.selectById(pid);
+ // 校验父分类是否存在
+ if (parentCategory == null) {
+ throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_EXISTS.getCode());
+ }
+ // 父分类必须是一级分类
+ if (!ProductCategoryConstants.PID_ROOT.equals(parentCategory.getPid())) {
+ throw ServiceExceptionUtil.exception((ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_CAN_NOT_BE_LEVEL2.getCode()));
+ }
+ }
+ }
+
+}
diff --git a/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/controller/admins/AdminsProductCategoryController.java b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/controller/admins/AdminsProductCategoryController.java
new file mode 100644
index 000000000..1911caaa1
--- /dev/null
+++ b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/controller/admins/AdminsProductCategoryController.java
@@ -0,0 +1,78 @@
+package cn.iocoder.mall.product.rest.controller.admins;
+
+import cn.iocoder.common.framework.constant.MallConstants;
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAddBO;
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAllListBO;
+import cn.iocoder.mall.product.biz.dto.category.ProductCategoryAddDTO;
+import cn.iocoder.mall.product.biz.enums.product.ProductCategoryConstants;
+import cn.iocoder.mall.product.biz.service.product.ProductCategoryService;
+import cn.iocoder.mall.product.rest.convert.category.ProductCategoryConvert;
+import cn.iocoder.mall.product.rest.request.category.AdminsProductCategoryAddRequest;
+import cn.iocoder.mall.product.rest.response.category.AdminsProductCategoryAddResponse;
+import cn.iocoder.mall.product.rest.response.category.AdminsProductCategoryTreeNodeResponse;
+import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.common.framework.vo.CommonResult.success;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - API
+ */
+@RestController
+@RequestMapping(MallConstants.ROOT_PATH_ADMIN + "/category")
+@Api(tags = "商品分类 API")
+public class AdminsProductCategoryController {
+
+ @Autowired
+ private ProductCategoryService productCategoryService;
+
+ @GetMapping("/tree")
+ @ApiOperation("获取分类树结构")
+ public CommonResult> tree() {
+ List productCategories = productCategoryService.getAllProductCategory();
+ // 创建 ProductCategoryTreeNodeVO Map
+ Map treeNodeMap = productCategories.stream().collect(Collectors.toMap(ProductCategoryAllListBO::getId, ProductCategoryConvert.INSTANCE::convertToTreeNodeResponse));
+ // 处理父子关系
+ treeNodeMap.values().stream()
+ .filter(node -> !node.getPid().equals(ProductCategoryConstants.PID_ROOT))
+ .forEach((childNode) -> {
+ // 获得父节点
+ AdminsProductCategoryTreeNodeResponse parentNode = treeNodeMap.get(childNode.getPid());
+ if (parentNode.getChildren() == null) { // 初始化 children 数组
+ parentNode.setChildren(new ArrayList<>());
+ }
+ // 将自己添加到父节点中
+ parentNode.getChildren().add(childNode);
+ });
+ // 获得到所有的根节点
+ List rootNodes = treeNodeMap.values().stream()
+ .filter(node -> node.getPid().equals(ProductCategoryConstants.PID_ROOT))
+ .sorted(Comparator.comparing(AdminsProductCategoryTreeNodeResponse::getSort))
+ .collect(Collectors.toList());
+ return success(rootNodes);
+ }
+
+ @PostMapping("/add")
+ @ApiOperation(value = "创建商品分类")
+ public CommonResult add(@RequestBody AdminsProductCategoryAddRequest adminsProductCategoryAddRequest) {
+ // 转换 ProductCategoryAddDTO 对象
+ ProductCategoryAddDTO productCategoryAddDTO = ProductCategoryConvert.INSTANCE.convertToAddDTO(AdminSecurityContextHolder.getContext().getAdminId(), adminsProductCategoryAddRequest);
+ // 创建商品分类
+ ProductCategoryAddBO addProductCategoryBO = productCategoryService.addProductCategory(productCategoryAddDTO);
+ // 返回结果
+ return success(ProductCategoryConvert.INSTANCE.convertToAddResponse(addProductCategoryBO));
+ }
+
+}
diff --git a/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/convert/category/ProductCategoryConvert.java b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/convert/category/ProductCategoryConvert.java
new file mode 100644
index 000000000..44f27e0a2
--- /dev/null
+++ b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/convert/category/ProductCategoryConvert.java
@@ -0,0 +1,47 @@
+package cn.iocoder.mall.product.rest.convert.category;
+
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAddBO;
+import cn.iocoder.mall.product.biz.bo.category.ProductCategoryAllListBO;
+import cn.iocoder.mall.product.biz.dto.category.ProductCategoryAddDTO;
+import cn.iocoder.mall.product.rest.request.category.AdminsProductCategoryAddRequest;
+import cn.iocoder.mall.product.rest.response.category.AdminsProductCategoryAddResponse;
+import cn.iocoder.mall.product.rest.response.category.AdminsProductCategoryTreeNodeResponse;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - API层数据转换
+ */
+@Mapper
+public interface ProductCategoryConvert {
+
+ ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
+
+ /**
+ * 商品分类列表 - BO转换Response
+ * @param productCategoryAllListBO
+ * @return
+ */
+ @Mappings({})
+ AdminsProductCategoryTreeNodeResponse convertToTreeNodeResponse(ProductCategoryAllListBO productCategoryAllListBO);
+
+
+ /**
+ * 新增商品分类 - Request转DTO
+ * @param adminsProductCategoryAddRequest
+ * @return
+ */
+ @Mappings({})
+ ProductCategoryAddDTO convertToAddDTO(Integer adminId, AdminsProductCategoryAddRequest adminsProductCategoryAddRequest);
+
+ /**
+ * 新增商品分类 - BO转Response
+ * @param productCategoryAddBO
+ * @return
+ */
+ @Mappings({})
+ AdminsProductCategoryAddResponse convertToAddResponse(ProductCategoryAddBO productCategoryAddBO);
+}
diff --git a/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/request/category/AdminsProductCategoryAddRequest.java b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/request/category/AdminsProductCategoryAddRequest.java
new file mode 100644
index 000000000..a9bd29c2a
--- /dev/null
+++ b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/request/category/AdminsProductCategoryAddRequest.java
@@ -0,0 +1,48 @@
+package cn.iocoder.mall.product.rest.request.category;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 创建商品分类Request
+ */
+@ApiModel("创建商品分类Request")
+@Data
+@Accessors(chain = true)
+public class AdminsProductCategoryAddRequest {
+ /**
+ * 父分类编号
+ */
+ @ApiModelProperty(name = "pid", value = "父级分类编号", required = true, example = "1")
+ @NotNull(message = "父分类编号不能为空")
+ private Integer pid;
+ /**
+ * 名称
+ */
+ @ApiModelProperty(name = "name", value = "分类名字(标识)", required = true, example = "admin/info")
+ @NotNull(message = "名称不能为空")
+ private String name;
+ /**
+ * 描述
+ */
+ @ApiModelProperty(name = "description", value = "描述", required = true, example = "1")
+ @NotNull(message = "描述不能为空")
+ private String description;
+ /**
+ * 分类图片
+ */
+ @ApiModelProperty(name = "picUrl", value = "分类图片", example = "http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg/")
+ private String picUrl;
+ /**
+ * 排序值
+ */
+ @ApiModelProperty(name = "sort", value = "排序", required = true, example = "1")
+ @NotNull(message = "排序值不能为空")
+ private Integer sort;
+}
diff --git a/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/response/category/AdminsProductCategoryAddResponse.java b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/response/category/AdminsProductCategoryAddResponse.java
new file mode 100644
index 000000000..b4ebff33a
--- /dev/null
+++ b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/response/category/AdminsProductCategoryAddResponse.java
@@ -0,0 +1,36 @@
+package cn.iocoder.mall.product.rest.response.category;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import java.util.Date;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 新增商品分类Response
+ */
+@ApiModel("创建商品分类Response")
+@Data
+@Accessors(chain = true)
+public class AdminsProductCategoryAddResponse {
+
+ @ApiModelProperty(value = "分类编号", required = true, example = "1")
+ private Integer id;
+ @ApiModelProperty(value = "父分类编号", required = true, example = "0")
+ private Integer pid;
+ @ApiModelProperty(value = "分类名", required = true, example = "手机")
+ private String name;
+ @ApiModelProperty(value = "描述", required = true, example = "这个商品很吊")
+ private String description;
+ @ApiModelProperty(value = "分类图片", notes = "一般情况下,只有根分类才有图片", example = "http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
+ private String picUrl;
+ @ApiModelProperty(value = "排序值", required = true, example = "10")
+ private Integer sort;
+ @ApiModelProperty(value = "状态", required = true, notes = "1-开启;2-关闭", example = "1")
+ private Integer status;
+ @ApiModelProperty(value = "创建时间", required = true, example = "时间戳")
+ private Date createTime;
+
+}
diff --git a/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/response/category/AdminsProductCategoryTreeNodeResponse.java b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/response/category/AdminsProductCategoryTreeNodeResponse.java
new file mode 100644
index 000000000..2fec71cd7
--- /dev/null
+++ b/product/product-rest/src/main/java/cn/iocoder/mall/product/rest/response/category/AdminsProductCategoryTreeNodeResponse.java
@@ -0,0 +1,40 @@
+package cn.iocoder.mall.product.rest.response.category;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Author: jiangweifan
+ * @Date: 2020/5/6
+ * @Description: 商品分类 - 分类树Response
+ */
+@ApiModel("商品分类树节点")
+@Data
+@Accessors(chain = true)
+public class AdminsProductCategoryTreeNodeResponse {
+
+ @ApiModelProperty(value = "分类编号", required = true, example = "1")
+ private Integer id;
+ @ApiModelProperty(value = "父分类编号", required = true, example = "0")
+ private Integer pid;
+ @ApiModelProperty(value = "分类名", required = true, example = "手机")
+ private String name;
+ @ApiModelProperty(value = "描述", required = true, example = "这个商品很吊")
+ private String description;
+ @ApiModelProperty(value = "分类图片", notes = "一般情况下,只有根分类才有图片", example = "http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
+ private String picUrl;
+ @ApiModelProperty(value = "排序值", required = true, example = "10")
+ private Integer sort;
+ @ApiModelProperty(value = "状态", required = true, notes = "1-开启;2-关闭", example = "1")
+ private Integer status;
+ @ApiModelProperty(value = "创建时间", required = true, example = "时间戳")
+ private Date createTime;
+ @ApiModelProperty(value = "子节点数组")
+ private List children;
+
+}