Commit dd932151391dce7051eb86f8e9a84a663182ce01

Authored by YunaiV
1 parent e72f741d

mall + trade:review 商品管理

Showing 12 changed files with 40 additions and 75 deletions
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ProductConstants.java
1 1 package cn.iocoder.yudao.module.product.enums;
2 2  
3 3 /**
4   - * Product 常量 TODO 把使用到的常量收拢到一块定义替换魔法值
  4 + * Product 常量
5 5 *
6 6 * @author HUIHUI
7 7 */
... ... @@ -12,13 +12,4 @@ public interface ProductConstants {
12 12 */
13 13 int ALERT_STOCK = 10;
14 14  
15   - /**
16   - * 默认商品销量 TODO 默认商品销量为零
17   - */
18   - Integer SALES_COUNT = 0;
19   - /**
20   - * 默认善品浏览量 TODO 默认浏览量为零
21   - */
22   - Integer BROWSE_COUNT = 0;
23   -
24 15 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
1 1 package cn.iocoder.yudao.module.product.controller.app.spu;
2 2  
3   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 5 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
... ... @@ -67,7 +66,7 @@ public class AppProductSpuController {
67 66 }
68 67  
69 68 // 查询商品 SKU
70   - List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId());
  69 + List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
71 70 // 查询商品属性
72 71 List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
73 72 .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
... ... @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.StrUtil;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
7   -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO;
8 7 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
9 8 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
10 9 import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
... ... @@ -23,9 +22,6 @@ import org.mapstruct.factory.Mappers;
23 22 import java.util.ArrayList;
24 23 import java.util.List;
25 24 import java.util.Map;
26   -import java.util.Set;
27   -import java.util.function.Function;
28   -import java.util.stream.Collectors;
29 25  
30 26 import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
31 27 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
... ... @@ -65,8 +61,6 @@ public interface ProductSpuConvert {
65 61 return StrUtil.toString(list);
66 62 }
67 63  
68   - // TODO @puhui999:部分属性,可以通过 mapstruct 的 @Mapping(source = , target = , ) 映射转换,可以查下文档 fix:哈哈 这样确实丝滑哈
69   -
70 64 @Mapping(source = "sliderPicUrls", target = "sliderPicUrls", qualifiedByName = "convertListToString")
71 65 @Mapping(source = "giveCouponTemplateIds", target = "giveCouponTemplateIds", qualifiedByName = "convertListToString")
72 66 @Mapping(source = "activityOrders", target = "activityOrders", qualifiedByName = "convertListToString")
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
... ... @@ -14,11 +14,6 @@ import org.apache.ibatis.annotations.Mapper;
14 14 import java.util.Collection;
15 15 import java.util.List;
16 16  
17   -/**
18   - * 商品 SKU Mapper
19   - *
20   - * @author 芋道源码
21   - */
22 17 @Mapper
23 18 public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
24 19  
... ... @@ -26,11 +21,6 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; {
26 21 return selectList(ProductSkuDO::getSpuId, spuId);
27 22 }
28 23  
29   - default List<ProductSkuDO> selectListBySpuIdAndStatus(Long spuId) {
30   - return selectList(new LambdaQueryWrapperX<ProductSkuDO>()
31   - .eq(ProductSkuDO::getSpuId, spuId));
32   - }
33   -
34 24 default List<ProductSkuDO> selectListBySpuId(Collection<Long> spuIds) {
35 25 return selectList(ProductSkuDO::getSpuId, spuIds);
36 26 }
... ... @@ -73,6 +63,7 @@ public interface ProductSkuMapper extends BaseMapperX&lt;ProductSkuDO&gt; {
73 63 return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
74 64 }
75 65  
  66 + // TODO @puhui999:貌似 IN 不出来数据哈。直接全部查询出来,处理就好列;
