From 493d91a5151832ce51cf65362a23abb72dba6b35 Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Wed, 10 Apr 2024 19:15:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=96=B0=E5=A2=9E):=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=BC=98=E6=83=A0=E5=88=B8=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 2 +- .../atguigu/ssyx/vo/order/OrderConfirmVo.java | 36 ++-- .../ssyx/client/ActivityFeignClient.java | 6 + .../activity/api/ActivityApiController.java | 8 + .../activity/mapper/ActivityInfoMapper.java | 10 + .../activity/mapper/CouponInfoMapper.java | 8 + .../activity/service/ActivityInfoService.java | 11 + .../activity/service/CouponInfoService.java | 10 + .../service/impl/ActivityInfoServiceImpl.java | 57 +++++ .../service/impl/CouponInfoServiceImpl.java | 72 +++++++ .../module/ActivityInfoServiceModule.java | 200 +++++++++++++++++- .../module/CouponInfoServiceModule.java | 42 ++++ .../resources/mapper/ActivityInfoMapper.xml | 13 ++ .../resources/mapper/CouponInfoMapper.xml | 14 ++ 14 files changed, 468 insertions(+), 21 deletions(-) create mode 100644 service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/module/CouponInfoServiceModule.java diff --git a/.idea/misc.xml b/.idea/misc.xml index 9b83232..fb0bd54 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -14,7 +14,7 @@ - + \ No newline at end of file diff --git a/model/src/main/java/com/atguigu/ssyx/vo/order/OrderConfirmVo.java b/model/src/main/java/com/atguigu/ssyx/vo/order/OrderConfirmVo.java index bcd2037..d6e9f78 100644 --- a/model/src/main/java/com/atguigu/ssyx/vo/order/OrderConfirmVo.java +++ b/model/src/main/java/com/atguigu/ssyx/vo/order/OrderConfirmVo.java @@ -18,32 +18,30 @@ import java.util.List; */ @Data public class OrderConfirmVo implements Serializable { - - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - @ApiModelProperty(value = "预生产订单号") - private String orderNo; + @ApiModelProperty(value = "预生产订单号") + private String orderNo; - @ApiModelProperty(value = "用户对应的团长地址") - private LeaderAddressVo leaderAddressVo; - - @ApiModelProperty(value = "购物项列表") - private List carInfoVoList; + @ApiModelProperty(value = "用户对应的团长地址") + private LeaderAddressVo leaderAddressVo; - @ApiModelProperty(value = "订单优惠券列表") + @ApiModelProperty(value = "购物项列表") + private List carInfoVoList; + + @ApiModelProperty(value = "订单优惠券列表") private List couponInfoList; - @ApiModelProperty(value = "促销优惠金额") - private BigDecimal activityReduceAmount; + @ApiModelProperty(value = "促销优惠金额") + private BigDecimal activityReduceAmount; - @ApiModelProperty(value = "优惠券优惠金额") - private BigDecimal couponReduceAmount; + @ApiModelProperty(value = "优惠券优惠金额") + private BigDecimal couponReduceAmount; - @ApiModelProperty(value = "购物车原始总金额") - private BigDecimal originalTotalAmount; - - @ApiModelProperty(value = "最终总金额") - private BigDecimal totalAmount; + @ApiModelProperty(value = "购物车原始总金额") + private BigDecimal originalTotalAmount; + @ApiModelProperty(value = "最终总金额") + private BigDecimal totalAmount; } diff --git a/service-client/service-activity-client/src/main/java/com/atguigu/ssyx/client/ActivityFeignClient.java b/service-client/service-activity-client/src/main/java/com/atguigu/ssyx/client/ActivityFeignClient.java index 147c5ec..8ac4ca6 100644 --- a/service-client/service-activity-client/src/main/java/com/atguigu/ssyx/client/ActivityFeignClient.java +++ b/service-client/service-activity-client/src/main/java/com/atguigu/ssyx/client/ActivityFeignClient.java @@ -1,5 +1,7 @@ package com.atguigu.ssyx.client; +import com.atguigu.ssyx.model.order.CartInfo; +import com.atguigu.ssyx.vo.order.OrderConfirmVo; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -18,4 +20,8 @@ public interface ActivityFeignClient { // 根据skuId获取促销与优惠券信息 @GetMapping("inner/findActivityAndCoupon/{skuId}/{userId}") Map findActivityAndCoupon(@PathVariable Long skuId, @PathVariable Long userId); + + // 获取购物车满足条件的促销与优惠券信息 + @PostMapping("inner/findCartActivityAndCoupon/{userId}") + OrderConfirmVo findCartActivityAndCoupon(@RequestBody List cartInfoList, @PathVariable Long userId); } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/api/ActivityApiController.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/api/ActivityApiController.java index 07425cc..6393a0c 100644 --- a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/api/ActivityApiController.java +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/api/ActivityApiController.java @@ -1,6 +1,8 @@ package com.atguigu.ssyx.activity.api; import com.atguigu.ssyx.activity.service.ActivityInfoService; +import com.atguigu.ssyx.model.order.CartInfo; +import com.atguigu.ssyx.vo.order.OrderConfirmVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -29,4 +31,10 @@ public class ActivityApiController { public Map findActivityAndCoupon(@PathVariable Long skuId, @PathVariable Long userId) { return activityInfoService.findActivityAndCoupon(skuId, userId); } + + @ApiOperation(value = "获取购物车满足条件的促销与优惠券信息") + @PostMapping("inner/findCartActivityAndCoupon/{userId}") + public OrderConfirmVo findCartActivityAndCoupon(@RequestBody List cartInfoList, @PathVariable Long userId) { + return activityInfoService.findCartActivityAndCoupon(cartInfoList, userId); + } } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/mapper/ActivityInfoMapper.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/mapper/ActivityInfoMapper.java index 53a1605..23e83a1 100644 --- a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/mapper/ActivityInfoMapper.java +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/mapper/ActivityInfoMapper.java @@ -2,8 +2,10 @@ package com.atguigu.ssyx.activity.mapper; import com.atguigu.ssyx.model.activity.ActivityInfo; import com.atguigu.ssyx.model.activity.ActivityRule; +import com.atguigu.ssyx.model.activity.ActivitySku; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -33,4 +35,12 @@ public interface ActivityInfoMapper extends BaseMapper { * @return 商品活动列表 */ List findActivityRule(Long skuId); + + /** + * * 根据所有skuId获取参与活动 + * + * @param skuIdList skuId列表 + * @return List + */ + List selectCartActivity(@Param("skuIdList") List skuIdList); } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/mapper/CouponInfoMapper.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/mapper/CouponInfoMapper.java index 5533162..ead0f03 100644 --- a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/mapper/CouponInfoMapper.java +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/mapper/CouponInfoMapper.java @@ -25,4 +25,12 @@ public interface CouponInfoMapper extends BaseMapper { * @return 优惠卷信息列表 */ List selectCouponInfoList(Long id, Long categoryId, Long userId); + + /** + * 获取用户全部优惠券 + * + * @param userId 用户ID + * @return List + */ + List selectCartCouponInfoList(Long userId); } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/ActivityInfoService.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/ActivityInfoService.java index aa73529..ca2fe3f 100644 --- a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/ActivityInfoService.java +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/ActivityInfoService.java @@ -1,8 +1,10 @@ package com.atguigu.ssyx.activity.service; import com.atguigu.ssyx.model.activity.ActivityInfo; +import com.atguigu.ssyx.model.order.CartInfo; import com.atguigu.ssyx.model.product.SkuInfo; import com.atguigu.ssyx.vo.activity.ActivityRuleVo; +import com.atguigu.ssyx.vo.order.OrderConfirmVo; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; @@ -59,4 +61,13 @@ public interface ActivityInfoService extends IService { * @return 营销的活动 */ Map findActivityAndCoupon(Long skuId, Long userId); + + /** + * * 获取购物车满足条件的促销与优惠券信息 + * + * @param cartInfoList 购物车信息列表 + * @param userId 用户ID + * @return OrderConfirmVo + */ + OrderConfirmVo findCartActivityAndCoupon(List cartInfoList, Long userId); } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/CouponInfoService.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/CouponInfoService.java index edd2668..85b250f 100644 --- a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/CouponInfoService.java +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/CouponInfoService.java @@ -1,6 +1,7 @@ package com.atguigu.ssyx.activity.service; import com.atguigu.ssyx.model.activity.CouponInfo; +import com.atguigu.ssyx.model.order.CartInfo; import com.atguigu.ssyx.vo.activity.CouponRuleVo; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -66,4 +67,13 @@ public interface CouponInfoService extends IService { * @return 优惠卷列表 */ List findCouponInfo(Long skuId, Long userId); + + /** + * * 购物车可使用的优惠券列表 + * + * @param cartInfoList 购物车列表信息 + * @param userId 用户ID + * @return List + */ + List findCartCouponInfo(List cartInfoList, Long userId); } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/impl/ActivityInfoServiceImpl.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/impl/ActivityInfoServiceImpl.java index 9bbdb73..09543cb 100644 --- a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/impl/ActivityInfoServiceImpl.java +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/impl/ActivityInfoServiceImpl.java @@ -11,8 +11,11 @@ import com.atguigu.ssyx.model.activity.ActivityInfo; import com.atguigu.ssyx.model.activity.ActivityRule; import com.atguigu.ssyx.model.activity.ActivitySku; import com.atguigu.ssyx.model.activity.CouponInfo; +import com.atguigu.ssyx.model.order.CartInfo; import com.atguigu.ssyx.model.product.SkuInfo; import com.atguigu.ssyx.vo.activity.ActivityRuleVo; +import com.atguigu.ssyx.vo.order.CartInfoVo; +import com.atguigu.ssyx.vo.order.OrderConfirmVo; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; @@ -23,6 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -191,4 +195,57 @@ public class ActivityInfoServiceImpl extends ServiceImpl cartInfoList, Long userId) { + // 获取购物车,每个购物车参与活动,根据活动规则分组 + List carInfoVoList = module.findCartActivityList(cartInfoList); + // 促销活动优惠的总金额 + BigDecimal activityReduceAmount = carInfoVoList.stream() + .filter(carInfoVo -> null != carInfoVo.getActivityRule()) + .map(carInfoVo -> carInfoVo.getActivityRule().getReduceAmount()) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 购物车可使用的优惠券列表 + List couponInfoList = couponInfoService.findCartCouponInfo(cartInfoList, userId); + // 优惠券可优惠的总金额,一次购物只能使用一张优惠券 + BigDecimal couponReduceAmount = new BigDecimal(0); + if (!CollectionUtils.isEmpty(couponInfoList)) { + couponReduceAmount = couponInfoList.stream() + .filter(couponInfo -> couponInfo.getIsOptimal().intValue() == 1) + .map(couponInfo -> couponInfo.getAmount()) + .reduce(BigDecimal.ZERO, BigDecimal::add); + } + + // 购物车总金额 + BigDecimal carInfoTotalAmount = cartInfoList.stream() + .filter(cartInfo -> cartInfo.getIsChecked() == 1) + .map(cartInfo -> cartInfo.getCartPrice().multiply(new BigDecimal(cartInfo.getSkuNum()))) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 购物车原始总金额 + BigDecimal originalTotalAmount = cartInfoList.stream() + .filter(cartInfo -> cartInfo.getIsChecked() == 1) + .map(cartInfo -> cartInfo.getCartPrice().multiply(new BigDecimal(cartInfo.getSkuNum()))) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // 最终总金额 + BigDecimal totalAmount = originalTotalAmount.subtract(activityReduceAmount).subtract(couponReduceAmount); + + OrderConfirmVo orderTradeVo = new OrderConfirmVo(); + orderTradeVo.setCarInfoVoList(carInfoVoList); + orderTradeVo.setActivityReduceAmount(activityReduceAmount); + orderTradeVo.setCouponInfoList(couponInfoList); + orderTradeVo.setCouponReduceAmount(couponReduceAmount); + orderTradeVo.setOriginalTotalAmount(originalTotalAmount); + orderTradeVo.setTotalAmount(totalAmount); + return orderTradeVo; + } } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/impl/CouponInfoServiceImpl.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/impl/CouponInfoServiceImpl.java index dae86d4..80462f6 100644 --- a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/impl/CouponInfoServiceImpl.java +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/impl/CouponInfoServiceImpl.java @@ -3,13 +3,17 @@ package com.atguigu.ssyx.activity.service.impl; import com.atguigu.ssyx.activity.mapper.CouponInfoMapper; import com.atguigu.ssyx.activity.mapper.CouponRangeMapper; import com.atguigu.ssyx.activity.service.CouponInfoService; +import com.atguigu.ssyx.activity.service.module.CouponInfoServiceModule; import com.atguigu.ssyx.client.product.ProductFeignClient; import com.atguigu.ssyx.enums.CouponRangeType; import com.atguigu.ssyx.model.activity.CouponInfo; import com.atguigu.ssyx.model.activity.CouponRange; +import com.atguigu.ssyx.model.base.BaseEntity; +import com.atguigu.ssyx.model.order.CartInfo; import com.atguigu.ssyx.model.product.Category; import com.atguigu.ssyx.model.product.SkuInfo; import com.atguigu.ssyx.vo.activity.CouponRuleVo; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; @@ -19,6 +23,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -33,6 +38,8 @@ public class CouponInfoServiceImpl extends ServiceImpl + */ + @Override + public List findCartCouponInfo(List cartInfoList, Long userId) { + // 获取全部用户优惠券 + List userAllCouponInfoList = baseMapper.selectCartCouponInfoList(userId); + if (CollectionUtils.isEmpty(userAllCouponInfoList)) return null; + + // 获取优惠券id列表 + List couponIdList = userAllCouponInfoList.stream().map(BaseEntity::getId).collect(Collectors.toList()); + // 查询优惠券对应的范围 + List couponRangesList = couponRangeMapper.selectList(new LambdaQueryWrapper().in(CouponRange::getCouponId, couponIdList)); + // 获取优惠券id对应的满足使用范围的购物项skuId列表 + Map> couponIdToSkuIdMap = module.findCouponIdToSkuIdMap(cartInfoList, couponRangesList); + // 优惠后减少金额 + BigDecimal reduceAmount = new BigDecimal("0"); + // 记录最优优惠券 + CouponInfo optimalCouponInfo = null; + for (CouponInfo couponInfo : userAllCouponInfoList) { + if (CouponRangeType.ALL == couponInfo.getRangeType()) { + // 全场通用 + // 判断是否满足优惠使用门槛 + // 计算购物车商品的总价 + BigDecimal totalAmount = computeTotalAmount(cartInfoList); + if (totalAmount.subtract(couponInfo.getConditionAmount()).doubleValue() >= 0) { + couponInfo.setIsSelect(1); + } + } else { + // 优惠券id对应的满足使用范围的购物项skuId列表 + List skuIdList = couponIdToSkuIdMap.get(couponInfo.getId()); + // 当前满足使用范围的购物项 + List currentCartInfoList = cartInfoList.stream().filter(cartInfo -> skuIdList.contains(cartInfo.getSkuId())).collect(Collectors.toList()); + BigDecimal totalAmount = computeTotalAmount(currentCartInfoList); + if (totalAmount.subtract(couponInfo.getConditionAmount()).doubleValue() >= 0) { + couponInfo.setIsSelect(1); + } + } + if (couponInfo.getIsSelect() == 1 && couponInfo.getAmount().subtract(reduceAmount).doubleValue() > 0) { + reduceAmount = couponInfo.getAmount(); + optimalCouponInfo = couponInfo; + } + } + if (null != optimalCouponInfo) { + optimalCouponInfo.setIsOptimal(1); + } + return userAllCouponInfoList; + } + + private BigDecimal computeTotalAmount(List cartInfoList) { + BigDecimal total = new BigDecimal("0"); + for (CartInfo cartInfo : cartInfoList) { + // 是否选中 + if (cartInfo.getIsChecked() == 1) { + BigDecimal itemTotal = cartInfo.getCartPrice().multiply(new BigDecimal(cartInfo.getSkuNum())); + total = total.add(itemTotal); + } + } + return total; + } } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/module/ActivityInfoServiceModule.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/module/ActivityInfoServiceModule.java index 3936435..e956d6a 100644 --- a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/module/ActivityInfoServiceModule.java +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/module/ActivityInfoServiceModule.java @@ -1,17 +1,27 @@ package com.atguigu.ssyx.activity.service.module; import com.atguigu.ssyx.activity.mapper.ActivityInfoMapper; +import com.atguigu.ssyx.activity.mapper.ActivityRuleMapper; import com.atguigu.ssyx.enums.ActivityType; import com.atguigu.ssyx.model.activity.ActivityRule; +import com.atguigu.ssyx.model.activity.ActivitySku; +import com.atguigu.ssyx.model.order.CartInfo; +import com.atguigu.ssyx.vo.order.CartInfoVo; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.List; +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; @Component public class ActivityInfoServiceModule { @Autowired private ActivityInfoMapper activityInfoMapper; + @Autowired + private ActivityRuleMapper activityRuleMapper; // 根据skuId获取活动规则数据 public List findActivityRuleList(Long skuId) { @@ -44,4 +54,192 @@ public class ActivityInfoServiceModule { } return ruleDesc.toString(); } + + // 获取购物车,每个购物车参与活动,根据活动规则分组 + public List findCartActivityList(List cartInfoList) { + // 创建最终返回集合 + List carInfoVoList = new ArrayList<>(); + // 获取所有skuId + List skuIdList = cartInfoList.stream().map(CartInfo::getSkuId).collect(Collectors.toList()); + // 根据所有skuId获取参与活动 + List activitySkuList = activityInfoMapper.selectCartActivity(skuIdList); + Map> activityIdToSkuIdListMap = activitySkuList.stream().collect(Collectors.groupingBy( + ActivitySku::getActivityId, Collectors.mapping(ActivitySku::getSkuId, Collectors.toSet()))); + // 获取活动里面规则数据 + Set activityIdSet = activitySkuList.stream().map(ActivitySku::getActivityId).collect(Collectors.toSet()); + Map> activityIdToActivityRuleListMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(activityIdSet)) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.in(ActivityRule::getActivityId, activityIdSet); + wrapper.orderByDesc(ActivityRule::getConditionAmount, ActivityRule::getConditionAmount); + List activityRuleList = activityRuleMapper.selectList(wrapper); + activityIdToActivityRuleListMap = activityRuleList.stream().collect(Collectors.groupingBy(ActivityRule::getActivityId)); + } + +// 第三步:根据活动汇总购物项,相同活动的购物项为一组显示在页面,并且计算最优优惠金额 + // 记录有活动的购物项skuId + Set activitySkuIdSet = new HashSet<>(); + if (!CollectionUtils.isEmpty(activityIdToSkuIdListMap)) { + for (Map.Entry> entry : activityIdToSkuIdListMap.entrySet()) { + Long activityId = entry.getKey(); + // 当前活动对应的购物项skuId列表 + Set currentActivitySkuIdSet = entry.getValue(); + // 当前活动对应的购物项列表 + List currentActivityCartInfoList = cartInfoList.stream().filter(cartInfo -> currentActivitySkuIdSet.contains(cartInfo.getSkuId())).collect(Collectors.toList()); + + // 当前活动的总金额 + BigDecimal activityTotalAmount = this.computeTotalAmount(currentActivityCartInfoList); + // 当前活动的购物项总个数 + Integer activityTotalNum = this.computeCartNum(currentActivityCartInfoList); + // 计算当前活动对应的最优规则 + // 活动当前活动对应的规则 + List currentActivityRuleList = activityIdToActivityRuleListMap.get(activityId); + ActivityType activityType = currentActivityRuleList.get(0).getActivityType(); + ActivityRule optimalActivityRule = null; + if (activityType == ActivityType.FULL_REDUCTION) { + optimalActivityRule = this.computeFullReduction(activityTotalAmount, currentActivityRuleList); + } else { + optimalActivityRule = this.computeFullDiscount(activityTotalNum, activityTotalAmount, currentActivityRuleList); + } + + // 同一活动对应的购物项列表与对应优化规则 + CartInfoVo carInfoVo = new CartInfoVo(); + carInfoVo.setCartInfoList(currentActivityCartInfoList); + carInfoVo.setActivityRule(optimalActivityRule); + carInfoVoList.add(carInfoVo); + // 记录 + activitySkuIdSet.addAll(currentActivitySkuIdSet); + } + } + + // 第四步:无活动的购物项,每一项一组 + skuIdList.removeAll(activitySkuIdSet); + if (!CollectionUtils.isEmpty(skuIdList)) { + // 获取skuId对应的购物项 + Map skuIdToCartInfoMap = cartInfoList.stream().collect(Collectors.toMap(CartInfo::getSkuId, CartInfo -> CartInfo)); + for (Long skuId : skuIdList) { + CartInfoVo carInfoVo = new CartInfoVo(); + carInfoVo.setActivityRule(null); + List currentCartInfoList = new ArrayList<>(); + currentCartInfoList.add(skuIdToCartInfoMap.get(skuId)); + carInfoVo.setCartInfoList(currentCartInfoList); + carInfoVoList.add(carInfoVo); + } + } + return carInfoVoList; + } + + /** + * 计算满量打折最优规则 + * + * @param activityRuleList //该活动规则skuActivityRuleList数据,已经按照优惠折扣从大到小排序了 + */ + private ActivityRule computeFullDiscount(Integer totalNum, BigDecimal totalAmount, List activityRuleList) { + ActivityRule optimalActivityRule = null; + // 该活动规则skuActivityRuleList数据,已经按照优惠金额从大到小排序了 + for (ActivityRule activityRule : activityRuleList) { + // 如果订单项购买个数大于等于满减件数,则优化打折 + if (totalNum >= activityRule.getConditionNum()) { + BigDecimal skuDiscountTotalAmount = totalAmount.multiply(activityRule.getBenefitDiscount().divide(new BigDecimal("10"))); + BigDecimal reduceAmount = totalAmount.subtract(skuDiscountTotalAmount); + activityRule.setReduceAmount(reduceAmount); + optimalActivityRule = activityRule; + break; + } + } + if (null == optimalActivityRule) { + // 如果没有满足条件的取最小满足条件的一项 + optimalActivityRule = activityRuleList.get(activityRuleList.size() - 1); + optimalActivityRule.setReduceAmount(new BigDecimal("0")); + optimalActivityRule.setSelectType(1); + + String ruleDesc = "满" + + optimalActivityRule.getConditionNum() + + "元打" + + optimalActivityRule.getBenefitDiscount() + + "折,还差" + + (totalNum - optimalActivityRule.getConditionNum()) + + "件"; + optimalActivityRule.setRuleDesc(ruleDesc); + } else { + String ruleDesc = "满" + + optimalActivityRule.getConditionNum() + + "元打" + + optimalActivityRule.getBenefitDiscount() + + "折,已减" + + optimalActivityRule.getReduceAmount() + + "元"; + optimalActivityRule.setRuleDesc(ruleDesc); + optimalActivityRule.setSelectType(2); + } + return optimalActivityRule; + } + + /** + * 计算满减最优规则 + * + * @param activityRuleList //该活动规则skuActivityRuleList数据,已经按照优惠金额从大到小排序了 + */ + private ActivityRule computeFullReduction(BigDecimal totalAmount, List activityRuleList) { + ActivityRule optimalActivityRule = null; + // 该活动规则skuActivityRuleList数据,已经按照优惠金额从大到小排序了 + for (ActivityRule activityRule : activityRuleList) { + // 如果订单项金额大于等于满减金额,则优惠金额 + if (totalAmount.compareTo(activityRule.getConditionAmount()) > -1) { + // 优惠后减少金额 + activityRule.setReduceAmount(activityRule.getBenefitAmount()); + optimalActivityRule = activityRule; + break; + } + } + if (null == optimalActivityRule) { + // 如果没有满足条件的取最小满足条件的一项 + optimalActivityRule = activityRuleList.get(activityRuleList.size() - 1); + optimalActivityRule.setReduceAmount(new BigDecimal("0")); + optimalActivityRule.setSelectType(1); + + String ruleDesc = "满" + + optimalActivityRule.getConditionAmount() + + "元减" + + optimalActivityRule.getBenefitAmount() + + "元,还差" + + totalAmount.subtract(optimalActivityRule.getConditionAmount()) + + "元"; + optimalActivityRule.setRuleDesc(ruleDesc); + } else { + String ruleDesc = "满" + + optimalActivityRule.getConditionAmount() + + "元减" + + optimalActivityRule.getBenefitAmount() + + "元,已减" + + optimalActivityRule.getReduceAmount() + + "元"; + optimalActivityRule.setRuleDesc(ruleDesc); + optimalActivityRule.setSelectType(2); + } + return optimalActivityRule; + } + + private BigDecimal computeTotalAmount(List cartInfoList) { + BigDecimal total = new BigDecimal("0"); + for (CartInfo cartInfo : cartInfoList) { + // 是否选中 + if (cartInfo.getIsChecked() == 1) { + BigDecimal itemTotal = cartInfo.getCartPrice().multiply(new BigDecimal(cartInfo.getSkuNum())); + total = total.add(itemTotal); + } + } + return total; + } + + private int computeCartNum(List cartInfoList) { + int total = 0; + for (CartInfo cartInfo : cartInfoList) { + // 是否选中 + if (cartInfo.getIsChecked() == 1) { + total += cartInfo.getSkuNum(); + } + } + return total; + } } diff --git a/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/module/CouponInfoServiceModule.java b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/module/CouponInfoServiceModule.java new file mode 100644 index 0000000..ed25a37 --- /dev/null +++ b/service/service-activity/src/main/java/com/atguigu/ssyx/activity/service/module/CouponInfoServiceModule.java @@ -0,0 +1,42 @@ +package com.atguigu.ssyx.activity.service.module; + +import com.atguigu.ssyx.enums.CouponRangeType; +import com.atguigu.ssyx.model.activity.CouponRange; +import com.atguigu.ssyx.model.order.CartInfo; +import org.jetbrains.annotations.NotNull; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +public class CouponInfoServiceModule { + @NotNull + private static Set getLongs(List cartInfoList, Map.Entry> entry) { + List couponRangeList = entry.getValue(); + + Set skuIdSet = new HashSet<>(); + for (CartInfo cartInfo : cartInfoList) { + for (CouponRange couponRange : couponRangeList) { + if (CouponRangeType.SKU == couponRange.getRangeType() && couponRange.getRangeId() == cartInfo.getSkuId().intValue()) { + skuIdSet.add(cartInfo.getSkuId()); + } else if (CouponRangeType.CATEGORY == couponRange.getRangeType() && couponRange.getRangeId() == cartInfo.getCategoryId().intValue()) { + skuIdSet.add(cartInfo.getSkuId()); + } + } + } + return skuIdSet; + } + + public Map> findCouponIdToSkuIdMap(List cartInfoList, List couponRangesList) { + Map> couponIdToSkuIdMap = new HashMap<>(); + // 优惠券id对应的范围列表 + Map> couponIdToCouponRangeListMap = couponRangesList.stream().collect(Collectors.groupingBy(couponRange -> couponRange.getCouponId())); + for (Map.Entry> entry : couponIdToCouponRangeListMap.entrySet()) { + Long couponId = entry.getKey(); + Set skuIdSet = getLongs(cartInfoList, entry); + couponIdToSkuIdMap.put(couponId, new ArrayList<>(skuIdSet)); + } + return couponIdToSkuIdMap; + } +} diff --git a/service/service-activity/src/main/resources/mapper/ActivityInfoMapper.xml b/service/service-activity/src/main/resources/mapper/ActivityInfoMapper.xml index 19cbc52..ce09495 100644 --- a/service/service-activity/src/main/resources/mapper/ActivityInfoMapper.xml +++ b/service/service-activity/src/main/resources/mapper/ActivityInfoMapper.xml @@ -29,4 +29,17 @@ and now() between info.start_time and info.end_time order by rule.condition_amount desc, rule.condition_num desc + + + diff --git a/service/service-activity/src/main/resources/mapper/CouponInfoMapper.xml b/service/service-activity/src/main/resources/mapper/CouponInfoMapper.xml index 3be11f9..b9098a3 100644 --- a/service/service-activity/src/main/resources/mapper/CouponInfoMapper.xml +++ b/service/service-activity/src/main/resources/mapper/CouponInfoMapper.xml @@ -34,4 +34,18 @@ and now() between info.start_time and info.end_time order by info.amount desc + + +