mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	秒回活动:订单金额计算初步设计
This commit is contained in:
		| @@ -1,5 +1,10 @@ | ||||
| package cn.iocoder.yudao.module.promotion.api.seckill; | ||||
|  | ||||
| import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityProductRespDTO; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 秒杀活动 API 接口 | ||||
|  * | ||||
| @@ -16,4 +21,13 @@ public interface SeckillActivityApi { | ||||
|      */ | ||||
|     void updateSeckillStock(Long id, Long skuId, Integer count); | ||||
|  | ||||
|     /** | ||||
|      * 获取秒杀活动商品信息 | ||||
|      * | ||||
|      * @param id     活动编号 | ||||
|      * @param skuIds sku 编号 | ||||
|      * @return 秒杀活动商品信息列表 | ||||
|      */ | ||||
|     List<SeckillActivityProductRespDTO> getSeckillActivityProductList(Long id, Collection<Long> skuIds); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,65 @@ | ||||
| package cn.iocoder.yudao.module.promotion.api.seckill.dto; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 秒杀活动商品 Response DTO | ||||
|  * | ||||
|  * @author HUIHUI | ||||
|  */ | ||||
| @Data | ||||
| public class SeckillActivityProductRespDTO { | ||||
|  | ||||
|     /** | ||||
|      * 秒杀参与商品编号 | ||||
|      */ | ||||
|     private Long id; | ||||
|     /** | ||||
|      * 秒杀活动 id | ||||
|      * | ||||
|      * 关联 SeckillActivityDO#getId() | ||||
|      */ | ||||
|     private Long activityId; | ||||
|     /** | ||||
|      * 秒杀时段 id | ||||
|      * | ||||
|      * 关联 SeckillConfigDO#getId() | ||||
|      */ | ||||
|     private List<Long> configIds; | ||||
|     /** | ||||
|      * 商品 SPU 编号 | ||||
|      */ | ||||
|     private Long spuId; | ||||
|     /** | ||||
|      * 商品 SKU 编号 | ||||
|      */ | ||||
|     private Long skuId; | ||||
|     /** | ||||
|      * 秒杀金额,单位:分 | ||||
|      */ | ||||
|     private Integer seckillPrice; | ||||
|     /** | ||||
|      * 秒杀库存 | ||||
|      */ | ||||
|     private Integer stock; | ||||
|  | ||||
|     /** | ||||
|      * 秒杀商品状态 | ||||
|      * | ||||
|      * 枚举 {@link CommonStatusEnum 对应的类} | ||||
|      */ | ||||
|     private Integer activityStatus; | ||||
|     /** | ||||
|      * 活动开始时间点 | ||||
|      */ | ||||
|     private LocalDateTime activityStartTime; | ||||
|     /** | ||||
|      * 活动结束时间点 | ||||
|      */ | ||||
|     private LocalDateTime activityEndTime; | ||||
|  | ||||
| } | ||||
| @@ -1,9 +1,13 @@ | ||||
| package cn.iocoder.yudao.module.promotion.api.seckill; | ||||
|  | ||||
| import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityProductRespDTO; | ||||
| import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; | ||||
| import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 秒杀活动接口 Api 接口实现类 | ||||
| @@ -21,4 +25,9 @@ public class SeckillActivityApiImpl implements SeckillActivityApi { | ||||
|         activityService.updateSeckillStock(id, skuId, count); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<SeckillActivityProductRespDTO> getSeckillActivityProductList(Long id, Collection<Long> skuIds) { | ||||
|         return SeckillActivityConvert.INSTANCE.convertList4(activityService.getSeckillActivityProductList(id, skuIds)); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | ||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||
| import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||||
| import cn.iocoder.yudao.module.product.enums.DictTypeConstants; | ||||
| import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityProductRespDTO; | ||||
| import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; | ||||
| import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO; | ||||
| import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO; | ||||
| @@ -137,4 +138,6 @@ public interface SeckillActivityConvert { | ||||
|                         "yyyy-MM-dd HH:mm:ss")); // 活动结束日期和时段结合 | ||||
|     } | ||||
|  | ||||
|     List<SeckillActivityProductRespDTO> convertList4(List<SeckillProductDO> seckillActivityProductList); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -37,9 +37,9 @@ public interface SeckillActivityService { | ||||
|     /** | ||||
|      * 更新秒杀库存 | ||||
|      * | ||||
|      * @param id 活动编号 | ||||
|      * @param skuId      sku 编号 | ||||
|      * @param count      数量 | ||||
|      * @param id    活动编号 | ||||
|      * @param skuId sku 编号 | ||||
|      * @param count 数量 | ||||
|      */ | ||||
|     void updateSeckillStock(Long id, Long skuId, Integer count); | ||||
|  | ||||
| @@ -114,4 +114,13 @@ public interface SeckillActivityService { | ||||
|      */ | ||||
|     PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO); | ||||
|  | ||||
|     /** | ||||
|      * 获取秒杀活动商品信息 | ||||
|      * | ||||
|      * @param id     活动编号 | ||||
|      * @param skuIds sku 编号 | ||||
|      * @return 秒杀活动商品信息列表 | ||||
|      */ | ||||
|     List<SeckillProductDO> getSeckillActivityProductList(Long id, Collection<Long> skuIds); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package cn.iocoder.yudao.module.promotion.service.seckill; | ||||
|  | ||||
| import cn.hutool.core.collection.CollectionUtil; | ||||
| import cn.hutool.core.util.ObjectUtil; | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||
| @@ -284,4 +285,18 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | ||||
|         return seckillActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<SeckillProductDO> getSeckillActivityProductList(Long id, Collection<Long> skuIds) { | ||||
|         // 1、校验秒杀活动是否存在 | ||||
|         validateSeckillActivityExists(id); | ||||
|         // 2、校验活动商品是否存在 | ||||
|         List<SeckillProductDO> productList = filterList(seckillProductMapper.selectListByActivityId(id), | ||||
|                 item -> skuIds.contains(item.getSkuId())); | ||||
|         if (CollectionUtil.isEmpty(productList)) { | ||||
|             throw exception(SKU_NOT_EXISTS); | ||||
|         } | ||||
|  | ||||
|         return productList; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -216,11 +216,11 @@ public interface TradeOrderConvert { | ||||
|     }) | ||||
|     ProductCommentCreateReqDTO convert04(AppTradeOrderItemCommentCreateReqVO createReqVO, TradeOrderItemDO tradeOrderItemDO); | ||||
|  | ||||
|     TradePriceCalculateReqBO convert(AppTradeOrderSettlementReqVO settlementReqVO); | ||||
|  | ||||
|     default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, | ||||
|                                              List<CartDO> cartList) { | ||||
|         TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO(); | ||||
|         reqBO.setUserId(userId).setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId()) | ||||
|                 .setItems(new ArrayList<>(settlementReqVO.getItems().size())); | ||||
|         TradePriceCalculateReqBO reqBO = convert(settlementReqVO).setUserId(userId).setItems(new ArrayList<>(settlementReqVO.getItems().size())); | ||||
|         // 商品项的构建 | ||||
|         Map<Long, CartDO> cartMap = convertMap(cartList, CartDO::getId); | ||||
|         for (AppTradeOrderSettlementReqVO.Item item : settlementReqVO.getItems()) { | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.price.bo; | ||||
|  | ||||
| import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; | ||||
| import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
|  | ||||
| import javax.validation.Valid; | ||||
| @@ -52,6 +53,23 @@ public class TradePriceCalculateReqBO { | ||||
|      */ | ||||
|     private Integer deliveryType; | ||||
|  | ||||
|     // ========== 秒杀活动相关字段 ========== | ||||
|     @Schema(description = "秒杀活动编号", example = "1024") | ||||
|     private Long seckillActivityId; | ||||
|  | ||||
|     // ========== 拼团活动相关字段 ========== | ||||
|     // TODO @puhui999:是不是拼团记录的编号哈? | ||||
|     @Schema(description = "拼团活动编号", example = "1024") | ||||
|     private Long combinationActivityId; | ||||
|  | ||||
|     @Schema(description = "拼团团长编号", example = "2048") | ||||
|     private Long combinationHeadId; | ||||
|  | ||||
|     // ========== 砍价活动相关字段 ========== | ||||
|     // TODO @puhui999:是不是砍价记录的编号哈? | ||||
|     @Schema(description = "砍价活动编号", example = "123") | ||||
|     private Long bargainActivityId; | ||||
|  | ||||
|     /** | ||||
|      * 商品 SKU 数组 | ||||
|      */ | ||||
|   | ||||
| @@ -84,9 +84,19 @@ public class TradePriceCalculateRespBO { | ||||
|          * 对应 taobao 的 trade.point_fee 字段 | ||||
|          */ | ||||
|         private Integer pointPrice; | ||||
|         /** | ||||
|          * 秒杀、拼团、砍价活动商品的总金额,单位:分 | ||||
|          * | ||||
|          * 基于 {@link OrderItem#getActivityPrice()} ()} * {@link OrderItem#getCount()} 求和 | ||||
|          */ | ||||
|         private Integer activityPrice; | ||||
|         /** | ||||
|          * 最终购买金额(总),单位:分 | ||||
|          * | ||||
|          * ==========活动情况=========== | ||||
|          * = {@link #activityPrice} | ||||
|          * + {@link #deliveryPrice} | ||||
|          * ==========正常情况=========== | ||||
|          * = {@link #totalPrice} | ||||
|          * - {@link #couponPrice} | ||||
|          * - {@link #pointPrice} | ||||
| @@ -153,9 +163,16 @@ public class TradePriceCalculateRespBO { | ||||
|          * 对应 taobao 的 trade.point_fee 字段 | ||||
|          */ | ||||
|         private Integer pointPrice; | ||||
|         /** | ||||
|          * 秒杀、拼团、砍价活动商品的金额,单位:分 | ||||
|          */ | ||||
|         private Integer activityPrice; | ||||
|         /** | ||||
|          * 应付金额(总),单位:分 | ||||
|          * | ||||
|          * ==========活动情况=========== | ||||
|          * = {@link #activityPrice} * {@link #count} | ||||
|          * + {@link #deliveryPrice} | ||||
|          * ==========正常情况=========== | ||||
|          * = {@link #price} * {@link #count} | ||||
|          * - {@link #couponPrice} | ||||
|          * - {@link #pointPrice} | ||||
|   | ||||
| @@ -84,6 +84,9 @@ public class TradePriceCalculatorHelper { | ||||
|             if (!item.getSelected()) { | ||||
|                 return; | ||||
|             } | ||||
|             // TODO puhui: 需要在这里计算活动的价格 | ||||
|             // ========== 一、活动情况 ========== | ||||
|             // ========== 二、正常情况 ========== | ||||
|             price.setTotalPrice(price.getTotalPrice() + item.getPrice() * item.getCount()); | ||||
|             price.setDiscountPrice(price.getDiscountPrice() + item.getDiscountPrice()); | ||||
|             price.setDeliveryPrice(price.getDeliveryPrice() + item.getDeliveryPrice()); | ||||
|   | ||||
| @@ -0,0 +1,47 @@ | ||||
| package cn.iocoder.yudao.module.trade.service.price.calculator; | ||||
|  | ||||
| import cn.hutool.core.util.ObjectUtil; | ||||
| import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi; | ||||
| import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityProductRespDTO; | ||||
| import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | ||||
| import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | ||||
| import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | ||||
| import org.springframework.core.annotation.Order; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import java.util.List; | ||||
| 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; | ||||
|  | ||||
| /** | ||||
|  * 秒杀活动的 {@link TradePriceCalculator} 实现类 | ||||
|  * | ||||
|  * @author HUIHUI | ||||
|  */ | ||||
| @Component | ||||
| @Order(TradePriceCalculator.ORDER_DISCOUNT_ACTIVITY) | ||||
| public class TradeSeckillActivityPriceCalculator implements TradePriceCalculator { | ||||
|  | ||||
|     @Resource | ||||
|     private SeckillActivityApi activityApi; | ||||
|  | ||||
|     @Override | ||||
|     public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { | ||||
|         // 1、判断订单类型和是否具有秒杀活动编号 | ||||
|         if (ObjectUtil.notEqual(param.getType(), TradeOrderTypeEnum.SECKILL.getType()) && param.getSeckillActivityId() == null) { | ||||
|             return; | ||||
|         } | ||||
|         // 2、获取秒杀活动商品信息 | ||||
|         List<SeckillActivityProductRespDTO> productList = activityApi.getSeckillActivityProductList(param.getSeckillActivityId(), convertSet(param.getItems(), | ||||
|                 TradePriceCalculateReqBO.Item::getSkuId)); | ||||
|         Map<Long, SeckillActivityProductRespDTO> productMap = convertMap(productList, SeckillActivityProductRespDTO::getSkuId); | ||||
|         result.getItems().forEach(item -> { | ||||
|             SeckillActivityProductRespDTO product = productMap.get(item.getSkuId()); | ||||
|             item.setActivityPrice(product.getSeckillPrice()); // 设置活动金额 | ||||
|         }); | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999