76 67 /**
77 68 * 更新 sku 属性值时使用的分页查询
78 69 *
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java
... ... @@ -96,6 +96,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
96 96 }
97 97 }
98 98  
  99 + // TODO @puhui999:不用抽方法,因为不太会复用这个方法哈。
99 100 private void validateProductCategoryIsHaveBindSpu(Long id) {
100 101 Long count = productSpuService.getSpuCountByCategoryId(id);
101 102 if (0 != count) {
... ... @@ -126,9 +127,9 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
126 127 }
127 128 int level = 1;
128 129 // for 的原因,是因为避免脏数据,导致可能的死循环。一般不会超过 100 层哈
129   - for (int i = 0; i < 100; i++) {
130   - ProductCategoryDO category = productCategoryMapper.selectById(id);
  130 + for (int i = 0; i < Byte.MAX_VALUE; i++) {
131 131 // 如果没有父节点,break 结束
  132 + ProductCategoryDO category = productCategoryMapper.selectById(id);
132 133 if (category == null
133 134 || Objects.equals(category.getParentId(), PARENT_ID_NULL)) {
134 135 break;
... ...
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.collection.CollUtil;
4 3 import cn.hutool.core.util.ObjUtil;
5 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO;
... ... @@ -72,7 +71,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
72 71 // 更新
73 72 ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO);
74 73 productPropertyMapper.updateById(updateObj);
75   - // TODO 芋艿:更新时,需要看看 sku 表 fix
  74 + // TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈
76 75 productSkuService.updateSkuProperty(updateObj);
77 76 }
78 77  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java
... ... @@ -73,7 +73,9 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ
73 73 // 更新
74 74 ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO);
75 75 productPropertyValueMapper.updateById(updateObj);
  76 +
76 77 // TODO 芋艿:更新时,需要看看 sku 表 fix
  78 + // TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈
77 79 productSkuService.updateSkuPropertyValue(updateObj);
78 80 }
79 81  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
... ... @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateO
5 5 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
6 6 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
7 7 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
8   -import org.springframework.lang.Nullable;
9 8  
10 9 import java.util.Collection;
11 10 import java.util.List;
... ... @@ -88,14 +87,6 @@ public interface ProductSkuService {
88 87 List<ProductSkuDO> getSkuListBySpuId(Long spuId);
89 88  
90 89 /**
91   - * 基于 SPU 编号和状态,获得商品 SKU 集合
92   - *
93   - * @param spuId SPU 编号
94   - * @return 商品 SKU 集合
95   - */
96   - List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId);
97   -
98   - /**
99 90 * 获得 spu 对应的 SKU 集合
100 91 *
101 92 * @param spuIds spu 编码集合
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
... ... @@ -141,11 +141,6 @@ public class ProductSkuServiceImpl implements ProductSkuService {
141 141 }
142 142  
143 143 @Override
144   - public List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId) {
145   - return productSkuMapper.selectListBySpuIdAndStatus(spuId);
146   - }
147   -
148   - @Override
149 144 public List<ProductSkuDO> getSkuListBySpuId(List<Long> spuIds) {
150 145 return productSkuMapper.selectListBySpuId(spuIds);
151 146 }
... ... @@ -163,9 +158,10 @@ public class ProductSkuServiceImpl implements ProductSkuService {
163 158 @Override
164 159 public int updateSkuProperty(ProductPropertyDO updateObj) {
165 160 // TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现
  161 + // TODO @puhui999:直接全部查询处理,批量处理就好列;一般项目的商品不会超过几十万的哈。
166 162 Long count = productSkuMapper.selectCountByPropertyNotNull();
167 163 int currentPage = 1;
168   - List<ProductSkuDO> skuDOs = new ArrayList<>();
  164 + List<ProductSkuDO> updateSkus = new ArrayList<>();
169 165 if (count == 0) {
170 166 return 0;
171 167 }
... ... @@ -178,25 +174,25 @@ public class ProductSkuServiceImpl implements ProductSkuService {
178 174 if (CollUtil.isEmpty(records)) {
179 175 break;
180 176 }
181   - records.stream()
182   - .filter(sku -> sku.getProperties() != null)
  177 + records.stream().filter(sku -> sku.getProperties() != null)
183 178 .forEach(sku -> sku.getProperties().forEach(property -> {
184 179 if (property.getPropertyId().equals(updateObj.getId())) {
185 180 property.setPropertyName(updateObj.getName());
186   - skuDOs.add(sku);
  181 + updateSkus.add(sku);
187 182 }
188 183 }));
189 184 }
190   - if (CollUtil.isEmpty(skuDOs)) {
  185 + if (CollUtil.isEmpty(updateSkus)) {
191 186 return 0;
192 187 }
  188 + // TODO @puhui999:貌似 updateBatch 自己会拆分批次,这里不用再拆分了
193 189 // 每批处理的大小
194 190 int batchSize = 1000;
195   - for (int i = 0; i < skuDOs.size(); i += batchSize) {
196   - List<ProductSkuDO> batchSkuDOs = skuDOs.subList(i, Math.min(i + batchSize, skuDOs.size()));
  191 + for (int i = 0; i < updateSkus.size(); i += batchSize) {
  192 + List<ProductSkuDO> batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size()));
197 193 productSkuMapper.updateBatch(batchSkuDOs, batchSize);
198 194 }
199   - return skuDOs.size();
  195 + return updateSkus.size();
200 196 }
201 197  
202 198 @Override
... ... @@ -204,7 +200,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
204 200 // TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现
205 201 Long count = productSkuMapper.selectCountByPropertyNotNull();
206 202 int currentPage = 1;
207   - List<ProductSkuDO> skuDOs = new ArrayList<>();
  203 + List<ProductSkuDO> updateSkus = new ArrayList<>();
208 204 if (count == 0) {
209 205 return 0;
210 206 }
... ... @@ -222,20 +218,20 @@ public class ProductSkuServiceImpl implements ProductSkuService {
222 218 .forEach(sku -> sku.getProperties().forEach(property -> {
223 219 if (property.getValueId().equals(updateObj.getId())) {
224 220 property.setValueName(updateObj.getName());
225   - skuDOs.add(sku);
  221 + updateSkus.add(sku);
226 222 }
227 223 }));
228 224 }
229   - if (CollUtil.isEmpty(skuDOs)) {
  225 + if (CollUtil.isEmpty(updateSkus)) {
230 226 return 0;
231 227 }
232 228 // 每批处理的大小
233 229 int batchSize = 1000;
234   - for (int i = 0; i < skuDOs.size(); i += batchSize) {
235   - List<ProductSkuDO> batchSkuDOs = skuDOs.subList(i, Math.min(i + batchSize, skuDOs.size()));
  230 + for (int i = 0; i < updateSkus.size(); i += batchSize) {
  231 + List<ProductSkuDO> batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size()));
236 232 productSkuMapper.updateBatch(batchSkuDOs, batchSize);
237 233 }
238   - return skuDOs.size();
  234 + return updateSkus.size();
239 235 }
240 236  
241 237 @Override
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
... ... @@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO
13 13 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
14 14 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
15 15 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
16   -import cn.iocoder.yudao.module.product.enums.ProductConstants;
17 16 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
18 17 import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
19 18 import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
... ... @@ -27,6 +26,7 @@ import javax.annotation.Resource;
27 26 import java.util.*;
28 27  
29 28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMinValue;
30 30 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
31 31 import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.CATEGORY_LEVEL;
32 32 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
... ... @@ -101,13 +101,13 @@ public class ProductSpuServiceImpl implements ProductSpuService {
101 101 */
102 102 private void initSpuFromSkus(ProductSpuDO spu, List<ProductSkuCreateOrUpdateReqVO> skus) {
103 103 // sku 单价最低的商品的价格
104   - spu.setPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice));
  104 + spu.setPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice));
