Quellcode durchsuchen

订单优惠价格计算逻辑变更

codingliang vor 2 Jahren
Ursprung
Commit
5a64d7cf1d

+ 24 - 0
src/main/java/com/sqx/modules/activity/bo/ShopActivityBO.java

@@ -1,8 +1,14 @@
 package com.sqx.modules.activity.bo;
 
+import com.sqx.modules.activity.dto.ActivityOfFullReductionDTO;
+import com.sqx.modules.activity.dto.ActivityOfGlobalDiscountDTO;
+import com.sqx.modules.activity.dto.ActivityOfTimeIntervalDTO;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.Date;
+import java.util.List;
+
 /**
  * 店铺活动bo
  *
@@ -14,6 +20,9 @@ public class ShopActivityBO {
     @ApiModelProperty(name = "活动id")
     private Long activityId;
 
+    @ApiModelProperty(name = "商家活动id")
+    private Long activityShopId;
+
     @ApiModelProperty(name = "店铺id")
     private Long shopId;
 
@@ -35,6 +44,21 @@ public class ShopActivityBO {
     @ApiModelProperty(name = "活动类型;1普通活动、2时段优惠、3满额优惠、4全场优惠")
     private String type;
 
+    @ApiModelProperty(name = "活动开始时间")
+    private Date startTime;
+
+    @ApiModelProperty(name = "活动结束时间")
+    private Date endTime;
+
     @ApiModelProperty(name = "活动配置;json字符串")
     private String config;
+
+    @ApiModelProperty("优惠时段信息列表;type为2时该字段不为空")
+    private List<ActivityOfTimeIntervalDTO> timeIntervalInfos;
+
+    @ApiModelProperty("满减字段优惠;type为3时该字段不为空")
+    private ActivityOfFullReductionDTO fullReductionInfo;
+
+    @ApiModelProperty("全场优惠;type为4时该字段不为空")
+    private ActivityOfGlobalDiscountDTO globalDiscountsInfo;
 }

+ 7 - 8
src/main/java/com/sqx/modules/activity/controller/app/AppActivityGoodsController.java

@@ -1,8 +1,8 @@
 package com.sqx.modules.activity.controller.app;
 
 import com.sqx.common.utils.Result;
-import com.sqx.modules.activity.service.ActivityGoodsService;
-import com.sqx.modules.activity.vo.GoodsActivityVO;
+import com.sqx.modules.activity.bo.ShopActivityBO;
+import com.sqx.modules.activity.service.ActivityService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -26,12 +25,12 @@ import java.util.List;
 @RequiredArgsConstructor
 public class AppActivityGoodsController {
 
-   private final ActivityGoodsService activityGoodsService;
+   private final ActivityService activityService;
 
-   @GetMapping("{goodsId}")
+   @GetMapping("{shopId}/{goodsId}")
    @ApiOperation("查看商品参与的活动列表")
-   public Result getActivityListByGoodsId(@PathVariable @ApiParam("商品id") Long goodsId) {
-       List<GoodsActivityVO> goodsActivityVOS = activityGoodsService.getActivityListByGoodsId(Arrays.asList(goodsId));
-       return Result.success().put("data", goodsActivityVOS);
+   public Result getActivityListByGoodsId(@PathVariable @ApiParam("店铺id") Long shopId, @PathVariable @ApiParam("商品id") Long goodsId) {
+       List<ShopActivityBO> shopActivityBOS = activityService.getActivityListByShopIdAndGoodsId(shopId, goodsId);
+       return Result.success().put("data", shopActivityBOS);
    }
 }

+ 0 - 6
src/main/java/com/sqx/modules/activity/dao/ActivityGoodsDao.java

@@ -1,12 +1,8 @@
 package com.sqx.modules.activity.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.sqx.modules.activity.bo.GoodsActivityBO;
 import com.sqx.modules.activity.entity.ActivityGoods;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
 
 /**
  * 活动商品
@@ -15,6 +11,4 @@ import java.util.List;
  */
 @Mapper
 public interface ActivityGoodsDao extends BaseMapper<ActivityGoods> {
-
-     List<GoodsActivityBO> getActivityListByGoodsId(@Param("goodsIds") List<Long> goodsIds);
  }

+ 3 - 0
src/main/java/com/sqx/modules/activity/dao/ActivityShopDao.java

@@ -3,6 +3,7 @@ package com.sqx.modules.activity.dao;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sqx.modules.activity.bo.ShopActivityBO;
 import com.sqx.modules.activity.entity.ActivityShop;
 import com.sqx.modules.activity.vo.ActivityShopVO;
 import com.sqx.modules.activity.vo.ShopActivityGroupVO;
