Commit 31f5b27d015ab382d496746a2019bb7707717815
1 parent
8940375e
feature(uniapp分类): review
Showing
18 changed files
with
142 additions
and
158 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
| ... | ... | @@ -24,9 +24,11 @@ public interface ErrorCodeConstants { |
| 24 | 24 | |
| 25 | 25 | // ========== 商品规格名称 1008003000 ========== |
| 26 | 26 | ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "规格名称不存在"); |
| 27 | + ErrorCode PROPERTY_EXISTS = new ErrorCode(1008003001, "规格名称已存在"); | |
| 27 | 28 | |
| 28 | 29 | // ========== 规格值 1008004000 ========== |
| 29 | 30 | ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "规格值不存在"); |
| 31 | + ErrorCode PROPERTY_VALUE_EXISTS = new ErrorCode(1008004001, "规格值已存在"); | |
| 30 | 32 | |
| 31 | 33 | // ========== 商品 SPU 1008005000 ========== |
| 32 | 34 | ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在"); | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java
| ... | ... | @@ -56,7 +56,7 @@ public class ProductPropertyController { |
| 56 | 56 | @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) |
| 57 | 57 | @PreAuthorize("@ss.hasPermission('product:property:query')") |
| 58 | 58 | public CommonResult<ProductPropertyRespVO> getProperty(@RequestParam("id") Long id) { |
| 59 | - return success(productPropertyService.getPropertyResp(id)); | |
| 59 | + return success(productPropertyService.getProperty(id)); | |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | @GetMapping("/list") | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java
| ... | ... | @@ -55,9 +55,8 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO { |
| 55 | 55 | |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | - // TODO @luowenfeng: 只返回 categoryId 可以么? 如果是为了前端修改时使用, 会拿到下拉列表, 自动选中合适的. 可以微信讨论下, 我也不完全确定哈; | |
| 59 | 58 | @ApiModelProperty(value = "分类 id 数组,一直递归到一级父节点", example = "[1,2,4]") |
| 60 | - private List<Long> categoryIds; | |
| 59 | + private Long categoryIds; | |
| 61 | 60 | |
| 62 | 61 | @ApiModelProperty(value = "规格属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]") |
| 63 | 62 | private List<ProductPropertyViewRespVO> productPropertyViews; | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java
| 1 | 1 | package cn.iocoder.yudao.module.product.convert.property; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO; | |
| 4 | 5 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; |
| 6 | 7 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; |
| 8 | +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; | |
| 7 | 9 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; |
| 10 | +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; | |
| 8 | 11 | import org.mapstruct.Mapper; |
| 9 | 12 | import org.mapstruct.factory.Mappers; |
| 10 | 13 | |
| ... | ... | @@ -23,6 +26,8 @@ public interface ProductPropertyConvert { |
| 23 | 26 | ProductPropertyDO convert(ProductPropertyCreateReqVO bean); |
| 24 | 27 | |
| 25 | 28 | ProductPropertyDO convert(ProductPropertyUpdateReqVO bean); |
| 29 | + ProductPropertyAndValueRespVO convert(ProductPropertyRespVO bean); | |
| 30 | + | |
| 26 | 31 | |
| 27 | 32 | ProductPropertyRespVO convert(ProductPropertyDO bean); |
| 28 | 33 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java
| ... | ... | @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.Pro |
| 7 | 7 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; |
| 8 | 8 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 9 | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 10 | 12 | /** |
| 11 | 13 | * 规格名称 Mapper |
| 12 | 14 | * |
| ... | ... | @@ -23,4 +25,9 @@ public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> { |
| 23 | 25 | .orderByDesc(ProductPropertyDO::getId)); |
| 24 | 26 | } |
| 25 | 27 | |
| 28 | + default ProductPropertyDO selectByName(String name) { | |
| 29 | + return selectOne(new LambdaQueryWrapperX<ProductPropertyDO>() | |
| 30 | + .likeIfPresent(ProductPropertyDO::getName, name)); | |
| 31 | + } | |
| 32 | + | |
| 26 | 33 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java
| ... | ... | @@ -17,19 +17,20 @@ import java.util.List; |
| 17 | 17 | @Mapper |
| 18 | 18 | public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> { |
| 19 | 19 | |
| 20 | - // TODO @luowenfeng:方法名,selectListByXXX。mapper 的操作都是 crud | |
| 21 | - default List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) { | |
| 22 | - // TODO @franky:调用父类的 selectList | |
| 20 | + default List<ProductPropertyValueDO> selectListByPropertyValueListByPropertyId(List<Long> propertyIds) { | |
| 23 | 21 | return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>() |
| 24 | 22 | .inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds)); |
| 25 | 23 | } |
| 26 | 24 | |
| 25 | + default ProductPropertyValueDO selectByName(Long propertyId, String name) { | |
| 26 | + return selectOne(new LambdaQueryWrapperX<ProductPropertyValueDO>() | |
| 27 | + .eq(ProductPropertyValueDO::getPropertyId, propertyId) | |
| 28 | + .eq(ProductPropertyValueDO::getName, name)); | |
| 29 | + } | |
| 30 | + | |
| 27 | 31 | default void deletePropertyValueByPropertyId(Long propertyId) { |
| 28 | - // TODO @luowenfeng:delete(new ) 即可 | |
| 29 | - LambdaQueryWrapperX<ProductPropertyValueDO> queryWrapperX = new LambdaQueryWrapperX<>(); | |
| 30 | - queryWrapperX.eq(ProductPropertyValueDO::getPropertyId, propertyId) | |
| 31 | - .eq(ProductPropertyValueDO::getDeleted, false); | |
| 32 | - delete(queryWrapperX); | |
| 32 | + delete(new LambdaQueryWrapperX<ProductPropertyValueDO>().eq(ProductPropertyValueDO::getPropertyId, propertyId) | |
| 33 | + .eq(ProductPropertyValueDO::getDeleted, false)); | |
| 33 | 34 | } |
| 34 | 35 | |
| 35 | 36 | default PageResult<ProductPropertyValueDO> selectPage(ProductPropertyValuePageReqVO reqVO) { | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
| ... | ... | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 5 | 5 | import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO; |
| 6 | 6 | import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; |
| 7 | +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |
| 7 | 8 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| 8 | 9 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 10 | |
| ... | ... | @@ -17,20 +18,13 @@ import java.util.List; |
| 17 | 18 | @Mapper |
| 18 | 19 | public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> { |
| 19 | 20 | |
| 20 | - // TODO @franky:方法名 selectList; 可以直接调用 selectList | |
| 21 | - default List<ProductSkuDO> selectListBySpuIds(List<Long> spuIds) { | |
| 22 | - return selectList(ProductSkuDO::getSpuId, spuIds); | |
| 23 | - } | |
| 24 | - | |
| 25 | 21 | default List<ProductSkuDO> selectListBySpuId(Long spuId) { |
| 26 | 22 | return selectList(ProductSkuDO::getSpuId, spuId); |
| 27 | 23 | } |
| 28 | 24 | |
| 29 | 25 | default void deleteBySpuId(Long spuId) { |
| 30 | - // TODO @franky:直接 delete(new XXX) 即可,更简洁一些 | |
| 31 | - LambdaQueryWrapperX<ProductSkuDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<ProductSkuDO>() | |
| 32 | - .eqIfPresent(ProductSkuDO::getSpuId, spuId); | |
| 33 | - delete(lambdaQueryWrapperX); | |
| 26 | + delete(new LambdaQueryWrapperX<ProductSkuDO>() | |
| 27 | + .eqIfPresent(ProductSkuDO::getSpuId, spuId)); | |
| 34 | 28 | } |
| 35 | 29 | |
| 36 | 30 | default void decrementStockBatch(List<SkuDecrementStockBatchReqDTO.Item> items) { |
| ... | ... | @@ -45,4 +39,7 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> { |
| 45 | 39 | this.update(null, lambdaUpdateWrapper); |
| 46 | 40 | } |
| 47 | 41 | } |
| 42 | + default List<ProductSkuDO> selectRemindSpuIds(){ | |
| 43 | + return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock")); | |
| 44 | + } | |
| 48 | 45 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java
| ... | ... | @@ -93,18 +93,15 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { |
| 93 | 93 | @Override |
| 94 | 94 | public void validateCategoryLevel(Long id) { |
| 95 | 95 | Long parentId = id; |
| 96 | - for (int i = 0; i < 3; i++) { // TODO @luowenfeng: 建议还是先获得 level; 然后判断 level 是不是满足; 这样逻辑会更清晰一些; | |
| 97 | - if (Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)) { | |
| 98 | - throw exception(CATEGORY_LEVEL_ERROR); | |
| 99 | - } | |
| 96 | + int i = 2; | |
| 97 | + for (; i >= 0; --i) { | |
| 100 | 98 | ProductCategoryDO category = productCategoryMapper.selectById(parentId); |
| 101 | - if (category == null) { | |
| 102 | - // TODO @luowenfeng: 应该抛出 CATEGORY_LEVEL_ERROR | |
| 103 | - throw exception(CATEGORY_NOT_EXISTS); | |
| 104 | - } | |
| 105 | 99 | parentId = category.getParentId(); |
| 100 | + if(Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)){ | |
| 101 | + break; | |
| 102 | + } | |
| 106 | 103 | } |
| 107 | - if (!Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL)) { | |
| 104 | + if (!Objects.equals(parentId, ProductCategoryDO.PARENT_ID_NULL) || i != 0) { | |
| 108 | 105 | throw exception(CATEGORY_LEVEL_ERROR); |
| 109 | 106 | } |
| 110 | 107 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java
| ... | ... | @@ -39,14 +39,6 @@ public interface ProductPropertyService { |
| 39 | 39 | void deleteProperty(Long id); |
| 40 | 40 | |
| 41 | 41 | /** |
| 42 | - * 获得规格名称 | |
| 43 | - * | |
| 44 | - * @param id 编号 | |
| 45 | - * @return 规格名称 | |
| 46 | - */ | |
| 47 | - ProductPropertyDO getProperty(Long id); | |
| 48 | - | |
| 49 | - /** | |
| 50 | 42 | * 获得规格名称列表 |
| 51 | 43 | * @param listReqVO 集合查询 |
| 52 | 44 | * @return 规格名称集合 |
| ... | ... | @@ -61,8 +53,12 @@ public interface ProductPropertyService { |
| 61 | 53 | */ |
| 62 | 54 | PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO); |
| 63 | 55 | |
| 64 | - // TODO luowenfeng: getProperty 就可以拉, 不用到 Resp | |
| 65 | - ProductPropertyRespVO getPropertyResp(Long id); | |
| 56 | + /** | |
| 57 | + * | |
| 58 | + * @param id 编号 | |
| 59 | + * @return 规格名称 | |
| 60 | + */ | |
| 61 | + ProductPropertyRespVO getProperty(Long id); | |
| 66 | 62 | |
| 67 | 63 | /** |
| 68 | 64 | * 根据规格属性编号的集合,获得对应的规格 + 规格值的集合 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.product.service.property; |
| 2 | 2 | |
| 3 | -import cn.hutool.core.bean.BeanUtil; | |
| 4 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 5 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | |
| 6 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 7 | -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; | |
| 8 | 7 | import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; |
| 9 | -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; | |
| 10 | -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; | |
| 11 | 8 | import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; |
| 12 | 9 | import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert; |
| 13 | 10 | import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; |
| ... | ... | @@ -19,13 +16,12 @@ import org.springframework.transaction.annotation.Transactional; |
| 19 | 16 | import org.springframework.validation.annotation.Validated; |
| 20 | 17 | |
| 21 | 18 | import javax.annotation.Resource; |
| 22 | -import java.util.Arrays; | |
| 23 | 19 | import java.util.Collection; |
| 24 | 20 | import java.util.List; |
| 25 | 21 | import java.util.Map; |
| 26 | -import java.util.stream.Collectors; | |
| 27 | 22 | |
| 28 | 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 24 | +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_EXISTS; | |
| 29 | 25 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_NOT_EXISTS; |
| 30 | 26 | |
| 31 | 27 | /** |
| ... | ... | @@ -46,7 +42,10 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { |
| 46 | 42 | @Override |
| 47 | 43 | @Transactional(rollbackFor = Exception.class) |
| 48 | 44 | public Long createProperty(ProductPropertyCreateReqVO createReqVO) { |
| 49 | - // TODO @luowenfeng: 插入和更新的时候, 要校验 name 的唯一性; | |
| 45 | + // 校验存在 | |
| 46 | + if(productPropertyMapper.selectByName(createReqVO.getName()) != null){ | |
| 47 | + throw exception(PROPERTY_EXISTS); | |
| 48 | + } | |
| 50 | 49 | // 插入 |
| 51 | 50 | ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO); |
| 52 | 51 | productPropertyMapper.insert(property); |
| ... | ... | @@ -59,6 +58,9 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { |
| 59 | 58 | public void updateProperty(ProductPropertyUpdateReqVO updateReqVO) { |
| 60 | 59 | // 校验存在 |
| 61 | 60 | this.validatePropertyExists(updateReqVO.getId()); |
| 61 | + if(productPropertyMapper.selectByName(updateReqVO.getName()) != null){ | |
| 62 | + throw exception(PROPERTY_EXISTS); | |
| 63 | + } | |
| 62 | 64 | // 更新 |
| 63 | 65 | ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); |
| 64 | 66 | productPropertyMapper.updateById(updateObj); |
| ... | ... | @@ -81,11 +83,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { |
| 81 | 83 | } |
| 82 | 84 | |
| 83 | 85 | @Override |
| 84 | - public ProductPropertyDO getProperty(Long id) { | |
| 85 | - return productPropertyMapper.selectById(id); | |
| 86 | - } | |
| 87 | - | |
| 88 | - @Override | |
| 89 | 86 | public List<ProductPropertyRespVO> getPropertyList(ProductPropertyListReqVO listReqVO) { |
| 90 | 87 | return ProductPropertyConvert.INSTANCE.convertList(productPropertyMapper.selectList(new LambdaQueryWrapperX<ProductPropertyDO>() |
| 91 | 88 | .likeIfPresent(ProductPropertyDO::getName, listReqVO.getName()) |
| ... | ... | @@ -96,29 +93,16 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { |
| 96 | 93 | public PageResult<ProductPropertyRespVO> getPropertyPage(ProductPropertyPageReqVO pageReqVO) { |
| 97 | 94 | //获取属性列表 |
| 98 | 95 | PageResult<ProductPropertyDO> pageResult = productPropertyMapper.selectPage(pageReqVO); |
| 99 | - PageResult<ProductPropertyRespVO> propertyRespVOPageResult = ProductPropertyConvert.INSTANCE.convertPage(pageResult); | |
| 100 | - // TODO @luofengwen: 下面的代码, 如果不要,可以删除哈; git 可以拿到记录的 | |
| 101 | -// List<Long> propertyIds = propertyRespVOPageResult.getList().stream().map(ProductPropertyAndValueRespVO::getId).collect(Collectors.toList()); | |
| 102 | -// | |
| 103 | -// //获取属性值列表 | |
| 104 | -// List<ProductPropertyValueDO> productPropertyValueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds); | |
| 105 | -// List<ProductPropertyValueRespVO> propertyValueRespVOList = ProductPropertyValueConvert.INSTANCE.convertList(productPropertyValueDOList); | |
| 106 | -// //组装一对多 | |
| 107 | -// propertyRespVOPageResult.getList().forEach(x->{ | |
| 108 | -// Long propertyId = x.getId(); | |
| 109 | -// List<ProductPropertyValueRespVO> valueDOList = propertyValueRespVOList.stream().filter(v -> v.getPropertyId().equals(propertyId)).collect(Collectors.toList()); | |
| 110 | -// x.setValues(valueDOList); | |
| 111 | -// }); | |
| 112 | - return propertyRespVOPageResult; | |
| 96 | + return ProductPropertyConvert.INSTANCE.convertPage(pageResult); | |
| 113 | 97 | } |
| 114 | 98 | |
| 115 | 99 | private List<ProductPropertyValueDO> getPropertyValueListByPropertyId(List<Long> propertyIds) { |
| 116 | - return productPropertyValueMapper.getPropertyValueListByPropertyId(propertyIds); | |
| 100 | + return productPropertyValueMapper.selectListByPropertyValueListByPropertyId(propertyIds); | |
| 117 | 101 | } |
| 118 | 102 | |
| 119 | 103 | @Override |
| 120 | - public ProductPropertyRespVO getPropertyResp(Long id) { | |
| 121 | - ProductPropertyDO property = getProperty(id); | |
| 104 | + public ProductPropertyRespVO getProperty(Long id) { | |
| 105 | + ProductPropertyDO property = productPropertyMapper.selectById(id); | |
| 122 | 106 | return ProductPropertyConvert.INSTANCE.convert(property); |
| 123 | 107 | } |
| 124 | 108 | |
| ... | ... | @@ -132,17 +116,12 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { |
| 132 | 116 | List<ProductPropertyRespVO> propertyList = getPropertyList(listReqVO); |
| 133 | 117 | |
| 134 | 118 | // 查询属性值 |
| 135 | - List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.getPropertyValueListByPropertyId(CollectionUtils.convertList(propertyList, ProductPropertyRespVO::getId)); | |
| 136 | -// CollectionUtils.convertMultiMap() // TODO @luofengwen: 可以使用这个方法哈 | |
| 137 | - Map<Long, List<ProductPropertyValueRespVO>> valueDOMap = valueDOList.stream() | |
| 138 | - .map(ProductPropertyValueConvert.INSTANCE::convert) | |
| 139 | - .collect(Collectors.groupingBy(ProductPropertyValueRespVO::getPropertyId)); | |
| 140 | - // 组装 TODO @luowenfeng: CollectionUtils 转换哈; | |
| 141 | - return propertyList.stream().map(m -> { | |
| 142 | - // TODO @luowenfeng: 使用 mapstruct convert 哈 | |
| 143 | - ProductPropertyAndValueRespVO productPropertyAndValueRespVO = BeanUtil.copyProperties(m, ProductPropertyAndValueRespVO.class); | |
| 144 | - productPropertyAndValueRespVO.setValues(valueDOMap.get(m.getId())); | |
| 119 | + List<ProductPropertyValueDO> valueDOList = productPropertyValueMapper.selectListByPropertyValueListByPropertyId(CollectionUtils.convertList(propertyList, ProductPropertyRespVO::getId)); | |
| 120 | + Map<Long, List<ProductPropertyValueDO>> valueDOMap = CollectionUtils.convertMultiMap(valueDOList, ProductPropertyValueDO::getPropertyId); | |
| 121 | + return CollectionUtils.convertList(propertyList, m -> { | |
| 122 | + ProductPropertyAndValueRespVO productPropertyAndValueRespVO = ProductPropertyConvert.INSTANCE.convert(m); | |
| 123 | + productPropertyAndValueRespVO.setValues(ProductPropertyValueConvert.INSTANCE.convertList(valueDOMap.get(m.getId()))); | |
| 145 | 124 | return productPropertyAndValueRespVO; |
| 146 | - }).collect(Collectors.toList()); | |
| 125 | + }); | |
| 147 | 126 | } |
| 148 | 127 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java
| ... | ... | @@ -15,9 +15,12 @@ import org.springframework.validation.annotation.Validated; |
| 15 | 15 | import javax.annotation.Resource; |
| 16 | 16 | import java.util.List; |
| 17 | 17 | |
| 18 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 19 | +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS; | |
| 20 | + | |
| 18 | 21 | /** |
| 19 | - * <p> TODO @luowenfeng: 类注释 | |
| 20 | - * | |
| 22 | + * <p> | |
| 23 | + * 规格值 Service 实现类 | |
| 21 | 24 | * </p> |
| 22 | 25 | * |
| 23 | 26 | * @author LuoWenFeng |
| ... | ... | @@ -31,7 +34,9 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ |
| 31 | 34 | |
| 32 | 35 | @Override |
| 33 | 36 | public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) { |
| 34 | - // TODO @luowenfeng: 需要校验下在这个 propertyId, 新增和更新, name 都要唯一 | |
| 37 | + if (productPropertyValueMapper.selectByName(createReqVO.getPropertyId(), createReqVO.getName()) != null) { | |
| 38 | + throw exception(PROPERTY_VALUE_EXISTS); | |
| 39 | + } | |
| 35 | 40 | ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(createReqVO); |
| 36 | 41 | productPropertyValueMapper.insert(convert); |
| 37 | 42 | return convert.getId(); |
| ... | ... | @@ -39,6 +44,9 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ |
| 39 | 44 | |
| 40 | 45 | @Override |
| 41 | 46 | public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) { |
| 47 | + if (productPropertyValueMapper.selectByName(updateReqVO.getPropertyId(), updateReqVO.getName()) != null) { | |
| 48 | + throw exception(PROPERTY_VALUE_EXISTS); | |
| 49 | + } | |
| 42 | 50 | ProductPropertyValueDO convert = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); |
| 43 | 51 | productPropertyValueMapper.updateById(convert); |
| 44 | 52 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
| ... | ... | @@ -83,12 +83,11 @@ public interface ProductSkuService { |
| 83 | 83 | */ |
| 84 | 84 | void deleteSkuBySpuId(Long spuId); |
| 85 | 85 | |
| 86 | - // TODO @luowenfeng: 可以改成返回 ProductSkuDO 列表; 然后, 上层业务在做处理; | |
| 87 | 86 | /** |
| 88 | 87 | * 获得商品预警中的 SPU 集合 |
| 89 | 88 | * |
| 90 | 89 | * @return 商品spuId集合 |
| 91 | 90 | */ |
| 92 | - List<Long> getRemindSpuIds(); | |
| 91 | + List<ProductSkuDO> getRemindSpuIds(); | |
| 93 | 92 | |
| 94 | 93 | } | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
| ... | ... | @@ -124,12 +124,12 @@ public class ProductSkuServiceImpl implements ProductSkuService { |
| 124 | 124 | |
| 125 | 125 | @Override |
| 126 | 126 | public List<ProductSkuDO> getSkusBySpuId(Long spuId) { |
| 127 | - return productSkuMapper.selectListBySpuIds(Collections.singletonList(spuId)); | |
| 127 | + return productSkuMapper.selectList(ProductSkuDO::getSpuId, spuId); | |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | 130 | @Override |
| 131 | 131 | public List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds) { |
| 132 | - return productSkuMapper.selectListBySpuIds(spuIds); | |
| 132 | + return productSkuMapper.selectList(ProductSkuDO::getSpuId, spuIds); | |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | 135 | @Override |
| ... | ... | @@ -138,10 +138,8 @@ public class ProductSkuServiceImpl implements ProductSkuService { |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | @Override |
| 141 | - public List<Long> getRemindSpuIds() { | |
| 142 | - // TODO @luowenfeng: mybatis plus 不能出现在 Service 哈; 把这个查询, 下沉一个方法到 mapper 里 | |
| 143 | - List<ProductSkuDO> productSkuDOS = productSkuMapper.selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock")); | |
| 144 | - return productSkuDOS.stream().map(ProductSkuDO::getSpuId).distinct().collect(Collectors.toList()); | |
| 141 | + public List<ProductSkuDO> getRemindSpuIds() { | |
| 142 | + return productSkuMapper.selectRemindSpuIds(); | |
| 145 | 143 | } |
| 146 | 144 | |
| 147 | 145 | @Override |
| ... | ... | @@ -160,12 +158,6 @@ public class ProductSkuServiceImpl implements ProductSkuService { |
| 160 | 158 | return String.join("-", collect, String.valueOf(v.getId())); |
| 161 | 159 | }) |
| 162 | 160 | .collect(Collectors.toMap(v -> v.split("-")[0], v -> Long.valueOf(v.split("-")[1]))); |
| 163 | -// Map<String, Long> existsSkuMap2 = CollectionUtils.convertMap(existsSkus, productSkuDO -> { | |
| 164 | -// if (CollUtil.isEmpty(productSkuDO.getProperties())) { | |
| 165 | -// return ""; | |
| 166 | -// } | |
| 167 | -// return StrUtil.join("-", convertList(productSkuDO.getProperties(), ProductSkuDO.Property::getValueId)); | |
| 168 | -// }, ProductSkuDO::getId); | |
| 169 | 161 | |
| 170 | 162 | // 拆分三个集合,新插入的、需要更新的、需要删除的 |
| 171 | 163 | List<ProductSkuDO> insertSkus = new ArrayList<>(); | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
| ... | ... | @@ -72,7 +72,7 @@ public interface ProductSpuService { |
| 72 | 72 | PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO); |
| 73 | 73 | |
| 74 | 74 | /** |
| 75 | - * 获得商品 SPU 分页 // TODO @luowenfeng: 中文和英文之间, 要有一个空格; 这样, 阅读起来会更清晰; 我已经都改啦 | |
| 75 | + * 获得商品 SPU 分页 | |
| 76 | 76 | * |
| 77 | 77 | * @param pageReqVO 分页查询 |
| 78 | 78 | * @return 商品spu分页 | ... | ... |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
| ... | ... | @@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO; |
| 14 | 14 | import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO; |
| 15 | 15 | import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert; |
| 16 | 16 | import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; |
| 17 | +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; | |
| 17 | 18 | import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; |
| 18 | 19 | import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; |
| 19 | 20 | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum; |
| ... | ... | @@ -134,7 +135,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { |
| 134 | 135 | List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkusBySpuId(id)); |
| 135 | 136 | respVO.setSkus(skuReqs); |
| 136 | 137 | // 组合 sku 规格属性 |
| 137 | - if(spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) { | |
| 138 | + if (spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) { | |
| 138 | 139 | List<ProductSkuRespVO.Property> properties = new ArrayList<>(); |
| 139 | 140 | for (ProductSpuDetailRespVO.Sku productSkuRespVO : skuReqs) { |
| 140 | 141 | properties.addAll(productSkuRespVO.getProperties()); |
| ... | ... | @@ -162,18 +163,19 @@ public class ProductSpuServiceImpl implements ProductSpuService { |
| 162 | 163 | respVO.setProductPropertyViews(productPropertyViews); |
| 163 | 164 | } |
| 164 | 165 | // 组合分类 |
| 165 | - if (null != respVO.getCategoryId()) { | |
| 166 | - LinkedList<Long> categoryArray = new LinkedList<>(); | |
| 167 | - Long parentId = respVO.getCategoryId(); | |
| 168 | - categoryArray.addFirst(parentId); | |
| 169 | - while (parentId != 0) { | |
| 170 | - parentId = categoryService.getCategory(parentId).getParentId(); | |
| 171 | - if (parentId > 0) { | |
| 172 | - categoryArray.addFirst(parentId); | |
| 173 | - } | |
| 174 | - } | |
| 175 | - respVO.setCategoryIds(categoryArray); | |
| 176 | - } | |
| 166 | +// if (null != respVO.getCategoryId()) { | |
| 167 | +// LinkedList<Long> categoryArray = new LinkedList<>(); | |
| 168 | +// Long parentId = respVO.getCategoryId(); | |
| 169 | +// categoryArray.addFirst(parentId); | |
| 170 | +// while (parentId != 0) { | |
| 171 | +// parentId = categoryService.getCategory(parentId).getParentId(); | |
| 172 | +// if (parentId > 0) { | |
| 173 | +// categoryArray.addFirst(parentId); | |
| 174 | +// } | |
| 175 | +// } | |
| 176 | +// | |
| 177 | +// } | |
| 178 | + respVO.setCategoryIds(respVO.getCategoryId()); | |
| 177 | 179 | } |
| 178 | 180 | return respVO; |
| 179 | 181 | } |
| ... | ... | @@ -190,12 +192,10 @@ public class ProductSpuServiceImpl implements ProductSpuService { |
| 190 | 192 | |
| 191 | 193 | @Override |
| 192 | 194 | public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) { |
| 193 | - List<Long> remindSpuIds= null; | |
| 194 | - // todo @yunai 预警类型的判断应该可以优化,看下怎么处理 | |
| 195 | - // TODO @luowenfeng: 先这么简单处理; 性能应该影响不大的; | |
| 196 | - if(pageReqVO.getTabStatus() != null && pageReqVO.getTabStatus() == 2){ | |
| 197 | - remindSpuIds= productSkuService.getRemindSpuIds(); | |
| 198 | - if(remindSpuIds.isEmpty()){ | |
| 195 | + List<Long> remindSpuIds = null; | |
| 196 | + if (pageReqVO.getTabStatus() != null && pageReqVO.getTabStatus() == 2) { | |
| 197 | + remindSpuIds = productSkuService.getRemindSpuIds().stream().map(ProductSkuDO::getSpuId).distinct().collect(Collectors.toList()); | |
| 198 | + if (remindSpuIds.isEmpty()) { | |
| 199 | 199 | remindSpuIds.add(null); |
| 200 | 200 | } |
| 201 | 201 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/order/PayOrderApiImpl.java
| 1 | -package cn.iocoder.yudao.module.pay.api.order; | |
| 2 | - | |
| 3 | -import org.springframework.stereotype.Service; | |
| 4 | -import org.springframework.transaction.annotation.Transactional; | |
| 5 | - | |
| 6 | -/** | |
| 7 | - * @author LeeYan9 | |
| 8 | - * @since 2022-09-06 | |
| 9 | - */ | |
| 10 | -@Service | |
| 11 | -public class PayOrderApiImpl implements PayOrderApi { | |
| 12 | - | |
| 13 | - @Override | |
| 14 | - @Transactional(rollbackFor = Exception.class) | |
| 15 | - public Long createPayOrder(PayOrderInfoCreateReqDTO reqDTO) { | |
| 16 | - return null; | |
| 17 | - } | |
| 18 | - | |
| 19 | -} | |
| 1 | +//package cn.iocoder.yudao.module.pay.api.order; | |
| 2 | +// | |
| 3 | +//import org.springframework.stereotype.Service; | |
| 4 | +//import org.springframework.transaction.annotation.Transactional; | |
| 5 | +// | |
| 6 | +///** | |
| 7 | +// * @author LeeYan9 | |
| 8 | +// * @since 2022-09-06 | |
| 9 | +// */ | |
| 10 | +//@Service | |
| 11 | +//public class PayOrderApiImpl implements PayOrderApi { | |
| 12 | +// | |
| 13 | +// @Override | |
| 14 | +// @Transactional(rollbackFor = Exception.class) | |
| 15 | +// public Long createPayOrder(PayOrderInfoCreateReqDTO reqDTO) { | |
| 16 | +// return null; | |
| 17 | +// } | |
| 18 | +// | |
| 19 | +//} | ... | ... |
yudao-ui-admin/src/views/mall/product/spu/save.vue
| ... | ... | @@ -39,8 +39,7 @@ |
| 39 | 39 | <el-tab-pane label="价格库存" name="rates" class="rates"> |
| 40 | 40 | <el-form ref="rates" :model="ratesForm" :rules="rules"> |
| 41 | 41 | <el-form-item label="启用多规格"> |
| 42 | - <!-- TODO @luowenfeng: 1) activeSwitch 可以考虑改成; specSwitch, 更清晰一点, activeSwitch 太通用了; changeRadio 改成 changeSpecSwitch --> | |
| 43 | - <el-switch v-model="activeSwitch" @change="changeRadio"></el-switch> | |
| 42 | + <el-switch v-model="specSwitch" @change="changeSpecSwitch"></el-switch> | |
| 44 | 43 | </el-form-item> |
| 45 | 44 | |
| 46 | 45 | <!-- 动态添加规格属性 --> |
| ... | ... | @@ -67,7 +66,7 @@ |
| 67 | 66 | <!-- 规格明细 --> |
| 68 | 67 | <el-form-item label="规格明细"> |
| 69 | 68 | <el-table :data="ratesForm.rates" border style="width: 100%" ref="ratesTable"> |
| 70 | - <template v-if="this.activeSwitch"> | |
| 69 | + <template v-if="this.specSwitch"> | |
| 71 | 70 | <el-table-column :key="index" v-for="(item, index) in dynamicSpec.filter(v => v.specName !== undefined)" |
| 72 | 71 | :label="item.specName"> |
| 73 | 72 | <template slot-scope="scope"> |
| ... | ... | @@ -81,7 +80,7 @@ |
| 81 | 80 | style="width: 100px; height: 50px"/> |
| 82 | 81 | </template> |
| 83 | 82 | </el-table-column> |
| 84 | - <template v-if="this.activeSwitch"> | |
| 83 | + <template v-if="this.specSwitch"> | |
| 85 | 84 | <el-table-column label="sku名称" :render-header="addRedStar" key="91"> |
| 86 | 85 | <template slot-scope="scope"> |
| 87 | 86 | <el-form-item :prop="'rates.'+ scope.$index + '.name'" |
| ... | ... | @@ -148,13 +147,13 @@ |
| 148 | 147 | <el-input v-model="scope.row.barCode"></el-input> |
| 149 | 148 | </template> |
| 150 | 149 | </el-table-column> |
| 151 | - <template v-if="this.activeSwitch"> | |
| 150 | + <template v-if="this.specSwitch"> | |
| 152 | 151 | <el-table-column fixed="right" label="操作" width="50" key="100"> |
| 153 | 152 | <template slot-scope="scope"> |
| 154 | 153 | <el-button @click="scope.row.status = 1" type="text" size="small" |
| 155 | - v-show="scope.row.status == undefined || scope.row.status == 0 ">禁用 | |
| 154 | + v-show="scope.row.status === undefined || scope.row.status === 0 ">禁用 | |
| 156 | 155 | </el-button> |
| 157 | - <el-button @click="scope.row.status = 0" type="text" size="small" v-show="scope.row.status == 1"> | |
| 156 | + <el-button @click="scope.row.status = 0" type="text" size="small" v-show="scope.row.status === 1"> | |
| 158 | 157 | 启用 |
| 159 | 158 | </el-button> |
| 160 | 159 | </template> |
| ... | ... | @@ -220,7 +219,7 @@ export default { |
| 220 | 219 | }, |
| 221 | 220 | data() { |
| 222 | 221 | return { |
| 223 | - activeSwitch: false, | |
| 222 | + specSwitch: false, | |
| 224 | 223 | activeName: "base", |
| 225 | 224 | propName: { |
| 226 | 225 | checkStrictly: true, |
| ... | ... | @@ -287,7 +286,7 @@ export default { |
| 287 | 286 | methods: { |
| 288 | 287 | removeSpec(index) { |
| 289 | 288 | this.dynamicSpec.splice(index, 1); |
| 290 | - this.changeRadio() | |
| 289 | + this.changeSpecSwitch() | |
| 291 | 290 | }, |
| 292 | 291 | // 必选标识 |
| 293 | 292 | addRedStar(h, {column}) { |
| ... | ... | @@ -296,10 +295,10 @@ export default { |
| 296 | 295 | h('span', ' ' + column.label) |
| 297 | 296 | ]; |
| 298 | 297 | }, |
| 299 | - changeRadio() { | |
| 300 | - this.activeSwitch ? this.ratesForm.spec = 2 : this.ratesForm.spec = 1; | |
| 298 | + changeSpecSwitch() { | |
| 299 | + this.specSwitch ? this.ratesForm.spec = 2 : this.ratesForm.spec = 1; | |
| 301 | 300 | this.$refs.ratesTable.doLayout(); |
| 302 | - if (this.ratesForm.spec == 1) { | |
| 301 | + if (this.ratesForm.spec === 1) { | |
| 303 | 302 | this.ratesForm.rates = [{}] |
| 304 | 303 | } else { |
| 305 | 304 | this.ratesForm.rates = [] |
| ... | ... | @@ -380,7 +379,7 @@ export default { |
| 380 | 379 | }) |
| 381 | 380 | |
| 382 | 381 | // 动态规格调整字段 |
| 383 | - if (this.activeSwitch) { | |
| 382 | + if (this.specSwitch) { | |
| 384 | 383 | rates.forEach(r => { |
| 385 | 384 | let properties = [] |
| 386 | 385 | Array.of(r.spec).forEach(s => { |
| ... | ... | @@ -391,7 +390,7 @@ export default { |
| 391 | 390 | obj = Array.of(s); |
| 392 | 391 | } |
| 393 | 392 | obj.forEach((v, i) => { |
| 394 | - let specValue = this.dynamicSpec[i].specValue.find(o => o.name == v); | |
| 393 | + let specValue = this.dynamicSpec[i].specValue.find(o => o.name === v); | |
| 395 | 394 | let propertie = {}; |
| 396 | 395 | propertie.propertyId = this.dynamicSpec[i].specId; |
| 397 | 396 | propertie.valueId = specValue.id; |
| ... | ... | @@ -414,17 +413,20 @@ export default { |
| 414 | 413 | } |
| 415 | 414 | form.skus = rates; |
| 416 | 415 | form.specType = this.ratesForm.spec; |
| 417 | - form.categoryId = form.categoryIds[this.baseForm.categoryIds.length - 1]; | |
| 416 | + | |
| 417 | + let category = form.categoryIds instanceof Array ? form.categoryIds: Array.of(form.categoryIds) | |
| 418 | + console.log(category) | |
| 419 | + form.categoryId = category[category.length - 1]; | |
| 418 | 420 | |
| 419 | 421 | if (form.id == null) { |
| 420 | - createSpu(form).then((response) => { | |
| 422 | + createSpu(form).then(() => { | |
| 421 | 423 | this.$modal.msgSuccess("新增成功"); |
| 422 | 424 | }) |
| 423 | 425 | .then(()=>{ |
| 424 | 426 | this.cancel(); |
| 425 | 427 | }) |
| 426 | 428 | } else { |
| 427 | - updateSpu(form).then((response) => { | |
| 429 | + updateSpu(form).then(() => { | |
| 428 | 430 | this.$modal.msgSuccess("修改成功"); |
| 429 | 431 | }) |
| 430 | 432 | .then(()=>{ |
| ... | ... | @@ -443,8 +445,8 @@ export default { |
| 443 | 445 | }, |
| 444 | 446 | // 添加规格项目 |
| 445 | 447 | changeSpec(val) { |
| 446 | - let obj = this.propertyPageList.find(o => o.id == val); | |
| 447 | - let spec = this.dynamicSpec.find(o => o.specId == val) | |
| 448 | + let obj = this.propertyPageList.find(o => o.id === val); | |
| 449 | + let spec = this.dynamicSpec.find(o => o.specId === val) | |
| 448 | 450 | spec.specId = obj.id; |
| 449 | 451 | spec.specName = obj.name; |
| 450 | 452 | spec.specValue = obj.values; |
| ... | ... | @@ -471,8 +473,8 @@ export default { |
| 471 | 473 | r.price = this.divide(r.price, 100) |
| 472 | 474 | r.costPrice = this.divide(r.costPrice, 100) |
| 473 | 475 | }) |
| 474 | - if (this.ratesForm.spec == 2) { | |
| 475 | - this.activeSwitch = true; | |
| 476 | + if (this.ratesForm.spec === 2) { | |
| 477 | + this.specSwitch = true; | |
| 476 | 478 | data.productPropertyViews.forEach(p => { |
| 477 | 479 | let obj = {}; |
| 478 | 480 | obj.specId = p.propertyId; |
| ... | ... | @@ -483,7 +485,7 @@ export default { |
| 483 | 485 | data.skus.forEach(s => { |
| 484 | 486 | s.spec = []; |
| 485 | 487 | s.properties.forEach(sp => { |
| 486 | - let spec = data.productPropertyViews.find(o => o.propertyId == sp.propertyId).propertyValues.find(v => v.id == sp.valueId).name; | |
| 488 | + let spec = data.productPropertyViews.find(o => o.propertyId === sp.propertyId).propertyValues.find(v => v.id === sp.valueId).name; | |
| 487 | 489 | s.spec.push(spec) |
| 488 | 490 | }) |
| 489 | 491 | }) | ... | ... |