diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java index e328d2512..d47bb7543 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java @@ -3,16 +3,18 @@ package cn.iocoder.yudao.module.product.enums; import cn.iocoder.yudao.framework.common.exception.ErrorCode; /** - * product 错误码枚举类 - *

+ * Product 错误码枚举类 + * * product 系统,使用 1-008-000-000 段 */ public interface ErrorCodeConstants { - // ========== 商品分类相关 1008001000============ - ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在"); - ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在"); - ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001002, "存在子分类,无法删除"); + // ========== 商品分类相关 1008001000 ============ + ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在"); + ErrorCode PRODUCT_CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在"); + ErrorCode PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类"); + ErrorCode PRODUCT_CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除"); + ErrorCode PRODUCT_CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用"); // ========== 品牌相关编号 1008002000 ========== ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在"); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java deleted file mode 100644 index 12408ac28..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/CategoryController.java +++ /dev/null @@ -1,92 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; -import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; -import cn.iocoder.yudao.module.product.service.category.CategoryService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; -import java.io.IOException; -import java.util.Comparator; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; - -@Api(tags = "管理后台 - 商品分类") -@RestController -@RequestMapping("/product/category") -@Validated -public class CategoryController { - - @Resource - private CategoryService categoryService; - - @PostMapping("/create") - @ApiOperation("创建商品分类") - @PreAuthorize("@ss.hasPermission('product:category:create')") - public CommonResult createCategory(@Valid @RequestBody CategoryCreateReqVO createReqVO) { - return success(categoryService.createCategory(createReqVO)); - } - - @PutMapping("/update") - @ApiOperation("更新商品分类") - @PreAuthorize("@ss.hasPermission('product:category:update')") - public CommonResult updateCategory(@Valid @RequestBody CategoryUpdateReqVO updateReqVO) { - categoryService.updateCategory(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @ApiOperation("删除商品分类") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('product:category:delete')") - public CommonResult deleteCategory(@RequestParam("id") Long id) { - categoryService.deleteCategory(id); - return success(true); - } - - @GetMapping("/get") - @ApiOperation("获得商品分类") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('product:category:query')") - public CommonResult getCategory(@RequestParam("id") Long id) { - CategoryDO category = categoryService.getCategory(id); - return success(CategoryConvert.INSTANCE.convert(category)); - } - - // TODO @JeromeSoar:这应该是个 app 的接口,提供商品分类的树结构。这个调整下,后端只返回列表,前端构建 tree。注意,不需要返回创建时间、是否开启等无关字段。 - // TODO @YunaiV: 这个是在管理端展示了一个类似菜单的分类树列表, treeListReqVO 只是查询参数的封装命名,返给前端的是列表数据。PS: 这里 /page 接口没有使用到。 - @GetMapping("/listByQuery") - @ApiOperation("获得商品分类列表") - @PreAuthorize("@ss.hasPermission('product:category:query')") - public CommonResult> listByQuery(@Valid CategoryTreeListReqVO treeListReqVO) { - List list = categoryService.getCategoryTreeList(treeListReqVO); - list.sort(Comparator.comparing(CategoryDO::getSort)); - return success(CategoryConvert.INSTANCE.convertList(list)); - } - - @GetMapping("/export-excel") - @ApiOperation("导出商品分类 Excel") - @PreAuthorize("@ss.hasPermission('product:category:export')") - @OperateLog(type = EXPORT) - public void exportCategoryExcel(@Valid CategoryExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = categoryService.getCategoryList(exportReqVO); - // 导出 Excel - List datas = CategoryConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "商品分类.xls", "数据", CategoryExcelVO.class, datas); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java new file mode 100644 index 000000000..1f519e40d --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java @@ -0,0 +1,76 @@ +package cn.iocoder.yudao.module.product.controller.admin.category; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Comparator; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Api(tags = "管理后台 - 商品分类") +@RestController +@RequestMapping("/product/category") +@Validated +public class ProductCategoryController { + + @Resource + private ProductCategoryService categoryService; + + @PostMapping("/create") + @ApiOperation("创建商品分类") + @PreAuthorize("@ss.hasPermission('product:category:create')") + public CommonResult createProductCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) { + return success(categoryService.createProductCategory(createReqVO)); + } + + @PutMapping("/update") + @ApiOperation("更新商品分类") + @PreAuthorize("@ss.hasPermission('product:category:update')") + public CommonResult updateProductCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) { + categoryService.updateProductCategory(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除商品分类") + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('product:category:delete')") + public CommonResult deleteProductCategory(@RequestParam("id") Long id) { + categoryService.deleteProductCategory(id); + return success(true); + } + + @GetMapping("/get") + @ApiOperation("获得商品分类") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('product:category:query')") + public CommonResult getProductCategory(@RequestParam("id") Long id) { + ProductCategoryDO category = categoryService.getProductCategory(id); + return success(CategoryConvert.INSTANCE.convert(category)); + } + + @GetMapping("/list") + @ApiOperation("获得商品分类列表") + @PreAuthorize("@ss.hasPermission('product:category:query')") + public CommonResult> getProductCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) { + List list = categoryService.getEnableProductCategoryList(treeListReqVO); + list.sort(Comparator.comparing(ProductCategoryDO::getSort)); + return success(CategoryConvert.INSTANCE.convertList(list)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExcelVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExcelVO.java deleted file mode 100644 index f8e36ee8c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExcelVO.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; - -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; -import com.alibaba.excel.annotation.ExcelProperty; -import lombok.Data; - -import java.util.Date; - - -/** - * 商品分类 Excel VO - * - * @author 芋道源码 - */ -@Data -public class CategoryExcelVO { - - @ExcelProperty("分类编号") - private Long id; - - @ExcelProperty("父分类编号") - private Long parentId; - - @ExcelProperty("分类名称") - private String name; - - @ExcelProperty("分类图标") - private String icon; - - @ExcelProperty("分类图片") - private String bannerUrl; - - @ExcelProperty("分类排序") - private Integer sort; - - @ExcelProperty("分类描述") - private String description; - - @ExcelProperty(value = "开启状态", converter = DictConvert.class) - @DictFormat("common_status") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中 - private Integer status; - - @ExcelProperty("创建时间") - private Date createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExportReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExportReqVO.java deleted file mode 100644 index c119fb2dc..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryExportReqVO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel(value = "管理后台 - 商品分类 Excel 导出 Request VO", description = "参数和 CategoryPageReqVO 是一致的") -@Data -public class CategoryExportReqVO { - - @ApiModelProperty(value = "分类名称", example = "办公文具") - private String name; - - @ApiModelProperty(value = "开启状态", example = "0") - private Integer status; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") - private Date[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryPageReqVO.java deleted file mode 100644 index 1cf83bbbe..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryPageReqVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel("管理后台 - 商品分类分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CategoryPageReqVO extends PageParam { - - @ApiModelProperty(value = "分类名称", example = "办公文具") - private String name; - - @ApiModelProperty(value = "开启状态", example = "0") - private Integer status; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") - private Date[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryTreeListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryTreeListReqVO.java deleted file mode 100644 index 214349ee5..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryTreeListReqVO.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Data -@ApiModel(value = "管理后台 - 商品分类列表查询 Request VO", description = "参数和 CategoryPageReqVO 是一致的") -public class CategoryTreeListReqVO extends CategoryExportReqVO { - - @ApiModelProperty(value = "分类名称", example = "办公文具") - private String name; - - @ApiModelProperty(value = "开启状态", example = "0") - private Integer status; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") - private Date[] createTime; -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java similarity index 87% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java index 598e093eb..9b9c77a08 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java @@ -11,7 +11,7 @@ import javax.validation.constraints.NotNull; * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 */ @Data -public class CategoryBaseVO { +public class ProductCategoryBaseVO { @ApiModelProperty(value = "父分类编号", required = true, example = "1") @NotNull(message = "父分类编号不能为空") @@ -21,13 +21,9 @@ public class CategoryBaseVO { @NotBlank(message = "分类名称不能为空") private String name; - @ApiModelProperty(value = "分类图标") - @NotBlank(message = "分类图标不能为空") - private String icon; - @ApiModelProperty(value = "分类图片", required = true) @NotBlank(message = "分类图片不能为空") - private String bannerUrl; + private String picUrl; @ApiModelProperty(value = "分类排序", required = true, example = "1") private Integer sort; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java similarity index 68% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryCreateReqVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java index ce583f08b..d35e1ad3c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java @@ -1,14 +1,12 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; import lombok.*; -import java.util.*; import io.swagger.annotations.*; -import javax.validation.constraints.*; @ApiModel("管理后台 - 商品分类创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class CategoryCreateReqVO extends CategoryBaseVO { +public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO { } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java new file mode 100644 index 000000000..a487c16a4 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.product.controller.admin.category.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@ApiModel(value = "管理后台 - 商品分类列表查询 Request VO") +@Data +public class ProductCategoryListReqVO { + + @ApiModelProperty(value = "分类名称", example = "办公文具") + private String name; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java similarity index 87% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryRespVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java index e7d0b2238..9c3d1b458 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java @@ -8,7 +8,7 @@ import io.swagger.annotations.*; @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class CategoryRespVO extends CategoryBaseVO { +public class ProductCategoryRespVO extends ProductCategoryBaseVO { @ApiModelProperty(value = "分类编号", required = true, example = "2") private Long id; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java similarity index 85% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryUpdateReqVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java index 13ee83c1e..b0c8fe57d 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; import lombok.*; -import java.util.*; import io.swagger.annotations.*; import javax.validation.constraints.*; @@ -9,7 +8,7 @@ import javax.validation.constraints.*; @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class CategoryUpdateReqVO extends CategoryBaseVO { +public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { @ApiModelProperty(value = "分类编号", required = true, example = "2") @NotNull(message = "分类编号不能为空") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java index 201690717..508059ae7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.product.controller.app.category; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO; import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; -import cn.iocoder.yudao.module.product.service.category.CategoryService; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.validation.annotation.Validated; @@ -25,13 +25,13 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; public class AppCategoryController { @Resource - private CategoryService categoryService; + private ProductCategoryService categoryService; @GetMapping("/list") @ApiOperation("获得商品分类列表") public CommonResult> listByQuery() { - List list = categoryService.getCategoryList(); - list.sort(Comparator.comparing(CategoryDO::getSort)); + List list = categoryService.getEnableProductCategoryList(); + list.sort(Comparator.comparing(ProductCategoryDO::getSort)); return success(CategoryConvert.INSTANCE.convertList03(list)); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/CategoryConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/CategoryConvert.java index 9099067e2..637c52976 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/CategoryConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/CategoryConvert.java @@ -1,14 +1,14 @@ package cn.iocoder.yudao.module.product.convert.category; -import java.util.*; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; - +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; + +import java.util.List; /** * 商品分类 Convert @@ -20,17 +20,13 @@ public interface CategoryConvert { CategoryConvert INSTANCE = Mappers.getMapper(CategoryConvert.class); - CategoryDO convert(CategoryCreateReqVO bean); + ProductCategoryDO convert(ProductCategoryCreateReqVO bean); - CategoryDO convert(CategoryUpdateReqVO bean); + ProductCategoryDO convert(ProductCategoryUpdateReqVO bean); - CategoryRespVO convert(CategoryDO bean); + ProductCategoryRespVO convert(ProductCategoryDO bean); - List convertList(List list); + List convertList(List list); - PageResult convertPage(PageResult page); - - List convertList02(List list); - - List convertList03(List list); + List convertList03(List list); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/CategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java similarity index 70% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/CategoryDO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java index c6eb655ab..cb63f7563 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/CategoryDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java @@ -6,10 +6,13 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; -// TODO @JeromeSoar:Product 前缀 /** * 商品分类 DO * + * 商品分类一共两级: + * 1)一级分类:{@link #parentId} 等于 0 + * 2)二级分类:{@link #parentId} 等于父分类 + * * @author 芋道源码 */ @TableName("product_category") @@ -19,7 +22,12 @@ import lombok.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class CategoryDO extends BaseDO { +public class ProductCategoryDO extends BaseDO { + + /** + * 父分类编号 - 根分类 + */ + public static final Long PARENT_ID_NULL = 0L; /** * 分类编号 @@ -35,15 +43,12 @@ public class CategoryDO extends BaseDO { */ private String name; /** - * 分类图标 - */ - private String icon; - /** - * 分类 Banner 图片 + * 分类图片 * - * 第一层的商品分类,会有该字段,用于用户 App 展示 + * 一级分类:推荐 200 x 100 分辨率 + * 二级分类:推荐 100 x 100 分辨率 */ - private String bannerUrl; + private String picUrl; /** * 分类排序 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/CategoryMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/CategoryMapper.java deleted file mode 100644 index e0f798e18..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/CategoryMapper.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.product.dal.mysql.category; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * 商品分类 Mapper - * - * @author 芋道源码 - */ -@Mapper -public interface CategoryMapper extends BaseMapperX { - - default PageResult selectPage(CategoryPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(CategoryDO::getName, reqVO.getName()) - .eqIfPresent(CategoryDO::getStatus, reqVO.getStatus()) - .betweenIfPresent(CategoryDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(CategoryDO::getId)); - } - - default List selectList(CategoryExportReqVO reqVO) { - return selectList(new LambdaQueryWrapperX() - .likeIfPresent(CategoryDO::getName, reqVO.getName()) - .eqIfPresent(CategoryDO::getStatus, reqVO.getStatus()) - .betweenIfPresent(CategoryDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(CategoryDO::getId)); - } - - default Long selectCountByParentId(Long parentId) { - return selectCount(CategoryDO::getParentId, parentId); - } -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java new file mode 100644 index 000000000..8130d5a46 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.product.dal.mysql.category; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 商品分类 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface ProductCategoryMapper extends BaseMapperX { + + default List selectList(ProductCategoryListReqVO listReqVO) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(ProductCategoryDO::getName, listReqVO.getName()) + .orderByDesc(ProductCategoryDO::getId)); + } + + default Long selectCountByParentId(Long parentId) { + return selectCount(ProductCategoryDO::getParentId, parentId); + } + + default List selectListByStatus(Integer status) { + return selectList(ProductCategoryDO::getStatus, status); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java deleted file mode 100644 index 92c8463dd..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryService.java +++ /dev/null @@ -1,94 +0,0 @@ -package cn.iocoder.yudao.module.product.service.category; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; -import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryListRespVO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; - -// TODO @JeromeSoar:需要 Product 前缀 -/** - * 商品分类 Service 接口 - * - * @author 芋道源码 - */ -public interface CategoryService { - - /** - * 创建商品分类 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createCategory(@Valid CategoryCreateReqVO createReqVO); - - /** - * 更新商品分类 - * - * @param updateReqVO 更新信息 - */ - void updateCategory(@Valid CategoryUpdateReqVO updateReqVO); - - /** - * 删除商品分类 - * - * @param id 编号 - */ - void deleteCategory(Long id); - - /** - * 获得商品分类 - * - * @param id 编号 - * @return 商品分类 - */ - CategoryDO getCategory(Long id); - - /** - * 获得商品分类列表 - * - * @param ids 编号 - * @return 商品分类列表 - */ - List getCategoryList(Collection ids); - - /** - * 获得商品分类分页 - * - * @param pageReqVO 分页查询 - * @return 商品分类分页 - */ - PageResult getCategoryPage(CategoryPageReqVO pageReqVO); - - /** - * 获得商品分类列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 商品分类列表 - */ - List getCategoryList(CategoryExportReqVO exportReqVO); - - /** - * 获得商品分类列表 - * - * @param treeListReqVO 查询条件 - * @return 商品分类列表 - */ - List getCategoryTreeList(CategoryTreeListReqVO treeListReqVO); - - /** - * 验证选择的分类的合法性 - * @param categoryId 分类id - */ - void validatedCategoryById(Long categoryId); - - /** - * app端获得商品分类列表 - * - * @return 商品分类列表 - */ - List getCategoryList(); -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java deleted file mode 100644 index 85e456b2c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImpl.java +++ /dev/null @@ -1,120 +0,0 @@ -package cn.iocoder.yudao.module.product.service.category; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.exception.ErrorCode; -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.*; -import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; -import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; - -/** - * 商品分类 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class CategoryServiceImpl implements CategoryService { - - @Resource - private CategoryMapper categoryMapper; - - @Override - public Long createCategory(CategoryCreateReqVO createReqVO) { - // 校验父分类存在 - this.validateCategoryExists(createReqVO.getParentId(), CATEGORY_PARENT_NOT_EXISTS); - // 插入 - CategoryDO category = CategoryConvert.INSTANCE.convert(createReqVO); - categoryMapper.insert(category); - // 返回 - return category.getId(); - } - - @Override - public void updateCategory(CategoryUpdateReqVO updateReqVO) { - // 校验父分类存在 - this.validateCategoryExists(updateReqVO.getParentId(), CATEGORY_PARENT_NOT_EXISTS); - // 校验分类是否存在 - this.validateCategoryExists(updateReqVO.getId(), CATEGORY_NOT_EXISTS); - // 更新 - CategoryDO updateObj = CategoryConvert.INSTANCE.convert(updateReqVO); - categoryMapper.updateById(updateObj); - } - - @Override - public void deleteCategory(Long id) { - // TODO 芋艿 补充只有不存在商品才可以删除 - // 校验分类是否存在 - CategoryDO categoryDO = this.validateCategoryExists(id, CATEGORY_NOT_EXISTS); - // 校验是否还有子分类 - if (categoryMapper.selectCountByParentId(categoryDO.getParentId()) > 0) { - throw ServiceExceptionUtil.exception(CATEGORY_EXISTS_CHILDREN); - } - // 删除 - categoryMapper.deleteById(id); - } - - private CategoryDO validateCategoryExists(Long id, ErrorCode errorCode) { - // TODO franky:0 要枚举哈 - if (id == 0) { - return new CategoryDO().setId(id); - } - CategoryDO categoryDO = categoryMapper.selectById(id); - if (categoryDO == null) { - throw exception(errorCode); - } - return categoryDO; - } - - @Override - public void validatedCategoryById(Long categoryId) { - this.validateCategoryExists(categoryId, CATEGORY_NOT_EXISTS); - } - - @Override - public CategoryDO getCategory(Long id) { - return categoryMapper.selectById(id); - } - - @Override - public List getCategoryList(Collection ids) { - return categoryMapper.selectBatchIds(ids); - } - - @Override - public PageResult getCategoryPage(CategoryPageReqVO pageReqVO) { - return categoryMapper.selectPage(pageReqVO); - } - - @Override - public List getCategoryList(CategoryExportReqVO exportReqVO) { - return categoryMapper.selectList(exportReqVO); - } - - @Override - public List getCategoryTreeList(CategoryTreeListReqVO treeListReqVO) { - return categoryMapper.selectList(treeListReqVO); - } - - @Override - public List getCategoryList() { - return categoryMapper.selectList() - .stream() - .filter(v->v.getStatus().equals(CommonStatusEnum.ENABLE.getStatus())) - .collect(Collectors.toList()); - } - - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java new file mode 100644 index 000000000..264f81c27 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java @@ -0,0 +1,79 @@ +package cn.iocoder.yudao.module.product.service.category; + +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + +/** + * 商品分类 Service 接口 + * + * @author 芋道源码 + */ +public interface ProductCategoryService { + + /** + * 创建商品分类 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createProductCategory(@Valid ProductCategoryCreateReqVO createReqVO); + + /** + * 更新商品分类 + * + * @param updateReqVO 更新信息 + */ + void updateProductCategory(@Valid ProductCategoryUpdateReqVO updateReqVO); + + /** + * 删除商品分类 + * + * @param id 编号 + */ + void deleteProductCategory(Long id); + + /** + * 获得商品分类 + * + * @param id 编号 + * @return 商品分类 + */ + ProductCategoryDO getProductCategory(Long id); + + /** + * 获得商品分类列表 + * + * @param ids 编号 + * @return 商品分类列表 + */ + List getEnableProductCategoryList(Collection ids); + + /** + * 获得商品分类列表 + * + * @param listReqVO 查询条件 + * @return 商品分类列表 + */ + List getEnableProductCategoryList(ProductCategoryListReqVO listReqVO); + + /** + * 验证选择的商品分类是否合法 + * + * @param id 分类编号 + */ + void validateProductCategory(Long id); + + /** + * 获得开启状态的商品分类列表 + * + * @return 商品分类列表 + */ + List getEnableProductCategoryList(); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java new file mode 100644 index 000000000..65f61b323 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -0,0 +1,125 @@ +package cn.iocoder.yudao.module.product.service.category; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.convert.category.CategoryConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; + +/** + * 商品分类 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class ProductCategoryServiceImpl implements ProductCategoryService { + + @Resource + private ProductCategoryMapper productCategoryMapper; + + @Override + public Long createProductCategory(ProductCategoryCreateReqVO createReqVO) { + // 校验父分类存在 + validateParentProductCategory(createReqVO.getParentId()); + + // 插入 + ProductCategoryDO category = CategoryConvert.INSTANCE.convert(createReqVO); + productCategoryMapper.insert(category); + // 返回 + return category.getId(); + } + + @Override + public void updateProductCategory(ProductCategoryUpdateReqVO updateReqVO) { + // 校验分类是否存在 + validateProductCategoryExists(updateReqVO.getId()); + // 校验父分类存在 + validateParentProductCategory(updateReqVO.getParentId()); + + // 更新 + ProductCategoryDO updateObj = CategoryConvert.INSTANCE.convert(updateReqVO); + productCategoryMapper.updateById(updateObj); + } + + @Override + public void deleteProductCategory(Long id) { + // 校验分类是否存在 + validateProductCategoryExists(id); + // 校验是否还有子分类 + if (productCategoryMapper.selectCountByParentId(id) > 0) { + throw exception(PRODUCT_CATEGORY_EXISTS_CHILDREN); + } + + // 删除 + productCategoryMapper.deleteById(id); + } + + private void validateParentProductCategory(Long id) { + // 如果是根分类,无需验证 + if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + return; + } + // 父分类不存在 + ProductCategoryDO category = productCategoryMapper.selectById(id); + if (category == null) { + throw exception(PRODUCT_CATEGORY_PARENT_NOT_EXISTS); + } + // 父分类不能是二级分类 + if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + throw exception(PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL); + } + } + + private void validateProductCategoryExists(Long id) { + ProductCategoryDO category = productCategoryMapper.selectById(id); + if (category == null) { + throw exception(PRODUCT_CATEGORY_NOT_EXISTS); + } + } + + @Override + public void validateProductCategory(Long id) { + ProductCategoryDO category = productCategoryMapper.selectById(id); + if (category == null) { + throw exception(PRODUCT_CATEGORY_NOT_EXISTS); + } + if (ObjectUtil.notEqual(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { + throw exception(PRODUCT_CATEGORY_DISABLED); + } + } + + @Override + public ProductCategoryDO getProductCategory(Long id) { + return productCategoryMapper.selectById(id); + } + + @Override + public List getEnableProductCategoryList(Collection ids) { + return productCategoryMapper.selectBatchIds(ids); + } + + @Override + public List getEnableProductCategoryList(ProductCategoryListReqVO listReqVO) { + return productCategoryMapper.selectList(listReqVO); + } + + @Override + public List getEnableProductCategoryList() { + return productCategoryMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 0ff02e66f..ea4afb2e7 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java @@ -15,7 +15,7 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; -import cn.iocoder.yudao.module.product.service.category.CategoryService; +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import org.springframework.stereotype.Service; @@ -42,7 +42,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { private ProductSpuMapper ProductSpuMapper; @Resource - private CategoryService categoryService; + private ProductCategoryService categoryService; @Resource private ProductSkuService productSkuService; @@ -54,7 +54,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Transactional public Long createSpu(ProductSpuCreateReqVO createReqVO) { // 校验分类 - categoryService.validatedCategoryById(createReqVO.getCategoryId()); + categoryService.validateProductCategory(createReqVO.getCategoryId()); // 校验SKU List skuCreateReqList = createReqVO.getSkus(); productSkuService.validateSkus(skuCreateReqList); @@ -78,7 +78,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 校验 spu 是否存在 this.validateSpuExists(updateReqVO.getId()); // 校验分类 - categoryService.validatedCategoryById(updateReqVO.getCategoryId()); + categoryService.validateProductCategory(updateReqVO.getCategoryId()); // 校验SKU List skuCreateReqList = updateReqVO.getSkus(); productSkuService.validateSkus(skuCreateReqList); @@ -142,7 +142,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { Long parentId = spuVO.getCategoryId(); categoryArray.addFirst(parentId); while (parentId != 0) { - parentId = categoryService.getCategory(parentId).getParentId(); + parentId = categoryService.getProductCategory(parentId).getParentId(); if (parentId > 0) { categoryArray.addFirst(parentId); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImplTest.java deleted file mode 100644 index 34384201b..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/CategoryServiceImplTest.java +++ /dev/null @@ -1,192 +0,0 @@ -package cn.iocoder.yudao.module.product.service.category; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryExportReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.CategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.CategoryDO; -import cn.iocoder.yudao.module.product.dal.mysql.category.CategoryMapper; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; -import static org.junit.jupiter.api.Assertions.*; - -/** - * {@link CategoryServiceImpl} 的单元测试类 - * - * @author 芋道源码 - */ -@Import(CategoryServiceImpl.class) -public class CategoryServiceImplTest extends BaseDbUnitTest { - - @Resource - private CategoryServiceImpl categoryService; - - @Resource - private CategoryMapper categoryMapper; - - @Test - public void testCreateCategory_success() { - // 准备参数 - CategoryCreateReqVO reqVO = randomPojo(CategoryCreateReqVO.class); - - // 调用 - Long categoryId = categoryService.createCategory(reqVO); - // 断言 - assertNotNull(categoryId); - // 校验记录的属性是否正确 - CategoryDO category = categoryMapper.selectById(categoryId); - assertPojoEquals(reqVO, category); - } - - @Test - public void testUpdateCategory_success() { - // mock 数据 - CategoryDO dbCategory = randomPojo(CategoryDO.class); - categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 - // 准备参数 - CategoryUpdateReqVO reqVO = randomPojo(CategoryUpdateReqVO.class, o -> { - o.setId(dbCategory.getId()); // 设置更新的 ID - }); - - // 调用 - categoryService.updateCategory(reqVO); - // 校验是否更新正确 - CategoryDO category = categoryMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, category); - } - - @Test - public void testUpdateCategory_notExists() { - // 准备参数 - CategoryUpdateReqVO reqVO = randomPojo(CategoryUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> categoryService.updateCategory(reqVO), CATEGORY_NOT_EXISTS); - } - - @Test - public void testDeleteCategory_success() { - // mock 数据 - CategoryDO dbCategory = randomPojo(CategoryDO.class); - categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbCategory.getId(); - - // 调用 - categoryService.deleteCategory(id); - // 校验数据不存在了 - assertNull(categoryMapper.selectById(id)); - } - - @Test - public void testDeleteCategory_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> categoryService.deleteCategory(id), CATEGORY_NOT_EXISTS); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetCategoryPage() { - // mock 数据 - CategoryDO dbCategory = randomPojo(CategoryDO.class, o -> { // 等会查询到 - o.setParentId(null); - o.setName(null); - o.setIcon(null); - o.setBannerUrl(null); - o.setSort(null); - o.setDescription(null); - o.setStatus(null); - o.setCreateTime(null); - }); - categoryMapper.insert(dbCategory); - // 测试 pid 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setParentId(null))); - // 测试 name 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName(null))); - // 测试 icon 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setIcon(null))); - // 测试 bannerUrl 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setBannerUrl(null))); - // 测试 sort 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setSort(null))); - // 测试 description 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setDescription(null))); - // 测试 status 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(null))); - // 测试 createTime 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(null))); - // 准备参数 - CategoryPageReqVO reqVO = new CategoryPageReqVO(); - reqVO.setName(null); - reqVO.setStatus(null); - reqVO.setCreateTime(null); - - // 调用 - PageResult pageResult = categoryService.getCategoryPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbCategory, pageResult.getList().get(0)); - } - - @Test - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 - public void testGetCategoryList() { - // mock 数据 - CategoryDO dbCategory = randomPojo(CategoryDO.class, o -> { // 等会查询到 - o.setParentId(null); - o.setName(null); - o.setIcon(null); - o.setBannerUrl(null); - o.setSort(null); - o.setDescription(null); - o.setStatus(null); - o.setCreateTime(null); - }); - categoryMapper.insert(dbCategory); - // 测试 pid 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setParentId(null))); - // 测试 name 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName(null))); - // 测试 icon 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setIcon(null))); - // 测试 bannerUrl 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setBannerUrl(null))); - // 测试 sort 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setSort(null))); - // 测试 description 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setDescription(null))); - // 测试 status 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(null))); - // 测试 createTime 不匹配 - categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(null))); - // 准备参数 - CategoryExportReqVO reqVO = new CategoryExportReqVO(); - reqVO.setName(null); - reqVO.setStatus(null); - reqVO.setCreateTime(null); - - // 调用 - List list = categoryService.getCategoryList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbCategory, list.get(0)); - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java new file mode 100644 index 000000000..7fc3e2a22 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -0,0 +1,126 @@ +package cn.iocoder.yudao.module.product.service.category; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; +import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PRODUCT_CATEGORY_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link ProductCategoryServiceImpl} 的单元测试类 + * + * @author 芋道源码 + */ +@Import(ProductCategoryServiceImpl.class) +public class ProductCategoryServiceImplTest extends BaseDbUnitTest { + + @Resource + private ProductCategoryServiceImpl productCategoryService; + + @Resource + private ProductCategoryMapper productCategoryMapper; + + @Test + public void testCreateCategory_success() { + // 准备参数 + ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class); + // mock 父类 + ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId())); + productCategoryMapper.insert(parentProductCategory); + + // 调用 + Long categoryId = productCategoryService.createProductCategory(reqVO); + // 断言 + assertNotNull(categoryId); + // 校验记录的属性是否正确 + ProductCategoryDO category = productCategoryMapper.selectById(categoryId); + assertPojoEquals(reqVO, category); + } + + @Test + public void testUpdateCategory_success() { + // mock 数据 + ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class); + productCategoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 + // 准备参数 + ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class, o -> { + o.setId(dbCategory.getId()); // 设置更新的 ID + }); + // mock 父类 + ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> o.setId(reqVO.getParentId())); + productCategoryMapper.insert(parentProductCategory); + + // 调用 + productCategoryService.updateProductCategory(reqVO); + // 校验是否更新正确 + ProductCategoryDO category = productCategoryMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, category); + } + + @Test + public void testUpdateCategory_notExists() { + // 准备参数 + ProductCategoryUpdateReqVO reqVO = randomPojo(ProductCategoryUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> productCategoryService.updateProductCategory(reqVO), PRODUCT_CATEGORY_NOT_EXISTS); + } + + @Test + public void testDeleteCategory_success() { + // mock 数据 + ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class); + productCategoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbCategory.getId(); + + // 调用 + productCategoryService.deleteProductCategory(id); + // 校验数据不存在了 + assertNull(productCategoryMapper.selectById(id)); + } + + @Test + public void testDeleteCategory_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> productCategoryService.deleteProductCategory(id), PRODUCT_CATEGORY_NOT_EXISTS); + } + + @Test + public void testGetCategoryList() { + // mock 数据 + ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class, o -> { // 等会查询到 + o.setName("奥特曼"); + }); + productCategoryMapper.insert(dbCategory); + // 测试 name 不匹配 + productCategoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName("奥特块"))); + // 准备参数 + ProductCategoryListReqVO reqVO = new ProductCategoryListReqVO(); + reqVO.setName("特曼"); + + // 调用 + List list = productCategoryService.getEnableProductCategoryList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbCategory, list.get(0)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml new file mode 100644 index 000000000..3a2079cdc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/application-unit-test.yaml @@ -0,0 +1,50 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + +--- #################### 数据库相关配置 #################### + +spring: + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 + +mybatis-plus: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + type-aliases-package: ${yudao.info.base-package}.module.*.dal.dataobject + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +# Resilience4j 配置项 + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml new file mode 100644 index 000000000..daf756bff --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/logback.xml @@ -0,0 +1,4 @@ + + + + diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql index 94f0b7937..7b0e3e414 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-product-biz/src/test/resources/sql/create_tables.sql @@ -2,8 +2,7 @@ CREATE TABLE IF NOT EXISTS "product_category" ( "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, "parent_id" bigint(20) NOT NULL, "name" varchar(255) NOT NULL, - "icon" varchar(100), - "banner_url" varchar(255) NOT NULL, + "pic_url" varchar(255) NOT NULL, "sort" int(11) NOT NULL, "description" varchar(1024) NOT NULL, "status" tinyint(4) NOT NULL, @@ -12,7 +11,6 @@ CREATE TABLE IF NOT EXISTS "product_category" ( "updater" varchar(64) DEFAULT '', "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint(20) NOT NULL, PRIMARY KEY ("id") ) COMMENT '商品分类'; @@ -29,6 +27,5 @@ CREATE TABLE IF NOT EXISTS "product_brand" ( "updater" varchar(64) DEFAULT '', "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint(20) NOT NULL, PRIMARY KEY ("id") ) COMMENT '品牌';