@@ -25,4 +26,6 @@ public interface ActivityShopDao extends BaseMapper<ActivityShop> {
     ShopActivityGroupVO getShopActivityGroup(@Param("shopId") Long shopId);
 
     List<ShopActivityVO> getActivityByShopIds(@Param("shopIds") List<Long> shopIds);
+
+    List<ShopActivityBO> getShopActivityBOByShopId(@Param("shopId") Long shopId);
 }

+ 4 - 5
src/main/java/com/sqx/modules/activity/service/ActivityGoodsService.java

@@ -3,7 +3,6 @@ package com.sqx.modules.activity.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.sqx.modules.activity.dto.ActivityGoodsDTO;
 import com.sqx.modules.activity.entity.ActivityGoods;
-import com.sqx.modules.activity.vo.GoodsActivityVO;
 
 import java.util.List;
 
@@ -19,9 +18,9 @@ public interface ActivityGoodsService extends IService<ActivityGoods> {
     void deleteByActivityShopId(Long activityId);
 
     /**
-     * 查询商品参与的活动
-     * @param goodsIds 商品id集合
-     * @return 活动信息以及对应的商品id
+     * 根据活动店铺id查询
+     * @param activityShopId 活动店铺id
+     * @return 活动商品集合
      */
-    List<GoodsActivityVO> getActivityListByGoodsId(List<Long> goodsIds);
+    List<Long> getByActivityShopId(Long activityShopId);
 }

+ 9 - 0
src/main/java/com/sqx/modules/activity/service/ActivityService.java

@@ -2,6 +2,7 @@ package com.sqx.modules.activity.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.sqx.common.utils.PageUtils;
+import com.sqx.modules.activity.bo.ShopActivityBO;
 import com.sqx.modules.activity.dto.ActivityDTO;
 import com.sqx.modules.activity.dto.ActivityQueryDTO;
 import com.sqx.modules.activity.entity.Activity;
@@ -32,6 +33,14 @@ public interface ActivityService extends IService<Activity> {
     void deleteActivity(List<Long> ids);
 
     /**
+     * 查询根据店铺id和商品id获取可参与的活动
+     * @param shopId 店铺id
+     * @param goodsId 商品id
+     * @return 店铺活动列表
+     */
+    List<ShopActivityBO> getActivityListByShopIdAndGoodsId(Long shopId, Long goodsId);
+
+    /**
      * 获取订单适用活动列表
      * @param orderId 订单id
      * @return 活动列表

+ 8 - 0
src/main/java/com/sqx/modules/activity/service/ActivityShopService.java

@@ -3,6 +3,7 @@ package com.sqx.modules.activity.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.sqx.common.query.PageQuery;
 import com.sqx.common.utils.PageUtils;
+import com.sqx.modules.activity.bo.ShopActivityBO;
 import com.sqx.modules.activity.dto.JoinActivityDTO;
 import com.sqx.modules.activity.dto.QuitActivityDTO;
 import com.sqx.modules.activity.entity.ActivityShop;
@@ -41,4 +42,11 @@ public interface ActivityShopService extends IService<ActivityShop> {
      * @return 活动信息
      */
     List<ShopActivityVO> getActivityByShopIds(List<Long> shopIds);
+
+    /**
+     * 根据店铺id获取店铺参加的活动
+     * @param shopId
+     * @return
+     */
+    List<ShopActivityBO> getShopActivityBOByShopId(Long shopId);
 }

+ 10 - 24
src/main/java/com/sqx/modules/activity/service/impl/ActivityGoodsServiceImpl.java

@@ -1,22 +1,17 @@
 package com.sqx.modules.activity.service.impl;
 
-import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sqx.common.exception.SqxException;
 import com.sqx.common.utils.SpringContextUtils;
-import com.sqx.modules.activity.bo.GoodsActivityBO;
 import com.sqx.modules.activity.dao.ActivityGoodsDao;
 import com.sqx.modules.activity.dto.ActivityGoodsDTO;
 import com.sqx.modules.activity.entity.ActivityGoods;
 import com.sqx.modules.activity.entity.ActivityShop;
 import com.sqx.modules.activity.service.ActivityGoodsService;
 import com.sqx.modules.activity.service.ActivityShopService;
-import com.sqx.modules.activity.util.ActivityUtil;
-import com.sqx.modules.activity.vo.ActivityVO;
-import com.sqx.modules.activity.vo.GoodsActivityVO;
 import com.sqx.modules.datacentre.entity.SysUserShop;
 import com.sqx.modules.sys.entity.SysUserEntity;
 import com.sqx.modules.sys.service.SysUserShopService;
