Kaynağa Gözat

【代码优化】商城:完善满减送的计算逻辑

YunaiV 8 ay önce
ebeveyn
işleme
6f740fab7c

+ 3 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java

@@ -113,14 +113,16 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
         Map<Long, ProductCategoryDO> categoryMap = CollectionUtils.convertMap(list, ProductCategoryDO::getId);
         // 校验
         ids.forEach(id -> {
+            // 校验分类是否存在
             ProductCategoryDO category = categoryMap.get(id);
             if (category == null) {
                 throw exception(CATEGORY_NOT_EXISTS);
             }
+            // 校验分类是否启用
             if (!CommonStatusEnum.ENABLE.getStatus().equals(category.getStatus())) {
                 throw exception(CATEGORY_DISABLED, category.getName());
             }
-            // 校验层级
+            // 商品分类层级校验,必须使用第二级的商品分类
             if (getCategoryLevel(id) < CATEGORY_LEVEL) {
                 throw exception(SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR);
             }

+ 12 - 97
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/DiscountActivityConvert.java

@@ -1,19 +1,17 @@
 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.module.promotion.controller.admin.discount.vo.*;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+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
@@ -32,105 +30,22 @@ public interface DiscountActivityConvert {
     DiscountActivityRespVO convert(DiscountActivityDO bean);
 
     List<DiscountActivityRespVO> convertList(List<DiscountActivityDO> list);
+
     List<DiscountActivityBaseVO.Product> convertList2(List<DiscountProductDO> list);
+
     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;
-    }
-
-    // =========== 比较是否相等 ==========
-    /**
-     * 比较两个限时折扣商品是否相等
-     *
-     * @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;
+    default DiscountActivityRespVO convert(DiscountActivityDO activity, List<DiscountProductDO> products) {
+        return BeanUtils.toBean(activity, DiscountActivityRespVO.class).setProducts(convertList2(products));
     }
 
-    /**
-     * 比较两个限时折扣商品是否相等
-     * 注意,比较时忽略 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())
-                || ObjectUtil.notEqual(productDO.getActivityEndTime(), productVO.getActivityEndTime())
-                || ObjectUtil.notEqual(productDO.getActivityStartTime(), productVO.getActivityStartTime())
-                || ObjectUtil.notEqual(productDO.getActivityStatus(), productVO.getActivityStatus())) {
-            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 - 19
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/DiscountProductMapper.java

@@ -3,13 +3,12 @@ package cn.iocoder.yudao.module.promotion.dal.mysql.discount;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 
 /**
  * 限时折扣商城 Mapper
@@ -23,8 +22,23 @@ public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> {
         return selectList(DiscountProductDO::getActivityId, activityId);
     }
 
-    default List<DiscountProductDO> selectListBySkuIds(Collection<Long> skuIds) {
-        return selectList(DiscountProductDO::getSkuId, skuIds);
+    default List<DiscountProductDO> selectListByActivityId(Collection<Long> activityIds) {
+        return selectList(DiscountProductDO::getActivityId, activityIds);
+    }
+
+    default List<DiscountProductDO> selectListBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
+        return selectList(new LambdaQueryWrapperX<DiscountProductDO>()
+                .in(DiscountProductDO::getSpuId, spuIds)
+                .eq(DiscountProductDO::getActivityStatus, status));
+    }
+
+    default void updateByActivityId(DiscountProductDO discountProductDO) {
+        update(discountProductDO, new LambdaUpdateWrapper<DiscountProductDO>()
+                .eq(DiscountProductDO::getActivityId, discountProductDO.getActivityId()));
+    }
+
+    default void deleteByActivityId(Long activityId) {
+        delete(DiscountProductDO::getActivityId, activityId);
     }
 
     default List<DiscountProductDO> selectListBySkuIdsAndStatusAndNow(Collection<Long> skuIds, Integer status) {
@@ -36,19 +50,4 @@ public interface DiscountProductMapper extends BaseMapperX<DiscountProductDO> {
                 .gt(DiscountProductDO::getActivityEndTime, now));
     }
 
-    /**
-     * 查询出指定 spuId 的 spu 参加的活动最接近现在的一条记录。多个的话,一个 spuId 对应一个最近的活动编号
-     *
-     * @param spuIds spu 编号
-     * @param status 状态
-     * @return 包含 spuId 和 activityId 的 map 对象列表
-     */
-    default List<Map<String, Object>> selectSpuIdAndActivityIdMapsBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
-        return selectMaps(new QueryWrapper<DiscountProductDO>()
-                .select("spu_id AS spuId, MAX(DISTINCT(activity_id)) AS activityId")
-                .in("spu_id", spuIds)
-                .eq("activity_status", status)
-                .groupBy("spu_id"));
-    }
-
 }