105 105 // sku 单价最低的商品的市场价格
106   - spu.setMarketPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
  106 + spu.setMarketPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
107 107 // sku单价最低的商品的成本价格
108   - spu.setCostPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice));
  108 + spu.setCostPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice));
109 109 // sku单价最低的商品的条形码
110   - spu.setBarCode(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode));
  110 + spu.setBarCode(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode));
111 111 // skus 库存总数
112 112 spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
113 113 // 若是 spu 已有状态则不处理
... ... @@ -115,9 +115,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
115 115 // 默认状态为上架
116 116 spu.setStatus(ProductSpuStatusEnum.ENABLE.getStatus());
117 117 // 默认商品销量
118   - spu.setSalesCount(ProductConstants.SALES_COUNT);
  118 + spu.setSalesCount(0);
119 119 // 默认商品浏览量
120   - spu.setBrowseCount(ProductConstants.BROWSE_COUNT);
  120 + spu.setBrowseCount(0);
121 121 }
122 122 }
123 123  
... ... @@ -159,6 +159,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
159 159 *
160 160 * @param id id
161 161 */
  162 + // TODO puhui999:感觉不用独立出来一个方法,直接在 deleteSpu 方法中校验即可
162 163 private void validateSpuStatus(Long id) {
163 164 ProductSpuDO spuDO = productSpuMapper.selectById(id);
164 165 // 判断 SPU 状态是否为回收站
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/delivery/DeliveryExpressTemplateController.java
1 1 package cn.iocoder.yudao.module.trade.controller.admin.delivery;
2 2  
3   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 5 import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*;
... ... @@ -71,6 +70,7 @@ public class DeliveryExpressTemplateController {
71 70 return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list));
72 71 }
73 72  
  73 + // TODO @puhui999:DeliveryExpressTemplateRespVO 搞个 simple 的哈
74 74 @GetMapping("/list-all-simple")
75 75 @Operation(summary = "获取快递模版精简信息列表", description = "主要用于前端的下拉选项")
76 76 public CommonResult<List<DeliveryExpressTemplateRespVO>> getSimpleTemplateList() {
... ...
yudao-server/src/main/java/cn/iocoder/yudao/server/controller/DefaultController.java
... ... @@ -27,13 +27,13 @@ public class DefaultController {
27 27 "[微信公众号 yudao-module-mp - 已禁用][参考 https://doc.iocoder.cn/mp/build/ 开启]");
28 28 }
29 29  
30   - @RequestMapping(value = {"/admin-api/product/**", // 商品中心
31   - "/admin-api/trade/**", // 交易中心
32   - "/admin-api/promotion/**"}) // 营销中心
33   - public CommonResult<Boolean> mall404() {
34   - return CommonResult.error(NOT_IMPLEMENTED.getCode(),
35   - "[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]");
36   - }
  30 +// @RequestMapping(value = {"/admin-api/product/**", // 商品中心
  31 +// "/admin-api/trade/**", // 交易中心
  32 +// "/admin-api/promotion/**"}) // 营销中心
  33 +// public CommonResult<Boolean> mall404() {
  34 +// return CommonResult.error(NOT_IMPLEMENTED.getCode(),
  35 +// "[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]");
  36 +// }
37 37  
38 38 @RequestMapping(value = {"/admin-api/report/**"})
39 39 public CommonResult<Boolean> report404() {
... ...