@@ -25,7 +20,8 @@ import org.apache.shiro.SecurityUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Date;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -68,25 +64,15 @@ public class ActivityGoodsServiceImpl extends ServiceImpl<ActivityGoodsDao, Acti
     }
 
     @Override
-    public List<GoodsActivityVO> getActivityListByGoodsId(List<Long> goodsIds) {
-        List<GoodsActivityBO> activities = baseMapper.getActivityListByGoodsId(goodsIds);
-
-        Date currentDate = new Date();
-
-        return activities.stream()
-                .map(e -> {
-                    ActivityVO activityVO = ActivityUtil.convertActivityEntityToVO(e);
-                    GoodsActivityVO goodsActivityVO = new GoodsActivityVO();
-                    BeanUtil.copyProperties(activityVO, goodsActivityVO);
-                    goodsActivityVO.setGoodsIds(e.getGoodsIds());
+    public List<Long> getByActivityShopId(Long activityShopId) {
+        LambdaQueryWrapper<ActivityGoods> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(ActivityGoods::getActivityShopId, activityShopId);
 
-                    return goodsActivityVO;
-                })
-                // 过滤出当前时间范围内的活动
-                .filter(e -> currentDate.after(e.getStartTime()) && currentDate.before(e.getEndTime()))
-                // 时段优惠活动过滤
-                .filter(ActivityUtil::judgeActivitySuitCurTime)
-                .collect(Collectors.toList());
+        ActivityGoods activityGoods = this.getOne(queryWrapper);
+        if (ObjectUtil.isNull(activityGoods)) {
+            return Collections.emptyList();
+        }
+        return Arrays.stream(activityGoods.getGoodsIds().split(",")).map(Long::new).collect(Collectors.toList());
     }
 
     private void checkAuth(ActivityGoodsDTO activityGoodsDTO) {

+ 155 - 71
src/main/java/com/sqx/modules/activity/service/impl/ActivityServiceImpl.java

@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sqx.common.constant.MyConstant;
 import com.sqx.common.exception.SqxException;
 import com.sqx.common.utils.PageUtils;
+import com.sqx.modules.activity.bo.ShopActivityBO;
 import com.sqx.modules.activity.dao.ActivityDao;
 import com.sqx.modules.activity.dto.ActivityDTO;
 import com.sqx.modules.activity.dto.ActivityOfFullReductionDTO;
@@ -22,12 +23,13 @@ import com.sqx.modules.activity.entity.Activity;
 import com.sqx.modules.activity.entity.ActivityShop;
 import com.sqx.modules.activity.enums.ActivityTypeEnum;
 import com.sqx.modules.activity.enums.FullActivityTypeEnum;
+import com.sqx.modules.activity.enums.LimitTypeEnum;
+import com.sqx.modules.activity.enums.SuitTypeEnum;
 import com.sqx.modules.activity.service.ActivityGoodsService;
 import com.sqx.modules.activity.service.ActivityService;
 import com.sqx.modules.activity.service.ActivityShopService;
 import com.sqx.modules.activity.util.ActivityUtil;
 import com.sqx.modules.activity.vo.ActivityVO;
-import com.sqx.modules.activity.vo.GoodsActivityVO;
 import com.sqx.modules.activity.vo.OrderSuitActivityVO;
 import com.sqx.modules.order.entity.OrderGoods;
 import com.sqx.modules.order.entity.TbOrder;
@@ -161,6 +163,23 @@ public class ActivityServiceImpl extends ServiceImpl<ActivityDao, Activity> impl
     }
 
     @Override
+    public List<ShopActivityBO> getActivityListByShopIdAndGoodsId(Long shopId, Long goodsId) {
+        List<ShopActivityBO> shopActivityBOS = activityShopService.getShopActivityBOByShopId(shopId);
+
+        // 满减活动过滤
+        return shopActivityBOS.stream().filter(shopActivityBO -> {
+            // 满减优惠
+            if (ActivityTypeEnum.FULL.getTypeCode().equals(shopActivityBO.getType())) {
+                // 查询符合条件的商品
+                List<Long> applyGoodsIds = activityGoodsService.getByActivityShopId(shopActivityBO.getActivityShopId());
+                return applyGoodsIds.contains(goodsId);
+            } else {
+                return true;
+            }
+        }).collect(Collectors.toList());
+    }
+
+    @Override
     public List<OrderSuitActivityVO> getOrderSuitActivity(Long orderId) {
         TbOrder order = orderService.getById(orderId);
         if (ObjectUtil.isNull(order)) {
@@ -172,76 +191,20 @@ public class ActivityServiceImpl extends ServiceImpl<ActivityDao, Activity> impl
             throw new SqxException("订单数据异常,请联系管理员");
         }
 
-        List<Long> goodsIds = orderGoodsList.stream().map(OrderGoods::getGoodsId).collect(Collectors.toList());
-
-        // 获取当前订单内的商品符合的条件的活动
-        List<GoodsActivityVO> goodsActivityVOList = activityGoodsService.getActivityListByGoodsId(goodsIds);
-
-        // 计算各活动优惠价格
-        return goodsActivityVOList.stream()
-                .map(e -> {
-                    String type = e.getType();
-                    // 符合当前活动的商品id集合
-                    List<Long> curGoodsIds = e.getGoodsIds();
-
-                    // 符合当前活动的商品id集合
-                    List<String> curGoodsNames = orderGoodsList.stream()
-                            .filter(orderGoods -> curGoodsIds.contains(orderGoods.getGoodsId()))
-                            .map(OrderGoods::getGoodsName)
-                            .collect(Collectors.toList());
-
-                    // 当前商品总价
-                    double curGoodsTotalPrice = orderGoodsList.stream()
-                            .filter(orderGoods -> curGoodsIds.contains(orderGoods.getGoodsId()))
-                            .mapToDouble(orderGoods ->
-                                    orderGoods.getGoodsPrice().multiply(new BigDecimal(orderGoods.getGoodsNum().toString()))
-                            .doubleValue())
-                            .sum();
-
-                    // 优惠金额
-                    double discountAmount = 0.0;
-
-                    // 计算活动优惠金额
-                    if (ActivityTypeEnum.TIME.getTypeCode().equals(type)) {
-                        ActivityOfTimeIntervalDTO curTimeTimeActivity = ActivityUtil.getCurTimeTimeActivity(e.getTimeIntervalInfos());
-                        Double discountContent = curTimeTimeActivity.getDiscountContent();
-
-                        discountAmount = curGoodsTotalPrice - (curGoodsTotalPrice * discountContent);
-                    } else if (ActivityTypeEnum.FULL.getTypeCode().equals(type)) {
-                        ActivityOfFullReductionDTO fullReductionInfo = e.getFullReductionInfo();
-
-                        // 判断当前商品总价满足最低满减金额
-                        if (curGoodsTotalPrice - fullReductionInfo.getMinAmount() < 0) {
-                           return null;
-                        }
-
-                        if (FullActivityTypeEnum.DISCOUNT.getTypeCode().equals(fullReductionInfo.getType())) {
-                            discountAmount = curGoodsTotalPrice - (curGoodsTotalPrice * fullReductionInfo.getDiscountContent());
-                        } else {
-                            Double discountContent = fullReductionInfo.getDiscountContent();
-
-                            // 如果满减金额大于当前商品的总金额,则优惠金额为当前商品的总金额,否则优惠金额为当前配置的金额
-                            if (discountContent > curGoodsTotalPrice) {
-                                discountAmount = curGoodsTotalPrice;
-                            } else {
-                                discountAmount = discountContent;
-                            }
-                        }
-                    } else if (ActivityTypeEnum.GLOBAL.getTypeCode().equals(type)) {
-                        ActivityOfGlobalDiscountDTO globalDiscountsInfo = e.getGlobalDiscountsInfo();
-
-                        discountAmount = curGoodsTotalPrice - (curGoodsTotalPrice * globalDiscountsInfo.getDiscountRate());
-                    }
-
-                    OrderSuitActivityVO vo = new OrderSuitActivityVO();
-                    vo.setActivityId(e.getId());
-                    vo.setActivityTitle(e.getTitle());
-                    vo.setActivityType(type);
-                    vo.setDiscountAmount(discountAmount);
-                    vo.setGoodsIds(curGoodsIds);
-                    vo.setGoodsNames(curGoodsNames);
-                    return vo;
-                })
+        // 订单所在店铺id
+        Long shopId = order.getShopId();
+
+        // 获取当前店铺参加的活动
+        List<ShopActivityBO> curShopActivityBOs = activityShopService.getShopActivityBOByShopId(shopId);
+
+        // 活动限制过滤
+        curShopActivityBOs = curShopActivityBOs.stream()
+                .filter(shopActivityBO -> activityLimitFilter(shopActivityBO, order))
+                .collect(Collectors.toList());
+
+        // 计算当前订单适用的所有可用活动优惠价格
+        return curShopActivityBOs.stream()
+                .map(shopActivityBO -> calcOrderSuitActivity(shopActivityBO, orderGoodsList))
                 .filter(Objects::nonNull)
                 .sorted(Comparator.comparing(OrderSuitActivityVO::getDiscountAmount))
                 .collect(Collectors.toList());
@@ -374,4 +337,125 @@ public class ActivityServiceImpl extends ServiceImpl<ActivityDao, Activity> impl
             }
         }
     }