+ 0 - 8
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityService.java

@@ -89,12 +89,4 @@ public interface DiscountActivityService {
      */
     List<DiscountProductDO> getDiscountProductsByActivityId(Collection<Long> activityIds);
 
-    /**
-     * 获取指定 SPU 编号最近参加的活动,每个 spuId 只返回一条记录
-     *
-     * @param spuIds   SPU 编号数组
-     * @return 折扣活动列表
-     */
-    List<DiscountActivityDO> getDiscountActivityListBySpuIds(Collection<Long> spuIds);
-
 }

+ 87 - 61
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountActivityServiceImpl.java

@@ -1,11 +1,13 @@
 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;
@@ -20,15 +22,15 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.time.LocalDateTime;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
+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.*;
 
 /**
@@ -45,16 +47,16 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
     @Resource
     private DiscountProductMapper discountProductMapper;
 
-    @Override
-    public List<DiscountProductDO> getMatchDiscountProductListBySkuIds(Collection<Long> skuIds) {
-        return discountProductMapper.selectListBySkuIdsAndStatusAndNow(skuIds, CommonStatusEnum.ENABLE.getStatus());
-    }
+    @Resource
+    private ProductSkuApi productSkuApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long createDiscountActivity(DiscountActivityCreateReqVO createReqVO) {
         // 校验商品是否冲突
         validateDiscountActivityProductConflicts(null, createReqVO.getProducts());
+        // 校验商品是否存在
+        validateProductExists(createReqVO.getProducts());
 
         // 插入活动
         DiscountActivityDO discountActivity = DiscountActivityConvert.INSTANCE.convert(createReqVO)
@@ -66,6 +68,7 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
                         .setActivityName(discountActivity.getName()).setActivityStatus(discountActivity.getStatus())
                         .setActivityStartTime(createReqVO.getStartTime()).setActivityEndTime(createReqVO.getEndTime()));
         discountProductMapper.insertBatch(discountProducts);
+        // 返回
         return discountActivity.getId();
     }
 
@@ -79,36 +82,40 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
         }
         // 校验商品是否冲突
         validateDiscountActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts());
+        // 校验商品是否存在
+        validateProductExists(updateReqVO.getProducts());
 
         // 更新活动
         DiscountActivityDO updateObj = DiscountActivityConvert.INSTANCE.convert(updateReqVO);
         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.deleteByIds(deleteIds);
+    private void updateDiscountProduct(DiscountActivityDO activity, List<DiscountActivityCreateReqVO.Product> products) {
+        // 第一步,对比新老数据,获得添加、修改、删除的列表
+        List<DiscountProductDO> newList = BeanUtils.toBean(products, DiscountProductDO.class,
+                product -> product.setActivityId(activity.getId())
+                        .setActivityName(activity.getName()).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())
-                        .setActivityName(updateReqVO.getName())
-                        .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.deleteByIds(convertList(diffList.get(2), DiscountProductDO::getId));
         }
     }
 
@@ -119,20 +126,44 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
      * @param products 商品列表
      */
     private void validateDiscountActivityProductConflicts(Long id, List<DiscountActivityBaseVO.Product> products) {
-        if (CollUtil.isEmpty(products)) {
-            return;
-        }
-        // 查询商品参加的活动
-        List<DiscountProductDO> list = discountProductMapper.selectListByActivityId(id);
-        List<DiscountProductDO> matchDiscountProductList = discountProductMapper.selectListBySkuIds(
-                convertSet(list, DiscountProductDO::getSkuId));
-        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
@@ -143,9 +174,11 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
             throw exception(DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
         }
 
-        // 更新
-        DiscountActivityDO updateObj = new DiscountActivityDO().setId(id).setStatus(CommonStatusEnum.DISABLE.getStatus());
-        discountActivityMapper.updateById(updateObj);
+        // 更新活动状态
+        discountActivityMapper.updateById(new DiscountActivityDO().setId(id).setStatus(CommonStatusEnum.DISABLE.getStatus()));
+        // 更新活动商品状态
+        discountProductMapper.updateByActivityId(new DiscountProductDO().setActivityId(id).setActivityStatus(
+                CommonStatusEnum.DISABLE.getStatus()));
     }
 
     @Override
