mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 15:21:53 +08:00
mall + trade:review 商品管理
This commit is contained in:
parent
e72f741d02
commit
dd93215139
@ -1,7 +1,7 @@
|
||||
package cn.iocoder.yudao.module.product.enums;
|
||||
|
||||
/**
|
||||
* Product 常量 TODO 把使用到的常量收拢到一块定义替换魔法值
|
||||
* Product 常量
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@ -12,13 +12,4 @@ public interface ProductConstants {
|
||||
*/
|
||||
int ALERT_STOCK = 10;
|
||||
|
||||
/**
|
||||
* 默认商品销量 TODO 默认商品销量为零
|
||||
*/
|
||||
Integer SALES_COUNT = 0;
|
||||
/**
|
||||
* 默认善品浏览量 TODO 默认浏览量为零
|
||||
*/
|
||||
Integer BROWSE_COUNT = 0;
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.iocoder.yudao.module.product.controller.app.spu;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
||||
@ -67,7 +66,7 @@ public class AppProductSpuController {
|
||||
}
|
||||
|
||||
// 查询商品 SKU
|
||||
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId());
|
||||
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
|
||||
// 查询商品属性
|
||||
List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
|
||||
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
|
||||
|
@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||
import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
|
||||
@ -23,9 +22,6 @@ import org.mapstruct.factory.Mappers;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
@ -65,8 +61,6 @@ public interface ProductSpuConvert {
|
||||
return StrUtil.toString(list);
|
||||
}
|
||||
|
||||
// TODO @puhui999:部分属性,可以通过 mapstruct 的 @Mapping(source = , target = , ) 映射转换,可以查下文档 fix:哈哈 这样确实丝滑哈
|
||||
|
||||
@Mapping(source = "sliderPicUrls", target = "sliderPicUrls", qualifiedByName = "convertListToString")
|
||||
@Mapping(source = "giveCouponTemplateIds", target = "giveCouponTemplateIds", qualifiedByName = "convertListToString")
|
||||
@Mapping(source = "activityOrders", target = "activityOrders", qualifiedByName = "convertListToString")
|
||||
|
@ -14,11 +14,6 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SKU Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
|
||||
|
||||
@ -26,11 +21,6 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
|
||||
return selectList(ProductSkuDO::getSpuId, spuId);
|
||||
}
|
||||
|
||||
default List<ProductSkuDO> selectListBySpuIdAndStatus(Long spuId) {
|
||||
return selectList(new LambdaQueryWrapperX<ProductSkuDO>()
|
||||
.eq(ProductSkuDO::getSpuId, spuId));
|
||||
}
|
||||
|
||||
default List<ProductSkuDO> selectListBySpuId(Collection<Long> spuIds) {
|
||||
return selectList(ProductSkuDO::getSpuId, spuIds);
|
||||
}
|
||||
@ -73,6 +63,7 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
|
||||
return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
|
||||
}
|
||||
|
||||
// TODO @puhui999:貌似 IN 不出来数据哈。直接全部查询出来,处理就好列;
|
||||
/**
|
||||
* 更新 sku 属性值时使用的分页查询
|
||||
*
|
||||
|
@ -96,6 +96,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO @puhui999:不用抽方法,因为不太会复用这个方法哈。
|
||||
private void validateProductCategoryIsHaveBindSpu(Long id) {
|
||||
Long count = productSpuService.getSpuCountByCategoryId(id);
|
||||
if (0 != count) {
|
||||
@ -126,9 +127,9 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||
}
|
||||
int level = 1;
|
||||
// for 的原因,是因为避免脏数据,导致可能的死循环。一般不会超过 100 层哈
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ProductCategoryDO category = productCategoryMapper.selectById(id);
|
||||
for (int i = 0; i < Byte.MAX_VALUE; i++) {
|
||||
// 如果没有父节点,break 结束
|
||||
ProductCategoryDO category = productCategoryMapper.selectById(id);
|
||||
if (category == null
|
||||
|| Objects.equals(category.getParentId(), PARENT_ID_NULL)) {
|
||||
break;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.iocoder.yudao.module.product.service.property;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO;
|
||||
@ -72,7 +71,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
|
||||
// 更新
|
||||
ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO);
|
||||
productPropertyMapper.updateById(updateObj);
|
||||
// TODO 芋艿:更新时,需要看看 sku 表 fix
|
||||
// TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈
|
||||
productSkuService.updateSkuProperty(updateObj);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,9 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ
|
||||
// 更新
|
||||
ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO);
|
||||
productPropertyValueMapper.updateById(updateObj);
|
||||
|
||||
// TODO 芋艿:更新时,需要看看 sku 表 fix
|
||||
// TODO @puhui:是不是只要传递变量,不传递整个 updateObj 变量哈
|
||||
productSkuService.updateSkuPropertyValue(updateObj);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateO
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -87,14 +86,6 @@ public interface ProductSkuService {
|
||||
*/
|
||||
List<ProductSkuDO> getSkuListBySpuId(Long spuId);
|
||||
|
||||
/**
|
||||
* 基于 SPU 编号和状态,获得商品 SKU 集合
|
||||
*
|
||||
* @param spuId SPU 编号
|
||||
* @return 商品 SKU 集合
|
||||
*/
|
||||
List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId);
|
||||
|
||||
/**
|
||||
* 获得 spu 对应的 SKU 集合
|
||||
*
|
||||
|
@ -140,11 +140,6 @@ public class ProductSkuServiceImpl implements ProductSkuService {
|
||||
return productSkuMapper.selectListBySpuId(spuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId) {
|
||||
return productSkuMapper.selectListBySpuIdAndStatus(spuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSkuDO> getSkuListBySpuId(List<Long> spuIds) {
|
||||
return productSkuMapper.selectListBySpuId(spuIds);
|
||||
@ -163,9 +158,10 @@ public class ProductSkuServiceImpl implements ProductSkuService {
|
||||
@Override
|
||||
public int updateSkuProperty(ProductPropertyDO updateObj) {
|
||||
// TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现
|
||||
// TODO @puhui999:直接全部查询处理,批量处理就好列;一般项目的商品不会超过几十万的哈。
|
||||
Long count = productSkuMapper.selectCountByPropertyNotNull();
|
||||
int currentPage = 1;
|
||||
List<ProductSkuDO> skuDOs = new ArrayList<>();
|
||||
List<ProductSkuDO> updateSkus = new ArrayList<>();
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -178,25 +174,25 @@ public class ProductSkuServiceImpl implements ProductSkuService {
|
||||
if (CollUtil.isEmpty(records)) {
|
||||
break;
|
||||
}
|
||||
records.stream()
|
||||
.filter(sku -> sku.getProperties() != null)
|
||||
records.stream().filter(sku -> sku.getProperties() != null)
|
||||
.forEach(sku -> sku.getProperties().forEach(property -> {
|
||||
if (property.getPropertyId().equals(updateObj.getId())) {
|
||||
property.setPropertyName(updateObj.getName());
|
||||
skuDOs.add(sku);
|
||||
updateSkus.add(sku);
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (CollUtil.isEmpty(skuDOs)) {
|
||||
if (CollUtil.isEmpty(updateSkus)) {
|
||||
return 0;
|
||||
}
|
||||
// TODO @puhui999:貌似 updateBatch 自己会拆分批次,这里不用再拆分了
|
||||
// 每批处理的大小
|
||||
int batchSize = 1000;
|
||||
for (int i = 0; i < skuDOs.size(); i += batchSize) {
|
||||
List<ProductSkuDO> batchSkuDOs = skuDOs.subList(i, Math.min(i + batchSize, skuDOs.size()));
|
||||
for (int i = 0; i < updateSkus.size(); i += batchSize) {
|
||||
List<ProductSkuDO> batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size()));
|
||||
productSkuMapper.updateBatch(batchSkuDOs, batchSize);
|
||||
}
|
||||
return skuDOs.size();
|
||||
return updateSkus.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -204,7 +200,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
|
||||
// TODO 看了一下数据库有关于 json 字符串的处理,怕数据库出现兼容问题这里还是用数据库常规操作来实现
|
||||
Long count = productSkuMapper.selectCountByPropertyNotNull();
|
||||
int currentPage = 1;
|
||||
List<ProductSkuDO> skuDOs = new ArrayList<>();
|
||||
List<ProductSkuDO> updateSkus = new ArrayList<>();
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -222,20 +218,20 @@ public class ProductSkuServiceImpl implements ProductSkuService {
|
||||
.forEach(sku -> sku.getProperties().forEach(property -> {
|
||||
if (property.getValueId().equals(updateObj.getId())) {
|
||||
property.setValueName(updateObj.getName());
|
||||
skuDOs.add(sku);
|
||||
updateSkus.add(sku);
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (CollUtil.isEmpty(skuDOs)) {
|
||||
if (CollUtil.isEmpty(updateSkus)) {
|
||||
return 0;
|
||||
}
|
||||
// 每批处理的大小
|
||||
int batchSize = 1000;
|
||||
for (int i = 0; i < skuDOs.size(); i += batchSize) {
|
||||
List<ProductSkuDO> batchSkuDOs = skuDOs.subList(i, Math.min(i + batchSize, skuDOs.size()));
|
||||
for (int i = 0; i < updateSkus.size(); i += batchSize) {
|
||||
List<ProductSkuDO> batchSkuDOs = updateSkus.subList(i, Math.min(i + batchSize, updateSkus.size()));
|
||||
productSkuMapper.updateBatch(batchSkuDOs, batchSize);
|
||||
}
|
||||
return skuDOs.size();
|
||||
return updateSkus.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,7 +13,6 @@ import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO
|
||||
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.enums.ProductConstants;
|
||||
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
|
||||
import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
|
||||
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
||||
@ -27,6 +26,7 @@ import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMinValue;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
|
||||
import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.CATEGORY_LEVEL;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
|
||||
@ -101,13 +101,13 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
*/
|
||||
private void initSpuFromSkus(ProductSpuDO spu, List<ProductSkuCreateOrUpdateReqVO> skus) {
|
||||
// sku 单价最低的商品的价格
|
||||
spu.setPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||
spu.setPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice));
|
||||
// sku 单价最低的商品的市场价格
|
||||
spu.setMarketPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
|
||||
spu.setMarketPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
|
||||
// sku单价最低的商品的成本价格
|
||||
spu.setCostPrice(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice));
|
||||
spu.setCostPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice));
|
||||
// sku单价最低的商品的条形码
|
||||
spu.setBarCode(CollectionUtils.getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode));
|
||||
spu.setBarCode(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode));
|
||||
// skus 库存总数
|
||||
spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
|
||||
// 若是 spu 已有状态则不处理
|
||||
@ -115,9 +115,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
// 默认状态为上架
|
||||
spu.setStatus(ProductSpuStatusEnum.ENABLE.getStatus());
|
||||
// 默认商品销量
|
||||
spu.setSalesCount(ProductConstants.SALES_COUNT);
|
||||
spu.setSalesCount(0);
|
||||
// 默认商品浏览量
|
||||
spu.setBrowseCount(ProductConstants.BROWSE_COUNT);
|
||||
spu.setBrowseCount(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,6 +159,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
// TODO puhui999:感觉不用独立出来一个方法,直接在 deleteSpu 方法中校验即可
|
||||
private void validateSpuStatus(Long id) {
|
||||
ProductSpuDO spuDO = productSpuMapper.selectById(id);
|
||||
// 判断 SPU 状态是否为回收站
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.iocoder.yudao.module.trade.controller.admin.delivery;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.expresstemplate.*;
|
||||
@ -71,6 +70,7 @@ public class DeliveryExpressTemplateController {
|
||||
return success(DeliveryExpressTemplateConvert.INSTANCE.convertList(list));
|
||||
}
|
||||
|
||||
// TODO @puhui999:DeliveryExpressTemplateRespVO 搞个 simple 的哈
|
||||
@GetMapping("/list-all-simple")
|
||||
@Operation(summary = "获取快递模版精简信息列表", description = "主要用于前端的下拉选项")
|
||||
public CommonResult<List<DeliveryExpressTemplateRespVO>> getSimpleTemplateList() {
|
||||
|
@ -27,13 +27,13 @@ public class DefaultController {
|
||||
"[微信公众号 yudao-module-mp - 已禁用][参考 https://doc.iocoder.cn/mp/build/ 开启]");
|
||||
}
|
||||
|
||||
@RequestMapping(value = {"/admin-api/product/**", // 商品中心
|
||||
"/admin-api/trade/**", // 交易中心
|
||||
"/admin-api/promotion/**"}) // 营销中心
|
||||
public CommonResult<Boolean> mall404() {
|
||||
return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
"[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]");
|
||||
}
|
||||
// @RequestMapping(value = {"/admin-api/product/**", // 商品中心
|
||||
// "/admin-api/trade/**", // 交易中心
|
||||
// "/admin-api/promotion/**"}) // 营销中心
|
||||
// public CommonResult<Boolean> mall404() {
|
||||
// return CommonResult.error(NOT_IMPLEMENTED.getCode(),
|
||||
// "[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]");
|
||||
// }
|
||||
|
||||
@RequestMapping(value = {"/admin-api/report/**"})
|
||||
public CommonResult<Boolean> report404() {
|
||||
|
Loading…
Reference in New Issue
Block a user