+
+    /**
+     * 活动限制过滤
+     * @param shopActivityBO 店铺活动信息
+     * @param order 订单信息
+     * @return 订单是否适用当前活动
+     */
+    private boolean activityLimitFilter(ShopActivityBO shopActivityBO, TbOrder order) {
+        // 是否仅针对第一次下单
+        if (SuitTypeEnum.FIRST_ORDER.getTypeCode().equals(shopActivityBO.getSuitType())) {
+            // 查询用户在该店铺消费次数
+            int historyCount = orderService.countByShopIdAndUserId(order.getShopId(), order.getUserId());
+            return historyCount == 0;
+        }
+
+        // 是否有数量限制
+        if (LimitTypeEnum.NUM_LIMIT.getTypeCode().equals(shopActivityBO.getLimitType())) {
+            // 每天限制的数量
+            Integer limitValue = shopActivityBO.getLimitValue();
+
+            int curDateCount = orderService.countByShopIdAndUserIdAndCurDate(order.getShopId(), order.getUserId());
+            return limitValue.intValue() >= curDateCount;
+        }
+
+        return true;
+    }
+
+    /**
+     * 计算当前订单商品适用的活动优惠价格
+     * @param shopActivityBO 店铺活动信息
+     * @param orderGoodsList 订单商品列表
+     * @return 订单适用活动信息
+     */
+    private OrderSuitActivityVO calcOrderSuitActivity(ShopActivityBO shopActivityBO, List<OrderGoods> orderGoodsList) {
+        String type = shopActivityBO.getType();
+
+        // 当前参与活动商品总价
+        double curSuitGoodsTotalPrice = 0.0;
+        // 符合当前活动的商品id集合
+        List<Long> applyGoodsIds;
+        // 符合当前活动的商品name集合
+        List<String> applyGoodsNames;
+
+        // 满减优惠
+        if (ActivityTypeEnum.FULL.getTypeCode().equals(type)) {
+            // 查询符合条件的商品
+            applyGoodsIds = activityGoodsService.getByActivityShopId(shopActivityBO.getActivityShopId());
+
+            orderGoodsList.stream()
+                    .filter(orderGoods -> applyGoodsIds.contains(orderGoods.getGoodsId()))
+                    .mapToDouble(orderGoods -> orderGoods.getGoodsPrice().multiply(new BigDecimal(orderGoods.getGoodsNum().toString())).doubleValue())
+                    .sum();
+
+            applyGoodsNames = orderGoodsList.stream()
+                    .filter(orderGoods -> applyGoodsIds.contains(orderGoods.getGoodsId()))
+                    .map(OrderGoods::getGoodsName)
+                    .collect(Collectors.toList());
+        }
+        // 全场优惠和时段优惠所有的商品均参与活动
+        else {
+            applyGoodsIds = orderGoodsList.stream()
+                    .map(OrderGoods::getId)
+                    .collect(Collectors.toList());
+
+            curSuitGoodsTotalPrice = orderGoodsList.stream()
+                    .mapToDouble(orderGoods -> orderGoods.getGoodsPrice().multiply(new BigDecimal(orderGoods.getGoodsNum().toString())).doubleValue())
+                    .sum();
+
+            applyGoodsNames = orderGoodsList.stream()
+                    .map(OrderGoods::getGoodsName)
+                    .collect(Collectors.toList());
+        }
+
+        // 优惠金额
+        double discountAmount = 0.0;
+
+        // 计算活动优惠金额
+        if (ActivityTypeEnum.TIME.getTypeCode().equals(type)) {
+            ActivityOfTimeIntervalDTO curTimeTimeActivity = ActivityUtil.getCurTimeTimeActivity(shopActivityBO.getTimeIntervalInfos());
+
+            if (ObjectUtil.isNull(curTimeTimeActivity)) {
+                return null;
+            }
+
+            Double discountContent = curTimeTimeActivity.getDiscountContent();
+            discountAmount = curSuitGoodsTotalPrice - (curSuitGoodsTotalPrice * discountContent);
+        } else if (ActivityTypeEnum.FULL.getTypeCode().equals(type)) {
+            ActivityOfFullReductionDTO fullReductionInfo = shopActivityBO.getFullReductionInfo();
+
+            // 判断当前商品总价满足最低满减金额
+            if (curSuitGoodsTotalPrice - fullReductionInfo.getMinAmount() < 0) {
+                return null;
+            }
+
+            if (FullActivityTypeEnum.DISCOUNT.getTypeCode().equals(fullReductionInfo.getType())) {
+                discountAmount = curSuitGoodsTotalPrice - (curSuitGoodsTotalPrice * fullReductionInfo.getDiscountContent());
+            } else {
+                Double discountContent = fullReductionInfo.getDiscountContent();
+
+                // 如果满减金额大于当前商品的总金额,则优惠金额为当前商品的总金额,否则优惠金额为当前配置的金额
+                if (discountContent > curSuitGoodsTotalPrice) {
+                    discountAmount = curSuitGoodsTotalPrice;
+                } else {
+                    discountAmount = discountContent;
+                }
+            }
+        } else if (ActivityTypeEnum.GLOBAL.getTypeCode().equals(type)) {
+            ActivityOfGlobalDiscountDTO globalDiscountsInfo = shopActivityBO.getGlobalDiscountsInfo();
+
+            discountAmount = curSuitGoodsTotalPrice - (curSuitGoodsTotalPrice * globalDiscountsInfo.getDiscountRate());
+        }
+
+        OrderSuitActivityVO vo = new OrderSuitActivityVO();
+        vo.setActivityId(shopActivityBO.getActivityId());
+        vo.setActivityTitle(shopActivityBO.getTitle());
+        vo.setActivityType(type);
+        vo.setDiscountAmount(discountAmount);
+        vo.setGoodsIds(applyGoodsIds);
+        vo.setGoodsNames(applyGoodsNames);
+        return vo;
+    }
 }

