diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index c799066df..0e7fb2904 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -11,7 +11,7 @@ public interface ErrorCodeConstants { // ========== 促销活动相关 1-013-001-000 ============ ErrorCode DISCOUNT_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_001_000, "限时折扣活动不存在"); - ErrorCode DISCOUNT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1_013_001_001, "存在商品参加了其它限时折扣活动"); + ErrorCode DISCOUNT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1_013_001_001, "存在商品参加了其它限时折扣活动【{}】"); ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_002, "限时折扣活动已关闭,不能修改"); ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_013_001_003, "限时折扣活动未关闭,不能删除"); ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_004, "限时折扣活动已关闭,不能重复关闭"); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java index 6261285bb..bfbd0d530 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/DiscountActivityController.java @@ -3,9 +3,10 @@ package cn.iocoder.yudao.module.promotion.controller.admin.discount; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; @@ -13,12 +14,12 @@ import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityServic import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import jakarta.annotation.Resource; -import jakarta.validation.Valid; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -33,9 +34,6 @@ public class DiscountActivityController { @Resource private DiscountActivityService discountActivityService; - @Resource - private ProductSpuApi productSpuApi; - @PostMapping("/create") @Operation(summary = "创建限时折扣活动") @PreAuthorize("@ss.hasPermission('promotion:discount-activity:create')") @@ -73,7 +71,7 @@ public class DiscountActivityController { @Operation(summary = "获得限时折扣活动") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") - public CommonResult getDiscountActivity(@RequestParam("id") Long id) { + public CommonResult getDiscountActivity(@RequestParam("id") Long id) { DiscountActivityDO discountActivity = discountActivityService.getDiscountActivity(id); if (discountActivity == null) { return success(null); @@ -88,18 +86,14 @@ public class DiscountActivityController { @PreAuthorize("@ss.hasPermission('promotion:discount-activity:query')") public CommonResult> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) { PageResult pageResult = discountActivityService.getDiscountActivityPage(pageVO); - - if (CollUtil.isEmpty(pageResult.getList())) { // TODO @zhangshuai:方法里的空行,目的是让代码分块,可以更清晰;所以上面这个空格可以不要,而下面判断之后的,空格,其实加下比较好;类似的还有 spuList、以及后面的 convert + if (CollUtil.isEmpty(pageResult.getList())) { return success(PageResult.empty(pageResult.getTotal())); } + // 拼接数据 List products = discountActivityService.getDiscountProductsByActivityId( convertSet(pageResult.getList(), DiscountActivityDO::getId)); - - List spuList = productSpuApi.getSpuList( - convertSet(products, DiscountProductDO::getSpuId)); - - return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult, products, spuList)); + return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult, products)); } } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java deleted file mode 100755 index 85a989c05..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityDetailRespVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.List; - -@Schema(description = "管理后台 - 限时折扣活动的详细 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class DiscountActivityDetailRespVO extends DiscountActivityRespVO { - - /** - * 商品列表 - */ - private List products; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java index 7a9f7f0a0..abc6af8c7 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityRespVO.java @@ -1,11 +1,11 @@ package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; import java.util.List; @@ -25,25 +25,7 @@ public class DiscountActivityRespVO extends DiscountActivityBaseVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; - - @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") // TODO @zhangshuai:属性和属性之间,最多空一行噢; - private Long spuId; - @Schema(description = "限时折扣商品", requiredMode = Schema.RequiredMode.REQUIRED) - private List products; - - // ========== 商品字段 ========== - - // TODO @zhangshuai:一个优惠活动,会关联多个商品,所以它不用返回 spuName 哈; - // TODO 最终界面展示字段就:编号、活动名称、参与商品数、活动状态、开始时间、结束时间、操作 - @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 name 读取 - example = "618大促") - private String spuName; - @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 picUrl 读取 - example = "https://www.iocoder.cn/xx.png") - private String picUrl; - @Schema(description = "商品市场价,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, // 从 SPU 的 marketPrice 读取 - example = "50") - private Integer marketPrice; + private List products; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java index 46d5254cb..fab5a3d1b 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/vo/DiscountActivityUpdateReqVO.java @@ -1,13 +1,13 @@ package cn.iocoder.yudao.module.promotion.controller.admin.discount.vo; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; import java.util.List; @Schema(description = "管理后台 - 限时折扣活动更新 Request VO") @@ -25,6 +25,6 @@ public class DiscountActivityUpdateReqVO extends DiscountActivityBaseVO { */ @NotEmpty(message = "商品列表不能为空") @Valid - private List products; + private List products; } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java index 0ecbd92ef..f7997ed8b 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java @@ -1,20 +1,18 @@ package cn.iocoder.yudao.module.promotion.convert.discount; -import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO; -import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.*; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityUpdateReqVO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import java.util.List; -import java.util.Map; /** * 限时折扣活动 Convert @@ -33,6 +31,7 @@ public interface DiscountActivityConvert { DiscountActivityRespVO convert(DiscountActivityDO bean); List convertList(List list); + List convertList2(List list); List convertList02(List list); @@ -40,98 +39,16 @@ public interface DiscountActivityConvert { PageResult convertPage(PageResult page); default PageResult convertPage(PageResult page, - List discountProductDOList, - List spuList) { + List discountProductDOList) { PageResult pageResult = convertPage(page); - - // 拼接商品 TODO @zhangshuai:类似空行的问题,也可以看看 - Map discountActivityMap = CollectionUtils.convertMap(discountProductDOList, DiscountProductDO::getActivityId); - Map spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId); - pageResult.getList().forEach(item -> { - item.setProducts(convertList2(discountProductDOList)); - item.setSpuId(discountActivityMap.get(item.getId())==null?null: discountActivityMap.get(item.getId()).getSpuId()); - if (item.getSpuId() != null) { - MapUtils.findAndThen(spuMap, item.getSpuId(), - spu -> item.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()).setMarketPrice(spu.getMarketPrice())); - } - - }); + pageResult.getList().forEach(item -> item.setProducts(convertList2(discountProductDOList))); return pageResult; } DiscountProductDO convert(DiscountActivityBaseVO.Product bean); - default DiscountActivityDetailRespVO convert(DiscountActivityDO activity, List products){ - if ( activity == null && products == null ) { - return null; - } - - DiscountActivityDetailRespVO discountActivityDetailRespVO = new DiscountActivityDetailRespVO(); - - if ( activity != null ) { - discountActivityDetailRespVO.setName( activity.getName() ); - discountActivityDetailRespVO.setStartTime( activity.getStartTime() ); - discountActivityDetailRespVO.setEndTime( activity.getEndTime() ); - discountActivityDetailRespVO.setRemark( activity.getRemark() ); - discountActivityDetailRespVO.setId( activity.getId() ); - discountActivityDetailRespVO.setStatus( activity.getStatus() ); - discountActivityDetailRespVO.setCreateTime( activity.getCreateTime() ); - } - if (!products.isEmpty()) { - discountActivityDetailRespVO.setSpuId(products.get(0).getSpuId()); - } - discountActivityDetailRespVO.setProducts( convertList2( products ) ); - - return discountActivityDetailRespVO; + default DiscountActivityRespVO convert(DiscountActivityDO activity, List products) { + return BeanUtils.toBean(activity, DiscountActivityRespVO.class).setProducts(convertList2(products)); } - // =========== 比较是否相等 ========== - /** - * 比较两个限时折扣商品是否相等 - * - * @param productDO 数据库中的商品 - * @param productVO 前端传入的商品 - * @return 是否匹配 - */ - @SuppressWarnings("DuplicatedCode") - default boolean isEquals(DiscountProductDO productDO, DiscountActivityBaseVO.Product productVO) { - if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId()) - || ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId()) - || ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) { - return false; - } - if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) { - return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice()); - } - if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) { - return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent()); - } - return true; - } - - /** - * 比较两个限时折扣商品是否相等 - * 注意,比较时忽略 id 编号 - * - * @param productDO 商品 1 - * @param productVO 商品 2 - * @return 是否匹配 - */ - @SuppressWarnings("DuplicatedCode") - default boolean isEquals(DiscountProductDO productDO, DiscountProductDO productVO) { - if (ObjectUtil.notEqual(productDO.getSpuId(), productVO.getSpuId()) - || ObjectUtil.notEqual(productDO.getSkuId(), productVO.getSkuId()) - || ObjectUtil.notEqual(productDO.getDiscountType(), productVO.getDiscountType())) { - return false; - } - if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PRICE.getType())) { - return ObjectUtil.equal(productDO.getDiscountPrice(), productVO.getDiscountPrice()); - } - if (productDO.getDiscountType().equals(PromotionDiscountTypeEnum.PERCENT.getType())) { - return ObjectUtil.equal(productDO.getDiscountPercent(), productVO.getDiscountPercent()); - } - return true; - } - - } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java index 5257b836d..0cb17b7ec 100755 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java @@ -18,9 +18,6 @@ import java.util.Map; @Mapper public interface DiscountProductMapper extends BaseMapperX { - default List selectListBySkuId(Collection skuIds) { - return selectList(DiscountProductDO::getSkuId, skuIds); - } default List selectListByActivityId(Long activityId) { return selectList(DiscountProductDO::getActivityId, activityId); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java index 0c995267b..6f53a9385 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java @@ -1,11 +1,14 @@ package cn.iocoder.yudao.module.promotion.service.discount; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityBaseVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.discount.vo.DiscountActivityPageReqVO; @@ -27,11 +30,12 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import static cn.hutool.core.collection.CollUtil.intersectionDistinct; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; /** @@ -47,6 +51,8 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { private DiscountActivityMapper discountActivityMapper; @Resource private DiscountProductMapper discountProductMapper; + @Resource + private ProductSkuApi productSkuApi; @Override public List getMatchDiscountProductList(Collection skuIds) { @@ -58,6 +64,8 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { public Long createDiscountActivity(DiscountActivityCreateReqVO createReqVO) { // 校验商品是否冲突 validateDiscountActivityProductConflicts(null, createReqVO.getProducts()); + // 校验商品是否存在 + validateProductExists(createReqVO.getProducts()); // 插入活动 DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO) @@ -82,36 +90,40 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { } // 校验商品是否冲突 validateDiscountActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts()); + // 校验商品是否存在 + validateProductExists(updateReqVO.getProducts()); // 更新活动 DiscountActivityDO updateObj = DiscountActivityConvert.INSTANCE.convert(updateReqVO) .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime())); discountActivityMapper.updateById(updateObj); // 更新商品 - updateDiscountProduct(updateReqVO); + updateDiscountProduct(updateObj, updateReqVO.getProducts()); } - private void updateDiscountProduct(DiscountActivityUpdateReqVO updateReqVO) { - // TODO @zhangshuai:这里的逻辑,可以优化下哈;参考 CombinationActivityServiceImpl 的 updateCombinationProduct,主要是 CollectionUtils.diffList 的使用哈; - // 然后原先是使用 DiscountActivityConvert.INSTANCE.isEquals 对比,现在看看是不是简化就基于 skuId 对比就完事了;之前写的太精细,意义不大; - List dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId()); - // 计算要删除的记录 - List deleteIds = convertList(dbDiscountProducts, DiscountProductDO::getId, - discountProductDO -> updateReqVO.getProducts().stream() - .noneMatch(product -> DiscountActivityConvert.INSTANCE.isEquals(discountProductDO, product))); - if (CollUtil.isNotEmpty(deleteIds)) { - discountProductMapper.deleteBatchIds(deleteIds); + private void updateDiscountProduct(DiscountActivityDO activity, List products) { + // 第一步,对比新老数据,获得添加、修改、删除的列表 + List newList = BeanUtils.toBean(products, DiscountProductDO.class, + product -> product.setActivityId(activity.getId()).setActivityStatus(activity.getStatus()) + .setActivityStartTime(activity.getStartTime()).setActivityEndTime(activity.getEndTime())); + List oldList = discountProductMapper.selectListByActivityId(activity.getId()); + List> diffList = CollectionUtils.diffList(oldList, newList, (oldVal, newVal) -> { + boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId()); + if (same) { + newVal.setId(oldVal.getId()); + } + return same; + }); + + // 第二步,批量添加、修改、删除 + if (CollUtil.isNotEmpty(diffList.get(0))) { + discountProductMapper.insertBatch(diffList.get(0)); } - // 计算新增的记录 - List newDiscountProducts = convertList(updateReqVO.getProducts(), - product -> DiscountActivityConvert.INSTANCE.convert(product) - .setActivityId(updateReqVO.getId()) - .setActivityStartTime(updateReqVO.getStartTime()) - .setActivityEndTime(updateReqVO.getEndTime())); - newDiscountProducts.removeIf(product -> dbDiscountProducts.stream().anyMatch( - dbProduct -> DiscountActivityConvert.INSTANCE.isEquals(dbProduct, product))); // 如果匹配到,说明是更新的 - if (CollectionUtil.isNotEmpty(newDiscountProducts)) { - discountProductMapper.insertBatch(newDiscountProducts); + if (CollUtil.isNotEmpty(diffList.get(1))) { + discountProductMapper.updateBatch(diffList.get(1)); + } + if (CollUtil.isNotEmpty(diffList.get(2))) { + discountProductMapper.deleteBatchIds(convertList(diffList.get(2), DiscountProductDO::getId)); } } @@ -122,22 +134,44 @@ public class DiscountActivityServiceImpl implements DiscountActivityService { * @param products 商品列表 */ private void validateDiscountActivityProductConflicts(Long id, List products) { - if (CollUtil.isEmpty(products)) { - return; - } - // 查询商品参加的活动 - // TODO @zhangshuai:下面 121 这个查询,是不是不用做呀;直接 convert 出 skuId 集合就 ok 啦; - List list = discountProductMapper.selectListByActivityId(id); - // TODO @zhangshuai:一般简单的 stream 方法,建议是使用 CollectionUtils,例如说这里是 convertList 对把。 - List skuIds = list.stream().map(item -> item.getSkuId()).collect(Collectors.toList()); - List matchDiscountProductList = getMatchDiscountProductList(skuIds); - if (id != null) { // 排除自己这个活动 - matchDiscountProductList.removeIf(product -> id.equals(product.getActivityId())); - } - // 如果非空,则说明冲突 - if (CollUtil.isNotEmpty(matchDiscountProductList)) { - throw exception(DISCOUNT_ACTIVITY_SPU_CONFLICTS); + // 1.1 查询所有开启的折扣活动 + List activityList = discountActivityMapper.selectList(DiscountActivityDO::getStatus, + CommonStatusEnum.ENABLE.getStatus()); + if (id != null) { // 时排除自己 + activityList.removeIf(item -> ObjectUtil.equal(item.getId(), id)); } + // 1.2 查询活动下的所有商品 + List productList = discountProductMapper.selectListByActivityId( + convertList(activityList, DiscountActivityDO::getId)); + Map> productListMap = convertMultiMap(productList, DiscountProductDO::getActivityId); + + // 2. 校验商品是否冲突 + activityList.forEach(item -> { + findAndThen(productListMap, item.getId(), discountProducts -> { + if (!intersectionDistinct(convertList(discountProducts, DiscountProductDO::getSpuId), + convertList(products, DiscountActivityBaseVO.Product::getSpuId)).isEmpty()) { + throw exception(DISCOUNT_ACTIVITY_SPU_CONFLICTS, item.getName()); + } + }); + }); + } + + /** + * 校验活动商品是否都存在 + * + * @param products 活动商品 + */ + private void validateProductExists(List products) { + // 1.获得商品所有的 sku + List skus = productSkuApi.getSkuListBySpuId( + convertList(products, DiscountActivityBaseVO.Product::getSpuId)); + Map skuMap = convertMap(skus, ProductSkuRespDTO::getId); + // 2. 校验商品 sku 都存在 + products.forEach(product -> { + if (!skuMap.containsKey(product.getSkuId())) { + throw exception(SKU_NOT_EXISTS); + } + }); } @Override