mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	【代码优化】商城: 限时折扣活动
This commit is contained in:
		| @ -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, "限时折扣活动已关闭,不能重复关闭"); | ||||
|  | ||||
| @ -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<DiscountActivityDetailRespVO> getDiscountActivity(@RequestParam("id") Long id) { | ||||
|     public CommonResult<DiscountActivityRespVO> 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<PageResult<DiscountActivityRespVO>> getDiscountActivityPage(@Valid DiscountActivityPageReqVO pageVO) { | ||||
|         PageResult<DiscountActivityDO> 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<DiscountProductDO> products = discountActivityService.getDiscountProductsByActivityId( | ||||
|                 convertSet(pageResult.getList(), DiscountActivityDO::getId)); | ||||
|  | ||||
|         List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList( | ||||
|                 convertSet(products, DiscountProductDO::getSpuId)); | ||||
|  | ||||
|         return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult, products, spuList)); | ||||
|         return success(DiscountActivityConvert.INSTANCE.convertPage(pageResult, products)); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -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<Product> products; | ||||
|  | ||||
| } | ||||
| @ -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<DiscountActivityBaseVO.Product> 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<Product> products; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -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<DiscountActivityCreateReqVO.Product> products; | ||||
|     private List<Product> products; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -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<DiscountActivityRespVO> convertList(List<DiscountActivityDO> list); | ||||
|  | ||||
|     List<DiscountActivityBaseVO.Product> convertList2(List<DiscountProductDO> list); | ||||
|  | ||||
|     List<DiscountProductRespDTO> convertList02(List<DiscountProductDO> list); | ||||
| @ -40,98 +39,16 @@ public interface DiscountActivityConvert { | ||||
|     PageResult<DiscountActivityRespVO> convertPage(PageResult<DiscountActivityDO> page); | ||||
|  | ||||
|     default PageResult<DiscountActivityRespVO> convertPage(PageResult<DiscountActivityDO> page, | ||||
|                                                            List<DiscountProductDO> discountProductDOList, | ||||
|                                                            List<ProductSpuRespDTO> spuList) { | ||||
|                                                            List<DiscountProductDO> discountProductDOList) { | ||||
|         PageResult<DiscountActivityRespVO> pageResult = convertPage(page); | ||||
|  | ||||
|         // 拼接商品 TODO @zhangshuai:类似空行的问题,也可以看看 | ||||
|         Map<Long, DiscountProductDO> discountActivityMap = CollectionUtils.convertMap(discountProductDOList, DiscountProductDO::getActivityId); | ||||
|         Map<Long, ProductSpuRespDTO> 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<DiscountProductDO> 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<DiscountProductDO> 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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -18,9 +18,6 @@ import java.util.Map; | ||||
| @Mapper | ||||
| public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> { | ||||
|  | ||||
|     default List<DiscountProductDO> selectListBySkuId(Collection<Long> skuIds) { | ||||
|         return selectList(DiscountProductDO::getSkuId, skuIds); | ||||
|     } | ||||
|  | ||||
|     default List<DiscountProductDO> selectListByActivityId(Long activityId) { | ||||
|         return selectList(DiscountProductDO::getActivityId, activityId); | ||||
|  | ||||
| @ -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<DiscountProductDO> getMatchDiscountProductList(Collection<Long> 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<DiscountProductDO> dbDiscountProducts = discountProductMapper.selectListByActivityId(updateReqVO.getId()); | ||||
|         // 计算要删除的记录 | ||||
|         List<Long> 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<DiscountActivityCreateReqVO.Product> products) { | ||||
|         // 第一步,对比新老数据,获得添加、修改、删除的列表 | ||||
|         List<DiscountProductDO> newList = BeanUtils.toBean(products, DiscountProductDO.class, | ||||
|                 product -> product.setActivityId(activity.getId()).setActivityStatus(activity.getStatus()) | ||||
|                         .setActivityStartTime(activity.getStartTime()).setActivityEndTime(activity.getEndTime())); | ||||
|         List<DiscountProductDO> oldList = discountProductMapper.selectListByActivityId(activity.getId()); | ||||
|         List<List<DiscountProductDO>> 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<DiscountProductDO> 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<DiscountActivityBaseVO.Product> products) { | ||||
|         if (CollUtil.isEmpty(products)) { | ||||
|             return; | ||||
|         } | ||||
|         // 查询商品参加的活动 | ||||
|         // TODO @zhangshuai:下面 121 这个查询,是不是不用做呀;直接 convert 出 skuId 集合就 ok 啦; | ||||
|         List<DiscountProductDO> list = discountProductMapper.selectListByActivityId(id); | ||||
|         // TODO @zhangshuai:一般简单的 stream 方法,建议是使用 CollectionUtils,例如说这里是 convertList 对把。 | ||||
|         List<Long> skuIds = list.stream().map(item -> item.getSkuId()).collect(Collectors.toList()); | ||||
|         List<DiscountProductDO> 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<DiscountActivityDO> activityList = discountActivityMapper.selectList(DiscountActivityDO::getStatus, | ||||
|                 CommonStatusEnum.ENABLE.getStatus()); | ||||
|         if (id != null) { // 时排除自己 | ||||
|             activityList.removeIf(item -> ObjectUtil.equal(item.getId(), id)); | ||||
|         } | ||||
|         // 1.2 查询活动下的所有商品 | ||||
|         List<DiscountProductDO> productList = discountProductMapper.selectListByActivityId( | ||||
|                 convertList(activityList, DiscountActivityDO::getId)); | ||||
|         Map<Long, List<DiscountProductDO>> 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<DiscountActivityBaseVO.Product> products) { | ||||
|         // 1.获得商品所有的 sku | ||||
|         List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId( | ||||
|                 convertList(products, DiscountActivityBaseVO.Product::getSpuId)); | ||||
|         Map<Long, ProductSkuRespDTO> skuMap = convertMap(skus, ProductSkuRespDTO::getId); | ||||
|         // 2. 校验商品 sku 都存在 | ||||
|         products.forEach(product -> { | ||||
|             if (!skuMap.containsKey(product.getSkuId())) { | ||||
|                 throw exception(SKU_NOT_EXISTS); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999