+ 17 - 0
src/main/java/com/sqx/modules/activity/service/impl/ActivityShopServiceImpl.java

@@ -13,6 +13,7 @@ import com.sqx.common.query.PageQuery;
 import com.sqx.common.utils.Constant;
 import com.sqx.common.utils.PageUtils;
 import com.sqx.common.utils.SpringContextUtils;
+import com.sqx.modules.activity.bo.ShopActivityBO;
 import com.sqx.modules.activity.dao.ActivityShopDao;
 import com.sqx.modules.activity.dto.JoinActivityDTO;
 import com.sqx.modules.activity.dto.QuitActivityDTO;
@@ -21,6 +22,7 @@ import com.sqx.modules.activity.enums.LimitTypeEnum;
 import com.sqx.modules.activity.service.ActivityGoodsService;
 import com.sqx.modules.activity.service.ActivityService;
 import com.sqx.modules.activity.service.ActivityShopService;
+import com.sqx.modules.activity.util.ActivityUtil;
 import com.sqx.modules.activity.vo.ActivityShopVO;
 import com.sqx.modules.activity.vo.ActivityVO;
 import com.sqx.modules.activity.vo.ShopActivityGroupVO;
@@ -36,6 +38,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -147,6 +150,20 @@ public class ActivityShopServiceImpl extends ServiceImpl<ActivityShopDao, Activi
         return baseMapper.getActivityByShopIds(shopIds);
     }
 