@@ -156,8 +189,10 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
             throw exception(DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED);
         }
 
-        // 删除
+        // 删除活动
         discountActivityMapper.deleteById(id);
+        // 删除活动商品
+        discountProductMapper.deleteByActivityId(id);
     }
 
     private DiscountActivityDO validateDiscountActivityExists(Long id) {
@@ -185,21 +220,12 @@ public class DiscountActivityServiceImpl implements DiscountActivityService {
 
     @Override
     public List<DiscountProductDO> getDiscountProductsByActivityId(Collection<Long> activityIds) {
-        return discountProductMapper.selectList("activity_id", activityIds);
+        return discountProductMapper.selectList(DiscountProductDO::getActivityId, activityIds);
     }
 
     @Override
-    public List<DiscountActivityDO> getDiscountActivityListBySpuIds(Collection<Long> spuIds) {
-        // 1. 查询出指定 spuId 的 spu 参加的活动最接近现在的一条记录。多个的话,一个 spuId 对应一个最近的活动编号
-        List<Map<String, Object>> spuIdAndActivityIdMaps = discountProductMapper.selectSpuIdAndActivityIdMapsBySpuIdsAndStatus(
-                spuIds, CommonStatusEnum.ENABLE.getStatus());
-        if (CollUtil.isEmpty(spuIdAndActivityIdMaps)) {
-            return Collections.emptyList();
-        }
-
-        // 2. 查询活动详情
-        return discountActivityMapper.selectListByIdsAndDateTimeLt(
-                convertSet(spuIdAndActivityIdMaps, map -> MapUtil.getLong(map, "activityId")), LocalDateTime.now());
+    public List<DiscountProductDO> getMatchDiscountProductListBySkuIds(Collection<Long> skuIds) {
+        return discountProductMapper.selectListBySkuIdsAndStatusAndNow(skuIds, CommonStatusEnum.ENABLE.getStatus());
     }
 
 }

+ 2 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java

@@ -137,8 +137,8 @@ public class RewardActivityServiceImpl implements RewardActivityService {
             if (PromotionProductScopeEnum.isAll(item.getProductScope()) ||
                     PromotionProductScopeEnum.isAll(rewardActivity.getProductScope())) {
                 throw exception(REWARD_ACTIVITY_SCOPE_EXISTS, item.getName(),
-                        PromotionProductScopeEnum.isAll(item.getProductScope()) ? "该活动商品范围为全部已覆盖包含本活动范围" :
-                                "本活动商品范围为全部已覆盖包含了该活动商品范围");
+                        PromotionProductScopeEnum.isAll(item.getProductScope()) ?
+                                "该活动商品范围为全部已覆盖包含本活动范围" : "本活动商品范围为全部已覆盖包含了该活动商品范围");
             }
             // 情况二:如果与该时间段内商品范围为类别的活动冲突
             if (PromotionProductScopeEnum.isCategory(item.getProductScope())) {

+ 3 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDiscountActivityPriceCalculator.java

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.price.calculator;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
 import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
 import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
@@ -23,6 +22,7 @@ import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+import static cn.iocoder.yudao.framework.common.util.number.MoneyUtils.calculateRatePrice;
 import static cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper.formatPrice;
 
 /**
@@ -125,7 +125,7 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato
         if (PromotionDiscountTypeEnum.PRICE.getType().equals(discount.getDiscountType())) { // 减价
             newPrice -= discount.getDiscountPrice() * orderItem.getCount();
         } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(discount.getDiscountType())) { // 打折
-            newPrice = newPrice * discount.getDiscountPercent() / 100;
+            newPrice = calculateRatePrice(orderItem.getPayPrice(), discount.getDiscountPercent() / 100.0);
         } else {
             throw new IllegalArgumentException(String.format("优惠活动的商品(%s) 的优惠类型不正确", discount));
         }
@@ -144,7 +144,7 @@ public class TradeDiscountActivityPriceCalculator implements TradePriceCalculato
         if (level == null || level.getDiscountPercent() == null) {
             return 0;
         }
-        Integer newPrice = MoneyUtils.calculateRatePrice(orderItem.getPayPrice(), level.getDiscountPercent().doubleValue());
+        Integer newPrice = calculateRatePrice(orderItem.getPayPrice(), level.getDiscountPercent().doubleValue());
         return orderItem.getPayPrice() - newPrice;
     }