Commit 2f9eef589b68bffe1ab19a7b68d4a101ecbc5e6e

Authored by YunaiV
1 parent 5474ae87

product:优化商品分类的代码

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 {
15 15 ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");
16 16 ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");
17 17 ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");
18   - ErrorCode CATEGORY_LEVEL_ERROR = new ErrorCode(1008001005, "商品分类不正确,原因:必须使用第三级的商品分类下");
19 18  
20 19 // ========== 商品品牌相关编号 1008002000 ==========
21 20 ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
... ... @@ -33,6 +32,7 @@ public interface ErrorCodeConstants {
33 32  
34 33 // ========== 商品 SPU 1008005000 ==========
35 34 ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");
  35 + ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下");
36 36  
37 37 // ========== 商品 SKU 1008006000 ==========
38 38 ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在");
... ...
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
6 6 import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
7 7  
8 8 import javax.validation.Valid;
9   -import java.util.Collection;
10 9 import java.util.List;
11 10  
12 11 /**
... ... @@ -47,28 +46,27 @@ public interface ProductCategoryService {
47 46 ProductCategoryDO getCategory(Long id);
48 47  
49 48 /**
50   - * 获得商品分类列表
  49 + * 校验商品分类
51 50 *
52   - * @param ids 编号
53   - * @return 商品分类列表
  51 + * @param id 分类编号
54 52 */
55   - List<ProductCategoryDO> getEnableCategoryList(Collection<Long> ids);
  53 + void validateCategory(Long id);
56 54  
57 55 /**
58   - * 获得商品分类列表
  56 + * 获得商品分类的层级
59 57 *
60   - * @param listReqVO 查询条件
61   - * @return 商品分类列表
  58 + * @param id 编号
  59 + * @return 商品分类的层级
62 60 */
63   - List<ProductCategoryDO> getEnableCategoryList(ProductCategoryListReqVO listReqVO);
  61 + Integer getCategoryLevel(Long id);
64 62  
65 63 /**
66   - * 验证选择的商品分类的级别是否合法
67   - * 例如说,商品发布的时候,必须在第 3 级别
  64 + * 获得商品分类列表
68 65 *
69   - * @param id 分类编号
  66 + * @param listReqVO 查询条件
  67 + * @return 商品分类列表
70 68 */
71   - void validateCategoryLevel(Long id);
  69 + List<ProductCategoryDO> getEnableCategoryList(ProductCategoryListReqVO listReqVO);
72 70  
73 71 /**
74 72 * 获得开启状态的商品分类列表
... ...
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;
11 11 import org.springframework.validation.annotation.Validated;
12 12  
13 13 import javax.annotation.Resource;
14   -import java.util.Collection;
15 14 import java.util.List;
16 15 import java.util.Objects;
17 16  
... ... @@ -91,30 +90,39 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
91 90 }
92 91  
93 92 @Override
94   - public void validateCategoryLevel(Long id) {
95   - // TODO @芋艿:在看看,杂能优化下
96   - Long parentId = id;
97   - int i = 2;
98   - for (; i >= 0; --i) {
99   - ProductCategoryDO category = productCategoryMapper.selectById(parentId);
100   - parentId = category.getParentId();
101   - if(Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)){
102   - break;
103   - }
104   - }
105   - if (!Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL) || i != 0) {
106   - throw exception(CATEGORY_LEVEL_ERROR);
107   - }
  93 + public ProductCategoryDO getCategory(Long id) {
  94 + return productCategoryMapper.selectById(id);
108 95 }
109 96  
110 97 @Override
111   - public ProductCategoryDO getCategory(Long id) {
112   - return productCategoryMapper.selectById(id);
  98 + public void validateCategory(Long id) {
  99 + ProductCategoryDO category = productCategoryMapper.selectById(id);
  100 + if (category == null) {
  101 + throw exception(CATEGORY_NOT_EXISTS);
  102 + }
  103 + if (Objects.equals(category.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  104 + throw exception(CATEGORY_DISABLED, category.getName());
  105 + }
113 106 }
114 107  
115 108 @Override
116   - public List<ProductCategoryDO> getEnableCategoryList(Collection<Long> ids) {
117   - return productCategoryMapper.selectBatchIds(ids);
  109 + public Integer getCategoryLevel(Long id) {
  110 + if (Objects.equals(id, ProductCategoryDO.PARENT_ID_NULL)) {
  111 + return 0;
  112 + }
  113 + int level = 1;
  114 + for (int i = 0; i < 100; i++) {
  115 + ProductCategoryDO category = productCategoryMapper.selectById(id);
  116 + // 如果没有父节点,break 结束
  117 + if (category == null
  118 + || Objects.equals(category.getParentId(), ProductCategoryDO.PARENT_ID_NULL)) {
  119 + break;
  120 + }
  121 + // 继续递归父节点
  122 + level++;
  123 + id = category.getParentId();
  124 + }
  125 + return level;
118 126 }
119 127  
120 128 @Override
... ...
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;
36 36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
37 37 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
38 38 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
  39 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR;
39 40  
40 41 /**
41 42 * 商品 SPU Service 实现类
... ... @@ -66,7 +67,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
66 67 @Transactional
67 68 public Long createSpu(ProductSpuCreateReqVO createReqVO) {
68 69 // 校验分类
69   - categoryService.validateCategoryLevel(createReqVO.getCategoryId());
  70 + validateCategory(createReqVO.getCategoryId());
70 71 // 校验品牌
71 72 brandService.validateProductBrand(createReqVO.getBrandId());
72 73 // 校验SKU
... ... @@ -91,7 +92,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
91 92 // 校验 SPU 是否存在
92 93 validateSpuExists(updateReqVO.getId());
93 94 // 校验分类
94   - categoryService.validateCategoryLevel(updateReqVO.getCategoryId());
  95 + validateCategory(updateReqVO.getCategoryId());
95 96 // 校验品牌
96 97 brandService.validateProductBrand(updateReqVO.getBrandId());
97 98 // 校验SKU
... ... @@ -109,6 +110,19 @@ public class ProductSpuServiceImpl implements ProductSpuService {
109 110 productSkuService.updateSkus(updateObj.getId(), updateObj.getName(), updateReqVO.getSkus());
110 111 }
111 112  
  113 + /**
  114 + * 校验商品分类是否合法
  115 + *
  116 + * @param id 商品分类编号
  117 + */
  118 + private void validateCategory(Long id) {
  119 + categoryService.validateCategory(id);
  120 + // 校验层级
  121 + if (categoryService.getCategoryLevel(id) != 3) {
  122 + throw exception(SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR);
  123 + }
  124 + }
  125 +
112 126 @Override
113 127 @Transactional
114 128 public void deleteSpu(Long id) {
... ...
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java
... ... @@ -104,6 +104,25 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest {
104 104 }
105 105  
106 106 @Test
  107 + public void testGetCategoryLevel() {
  108 + // mock 数据
  109 + ProductCategoryDO category1 = randomPojo(ProductCategoryDO.class,
  110 + o -> o.setParentId(ProductCategoryDO.PARENT_ID_NULL));
  111 + productCategoryMapper.insert(category1);
  112 + ProductCategoryDO category2 = randomPojo(ProductCategoryDO.class,
  113 + o -> o.setParentId(category1.getId()));
  114 + productCategoryMapper.insert(category2);
  115 + ProductCategoryDO category3 = randomPojo(ProductCategoryDO.class,
  116 + o -> o.setParentId(category2.getId()));
  117 + productCategoryMapper.insert(category3);
  118 +
  119 + // 调用,并断言
  120 + assertEquals(productCategoryService.getCategoryLevel(category1.getId()), 1);
  121 + assertEquals(productCategoryService.getCategoryLevel(category2.getId()), 2);
  122 + assertEquals(productCategoryService.getCategoryLevel(category3.getId()), 3);
  123 + }
  124 +
  125 + @Test
107 126 public void testGetCategoryList() {
108 127 // mock 数据
109 128 ProductCategoryDO dbCategory = randomPojo(ProductCategoryDO.class, o -> { // 等会查询到
... ...
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 {
187 187 });
188 188  
189 189 Mockito.when(productSkuService.getSkusBySpuId(createReqVO.getId())).thenReturn(productSkuDOS);
190   - Mockito.when(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyValueRespVO);
191   - Mockito.when(productPropertyService.getPropertyVOList(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyRespVOS);
192   -
  190 +// Mockito.when(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyValueRespVO);
  191 +// Mockito.when(productPropertyService.getPropertyVOList(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyRespVOS);
  192 +//
193 193 // 调用
194 194 ProductSpuDetailRespVO spuDetail = productSpuService.getSpuDetail(createReqVO.getId());
195 195  
... ...
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` (
52 52 `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
53 53 PRIMARY KEY (`id`)
54 54 ) COMMENT '商品spu';
  55 +
  56 +CREATE TABLE IF NOT EXISTS `product_category` (
  57 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号',
  58 + `parent_id` bigint DEFAULT NULL COMMENT '父分类编号',
  59 + `name` varchar(128) NOT NULL COMMENT '分类名称',
  60 + `description` varchar(128) NOT NULL COMMENT '分类描述',
  61 + `pic_url` varchar DEFAULT NULL COMMENT '分类图片',
  62 + `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段',
  63 + `status` bit(1) DEFAULT NULL COMMENT '状态',
  64 + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  65 + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  66 + `creator` varchar DEFAULT NULL COMMENT '创建人',
  67 + `updater` varchar DEFAULT NULL COMMENT '更新人',
  68 + `deleted` bit(1) NOT NULL DEFAULT 0 COMMENT '是否删除',
  69 + PRIMARY KEY (`id`)
  70 +) COMMENT '商品分类';
... ...
yudao-ui-app/pages/category/category.vue
... ... @@ -34,7 +34,7 @@
34 34 <u-grid-item v-for="(subItem, subIndex) in item.children" :key="subItem.id">
35 35 <view class="sub-category-item" @click="handleCategory(item, subIndex)">
36 36 <u-icon name="photo" :size="80" v-if="subItem.picUrl === null"></u-icon>
37   - <image :src="item.picUrl" v-if="subItem.picUrl != null" mode='widthFix' />
  37 + <image :src="subItem.picUrl" v-if="subItem.picUrl != null" mode='widthFix' />
38 38 <text class="sub-category-title">{{ subItem.name }}</text>
39 39 </view>
40 40 </u-grid-item>
... ...