+    @Override
+    public List<ShopActivityBO> getShopActivityBOByShopId(Long shopId) {
+        List<ShopActivityBO> shopActivityBOS = baseMapper.getShopActivityBOByShopId(shopId);
+
+        Date currentDate = new Date();
+        return shopActivityBOS.stream()
+                .map(ActivityUtil::parseActivityConfig)
+                // 过滤出当前时间范围内的活动
+                .filter(e -> currentDate.after(e.getStartTime()) && currentDate.before(e.getEndTime()))
+                // 时段优惠活动过滤
+                .filter(ActivityUtil::judgeActivitySuitCurTime)
+                .collect(Collectors.toList());
+    }
+
     /**
      * 参数校验
      * @param dto 加入活动参数

+ 67 - 6
src/main/java/com/sqx/modules/activity/util/ActivityUtil.java

@@ -2,6 +2,8 @@ package com.sqx.modules.activity.util;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
+import com.sqx.common.exception.SqxException;
+import com.sqx.modules.activity.bo.ShopActivityBO;
 import com.sqx.modules.activity.dto.ActivityOfFullReductionDTO;
 import com.sqx.modules.activity.dto.ActivityOfGlobalDiscountDTO;
 import com.sqx.modules.activity.dto.ActivityOfTimeIntervalDTO;
@@ -14,6 +16,7 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.util.List;
+import java.util.function.Consumer;
 
 /**
  * activity工具集合
@@ -22,21 +25,64 @@ import java.util.List;
  * @date : 2024-06-22 18:01
  */
 public class ActivityUtil {
+    /**
+     * Activity转ActivityVO
+     * @param activity 活动信息
+     * @return
+     */
     public static ActivityVO convertActivityEntityToVO(Activity activity) {
         ActivityVO vo = new ActivityVO();
         BeanUtils.copyProperties(activity, vo);
 
-        String type = activity.getType();
-        String config = activity.getConfig();
+        parseActivityConfig(activity.getType(), activity.getConfig(), e -> {
+            if (e instanceof ActivityOfFullReductionDTO) {
+                vo.setFullReductionInfo((ActivityOfFullReductionDTO) e);
+            } else if (e instanceof ActivityOfGlobalDiscountDTO) {
+                vo.setGlobalDiscountsInfo((ActivityOfGlobalDiscountDTO) e);
+            } else {
+                vo.setTimeIntervalInfos((List<ActivityOfTimeIntervalDTO>) e);
+            }
+        });
+        return vo;
+    }
+
+    /**
+     * 解析ShopActivityBO中的config
+     * @param shopActivityBO 店铺活动信息
+     * @return
+     */
+    public static ShopActivityBO parseActivityConfig(ShopActivityBO shopActivityBO) {
+        String config = shopActivityBO.getConfig();
+        String type = shopActivityBO.getType();
+        parseActivityConfig(type, config, e -> {
+            if (e instanceof ActivityOfFullReductionDTO) {
+                shopActivityBO.setFullReductionInfo((ActivityOfFullReductionDTO) e);
+            } else if (e instanceof ActivityOfGlobalDiscountDTO) {
+                shopActivityBO.setGlobalDiscountsInfo((ActivityOfGlobalDiscountDTO) e);
+            } else {
+                shopActivityBO.setTimeIntervalInfos((List<ActivityOfTimeIntervalDTO>) e);
+            }
+        });
+
+        return shopActivityBO;
+    }
 
+    /**
+     * 解析活动config
+     * @param type 活动类型
+     * @param config 活动配置字符串
+     * @param consumer 回调
+     */
+    public static void parseActivityConfig(String type, String config, Consumer consumer) {
         if (ActivityTypeEnum.TIME.getTypeCode().equals(type)) {
-            vo.setTimeIntervalInfos(JSONUtil.toList(JSONUtil.parseArray(config), ActivityOfTimeIntervalDTO.class));
+            consumer.accept(JSONUtil.toList(JSONUtil.parseArray(config), ActivityOfTimeIntervalDTO.class));
         } else if (ActivityTypeEnum.FULL.getTypeCode().equals(type)) {
-            vo.setFullReductionInfo(JSONUtil.toBean(config, ActivityOfFullReductionDTO.class));
+            consumer.accept(JSONUtil.toBean(config, ActivityOfFullReductionDTO.class));
         } else if (ActivityTypeEnum.GLOBAL.getTypeCode().equals(type)) {
-            vo.setGlobalDiscountsInfo(JSONUtil.toBean(config, ActivityOfGlobalDiscountDTO.class));
+            consumer.accept(JSONUtil.toBean(config, ActivityOfGlobalDiscountDTO.class));
+        } else {
+            throw new SqxException("活动类型不存在");
         }
-        return vo;
     }
 
     /**
@@ -55,6 +101,21 @@ public class ActivityUtil {
     }
 
     /**
+     * 判断活动是否适用于当前时间段
+     * @param shopActivityBO 店铺活动信息
+     * @return true or false
+     */
+    public static Boolean judgeActivitySuitCurTime(ShopActivityBO shopActivityBO) {
+        if (ObjectUtil.isNull(shopActivityBO)) return false;
+
+        // 非时段优惠活动直接返回true
+        if (!ActivityTypeEnum.TIME.getTypeCode().equals(shopActivityBO.getType())) return true;
+
+        // 时段优惠根据具体的时间端配置判定
+        return ActivityUtil.getCurTimeTimeActivity(shopActivityBO.getTimeIntervalInfos()) != null;
+    }
+
+    /**
      * 获取符合当前时间段内的时段优惠活动
      * @param timeConfigs 时段配置信息
      * @return 符合的活动或者null

+ 16 - 0
src/main/java/com/sqx/modules/order/service/AppOrderService.java

@@ -120,4 +120,20 @@ public interface AppOrderService extends IService<TbOrder> {
      * @return 订单商品列表
      */
     List<OrderGoods> getOrderGoods(Long orderId);
+
+    /**
+     * 查询用户在指定店铺的有效订单数量
+     * @param shopId 店铺id
+     * @param userId 用户id
+     * @return 订单数量
+     */
+    int countByShopIdAndUserId(Long shopId, Long userId);
+
+    /**
+     * 查询用户当天在指定店铺的有效订单数量
+     * @param shopId 店铺id
+     * @param userId 用户id
+     * @return 订单数量
+     */
+    int countByShopIdAndUserIdAndCurDate(Long shopId, Long userId);
 }

