From 2f9eef589b68bffe1ab19a7b68d4a101ecbc5e6e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 14 Dec 2022 20:32:44 +0800 Subject: [PATCH] =?UTF-8?q?product=EF=BC=9A=E4=BC=98=E5=8C=96=E5=95=86?= =?UTF-8?q?=E5=93=81=E5=88=86=E7=B1=BB=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/enums/ErrorCodeConstants.java | 2 +- .../category/ProductCategoryService.java | 24 +++++----- .../category/ProductCategoryServiceImpl.java | 48 +++++++++++-------- .../service/spu/ProductSpuServiceImpl.java | 18 ++++++- .../ProductCategoryServiceImplTest.java | 19 ++++++++ .../spu/ProductSpuServiceImplTest.java | 6 +-- .../src/test/resources/sql/create_tables.sql | 16 +++++++ yudao-ui-app/pages/category/category.vue | 2 +- 8 files changed, 95 insertions(+), 40 deletions(-) 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 ba3798318..b752177e7 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 @@ -15,7 +15,6 @@ public interface ErrorCodeConstants { ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类"); ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除"); ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用"); - ErrorCode CATEGORY_LEVEL_ERROR = new ErrorCode(1008001005, "商品分类不正确,原因:必须使用第三级的商品分类下"); // ========== 商品品牌相关编号 1008002000 ========== ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在"); @@ -33,6 +32,7 @@ public interface ErrorCodeConstants { // ========== 商品 SPU 1008005000 ========== ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在"); + ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下"); // ========== 商品 SKU 1008006000 ========== ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在"); 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 index 118e8118b..32a4c030d 100644 --- 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 @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCateg import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import javax.validation.Valid; -import java.util.Collection; import java.util.List; /** @@ -47,12 +46,19 @@ public interface ProductCategoryService { ProductCategoryDO getCategory(Long id); /** - * 获得商品分类列表 + * 校验商品分类 * - * @param ids 编号 - * @return 商品分类列表 + * @param id 分类编号 */ - List getEnableCategoryList(Collection ids); + void validateCategory(Long id); + + /** + * 获得商品分类的层级 + * + * @param id 编号 + * @return 商品分类的层级 + */ + Integer getCategoryLevel(Long id); /** * 获得商品分类列表 @@ -62,14 +68,6 @@ public interface ProductCategoryService { */ List getEnableCategoryList(ProductCategoryListReqVO listReqVO); - /** - * 验证选择的商品分类的级别是否合法 - * 例如说,商品发布的时候,必须在第 3 级别 - * - * @param id 分类编号 - */ - void validateCategoryLevel(Long id); - /** * 获得开启状态的商品分类列表 * 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 index ffe55e9bf..f0d10b8b8 100644 --- 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 @@ -11,7 +11,6 @@ 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; @@ -90,31 +89,40 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { } } - @Override - public void validateCategoryLevel(Long id) { - // TODO @芋艿:在看看,杂能优化下 - Long parentId = id; - int i = 2; - for (; i >= 0; --i) { - ProductCategoryDO category = productCategoryMapper.selectById(parentId); - parentId = category.getParentId(); - if(Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)){ - break; - } - } - if (!Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL) || i != 0) { - throw exception(CATEGORY_LEVEL_ERROR); - } - } - @Override public ProductCategoryDO getCategory(Long id) { return productCategoryMapper.selectById(id); } @Override - public List getEnableCategoryList(Collection ids) { - return productCategoryMapper.selectBatchIds(ids); + public void validateCategory(Long id) { + ProductCategoryDO category = productCategoryMapper.selectById(id); + if (category == null) { + throw exception(CATEGORY_NOT_EXISTS); + } + if (Objects.equals(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { + throw exception(CATEGORY_DISABLED, category.getName()); + } + } + + @Override + public Integer getCategoryLevel(Long id) { + if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) { + return 0; + } + int level = 1; + for (int i = 0; i < 100; i++) { + ProductCategoryDO category = productCategoryMapper.selectById(id); + // 如果没有父节点,break 结束 + if (category == null + || Objects.equals(category.getParentId(), ProductCategoryDO.PARENT_ID_NULL)) { + break; + } + // 继续递归父节点 + level++; + id = category.getParentId(); + } + return level; } @Override 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 b878a106e..954bafdcd 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 @@ -36,6 +36,7 @@ import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR; /** * 商品 SPU Service 实现类 @@ -66,7 +67,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Transactional public Long createSpu(ProductSpuCreateReqVO createReqVO) { // 校验分类 - categoryService.validateCategoryLevel(createReqVO.getCategoryId()); + validateCategory(createReqVO.getCategoryId()); // 校验品牌 brandService.validateProductBrand(createReqVO.getBrandId()); // 校验SKU @@ -91,7 +92,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { // 校验 SPU 是否存在 validateSpuExists(updateReqVO.getId()); // 校验分类 - categoryService.validateCategoryLevel(updateReqVO.getCategoryId()); + validateCategory(updateReqVO.getCategoryId()); // 校验品牌 brandService.validateProductBrand(updateReqVO.getBrandId()); // 校验SKU @@ -109,6 +110,19 @@ public class ProductSpuServiceImpl implements ProductSpuService { productSkuService.updateSkus(updateObj.getId(), updateObj.getName(), updateReqVO.getSkus()); } + /** + * 校验商品分类是否合法 + * + * @param id 商品分类编号 + */ + private void validateCategory(Long id) { + categoryService.validateCategory(id); + // 校验层级 + if (categoryService.getCategoryLevel(id) != 3) { + throw exception(SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR); + } + } + @Override @Transactional public void deleteSpu(Long id) { 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 index a56c1aa1a..a2963d498 100644 --- 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 @@ -103,6 +103,25 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { assertServiceException(() -> productCategoryService.deleteCategory(id), CATEGORY_NOT_EXISTS); } + @Test + public void testGetCategoryLevel() { + // mock 数据 + ProductCategoryDO category1 = randomPojo(ProductCategoryDO.class, + o -> o.setParentId(ProductCategoryDO.PARENT_ID_NULL)); + productCategoryMapper.insert(category1); + ProductCategoryDO category2 = randomPojo(ProductCategoryDO.class, + o -> o.setParentId(category1.getId())); + productCategoryMapper.insert(category2); + ProductCategoryDO category3 = randomPojo(ProductCategoryDO.class, + o -> o.setParentId(category2.getId())); + productCategoryMapper.insert(category3); + + // 调用,并断言 + assertEquals(productCategoryService.getCategoryLevel(category1.getId()), 1); + assertEquals(productCategoryService.getCategoryLevel(category2.getId()), 2); + assertEquals(productCategoryService.getCategoryLevel(category3.getId()), 3); + } + @Test public void testGetCategoryList() { // mock 数据 diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java index b5a021d7c..dce109048 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java @@ -187,9 +187,9 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { }); Mockito.when(productSkuService.getSkusBySpuId(createReqVO.getId())).thenReturn(productSkuDOS); - Mockito.when(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyValueRespVO); - Mockito.when(productPropertyService.getPropertyVOList(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyRespVOS); - +// Mockito.when(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyValueRespVO); +// Mockito.when(productPropertyService.getPropertyVOList(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyRespVOS); +// // 调用 ProductSpuDetailRespVO spuDetail = productSpuService.getSpuDetail(createReqVO.getId()); 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 fd5abeed0..0d1977fcf 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 @@ -52,3 +52,19 @@ CREATE TABLE IF NOT EXISTS `product_spu` ( `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', PRIMARY KEY (`id`) ) COMMENT '商品spu'; + +CREATE TABLE IF NOT EXISTS `product_category` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号', + `parent_id` bigint DEFAULT NULL COMMENT '父分类编号', + `name` varchar(128) NOT NULL COMMENT '分类名称', + `description` varchar(128) NOT NULL COMMENT '分类描述', + `pic_url` varchar DEFAULT NULL COMMENT '分类图片', + `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段', + `status` bit(1) DEFAULT NULL COMMENT '状态', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `creator` varchar DEFAULT NULL COMMENT '创建人', + `updater` varchar DEFAULT NULL COMMENT '更新人', + `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除', + PRIMARY KEY (`id`) +) COMMENT '商品分类'; diff --git a/yudao-ui-app/pages/category/category.vue b/yudao-ui-app/pages/category/category.vue index 79092e91d..6d2624d84 100644 --- a/yudao-ui-app/pages/category/category.vue +++ b/yudao-ui-app/pages/category/category.vue @@ -34,7 +34,7 @@ - + {{ subItem.name }}