+ 27 - 0
src/main/java/com/sqx/modules/order/service/impl/AppAppOrderServiceImpl.java

@@ -3,8 +3,10 @@ package com.sqx.modules.order.service.impl;
 import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+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.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sqx.common.exception.SqxException;
@@ -71,6 +73,7 @@ import org.springframework.transaction.annotation.Transactional;
 import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
@@ -505,6 +508,30 @@ public class AppAppOrderServiceImpl extends ServiceImpl<AppOrderDao, TbOrder> im
         return orderGoodsDao.selectList(new QueryWrapper<OrderGoods>().eq("order_id", orderId));
     }
 
+    @Override
+    public int countByShopIdAndUserId(Long shopId, Long userId) {
+        LambdaQueryWrapper<TbOrder> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(TbOrder::getShopId, shopId);
+        queryWrapper.eq(TbOrder::getUserId, userId);
+        // 5 订单已取消
+        queryWrapper.ne(TbOrder::getStatus, 5);
+        return this.count(queryWrapper);
+    }
+
+    @Override
+    public int countByShopIdAndUserIdAndCurDate(Long shopId, Long userId) {
+        LocalDate now = LocalDate.now();
+
+        LambdaQueryWrapper<TbOrder> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(TbOrder::getShopId, shopId);
+        queryWrapper.eq(TbOrder::getUserId, userId);
+        queryWrapper.ge(TbOrder::getCreateTime, now + " 00:00:00")
+                .le(TbOrder::getCreateTime, now + " 23:59:59");
+        // 5 订单已取消
+        queryWrapper.ne(TbOrder::getStatus, 5);
+        return this.count(queryWrapper);
+    }
+
     /**
      * 用户钱包新增消费记录
      * @param order 订单信息

+ 0 - 25
src/main/resources/mapper/activity/ActivityGoodsDao.xml

@@ -19,29 +19,4 @@
             <result column="goods_id"/>
         </collection>
     </resultMap>
-
-    <select id="getActivityListByGoodsId" resultMap="goodsActivityVo">
-        select
-            a.*,
-            tmp.goods_id
-        from
-            (
-                select
-                    t.activity_shop_id,
-                    substring_index( substring_index( t.goods_ids, ',', n.n ), ',', - 1 ) goods_id
-                from
-                        ( select 1 as n union select 2 union select 3 union select 4 ) n
-                            inner join activity_goods t on char_length( t.goods_ids )- char_length(
-                            replace ( t.goods_ids, ',', '' ))>= n.n - 1
-                order by
-                    n.n
-            ) tmp
-                left join activity_shop ach on ach.id = tmp.activity_shop_id
-                left join activity a on ach.activity_id = a.id and a.type != '1'
-        where a.del_flag = '0'
-          and tmp.goods_id in
-              <foreach collection="goodsIds" open="(" close=")" separator="," item="item">
-                  #{item}
-              </foreach>
-    </select>
 </mapper>

+ 21 - 0
src/main/resources/mapper/activity/ActivityShopDao.xml

@@ -58,4 +58,25 @@
                     #{item}
                 </foreach>
     </select>
+
+    <select id="getShopActivityBOByShopId" resultType="com.sqx.modules.activity.bo.ShopActivityBO">
+        select
+            a.id,
+            ach.id activityShopId,
+            ach.shop_id,
+            ach.suit_type,
+            ach.limit_type,
+            ach.limit_value,
+            a.title,
+            a.content,
+            a.type,
+            a.start_time,
+            a.end_time,
+            a.config
+        from activity_shop ach
+            left join activity a on ach.activity_id = a.id
+       where ach.shop_id = #{shopId}
+         and a.enable_flag = '1'
+         and a.del_flag = '0'
+    </select>
 </mapper>