diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java index 5a144a75a..21e025520 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.promotion.api.combination; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; import javax.validation.Valid; import java.time.LocalDateTime; @@ -65,4 +66,17 @@ public interface CombinationRecordApi { */ void updateRecordStatusToInProgress(Long userId, Long orderId, LocalDateTime startTime); + /** + * 【下单前】校验是否满足拼团活动条件 + * + * 如果校验失败,则抛出业务异常 + * + * @param activityId 活动编号 + * @param userId 用户编号 + * @param skuId sku 编号 + * @param count 数量 + * @return 拼团信息 + */ + CombinationValidateJoinRespDTO validateJoinCombination(Long activityId, Long userId, Long skuId, Integer count); + } diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordRespDTO.java deleted file mode 100644 index 96b54ca1b..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordRespDTO.java +++ /dev/null @@ -1,41 +0,0 @@ -package cn.iocoder.yudao.module.promotion.api.combination.dto; - -import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; -import lombok.Data; - -/** - * 拼团记录 Response DTO - * - * @author HUIHUI - */ -@Data -public class CombinationRecordRespDTO { - - /** - * 拼团活动编号 - */ - private Long activityId; - /** - * SPU 编号 - */ - private Long spuId; - /** - * SKU 编号 - */ - private Long skuId; - /** - * 用户编号 - */ - private Long userId; - /** - * 订单编号 - */ - private Long orderId; - /** - * 开团状态 - * - * 枚举 {@link CombinationRecordStatusEnum} - */ - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationValidateJoinRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationValidateJoinRespDTO.java new file mode 100644 index 000000000..86fe00a5f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationValidateJoinRespDTO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.promotion.api.combination.dto; + +import lombok.Data; + +/** + * 校验参与拼团 Response DTO + * + * @author HUIHUI + */ +@Data +public class CombinationValidateJoinRespDTO { + + /** + * 砍价活动编号 + */ + private Long activityId; + /** + * 砍价活动名称 + */ + private String name; + + /** + * 拼团金额 + */ + private Integer combinationPrice; + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java index 5f0de5faa..8343dde58 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -55,7 +55,7 @@ public interface ErrorCodeConstants { ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_008_003, "秒杀活动已关闭,不能修改"); ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_008_004, "秒杀活动未关闭或未结束,不能删除"); ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_008_005, "秒杀活动已关闭,不能重复关闭"); - ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1_013_008_006, "秒杀失败,原因秒杀库存不足"); + ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1_013_008_006, "秒杀失败,原因:秒杀库存不足"); ErrorCode SECKILL_JOIN_ACTIVITY_TIME_ERROR = new ErrorCode(1_013_008_007, "秒杀失败,原因:不在活动时间范围内"); ErrorCode SECKILL_JOIN_ACTIVITY_STATUS_CLOSED = new ErrorCode(1_013_008_008, "秒杀失败,原因:秒杀活动已关闭"); ErrorCode SECKILL_JOIN_ACTIVITY_SINGLE_LIMIT_COUNT_EXCEED = new ErrorCode(1_013_008_009, "秒杀失败,原因:单次限购超出"); @@ -72,6 +72,8 @@ public interface ErrorCodeConstants { ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE_NOT_UPDATE = new ErrorCode(1_013_010_002, "拼团活动已关闭不能修改"); ErrorCode COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_010_003, "拼团活动未关闭或未结束,不能删除"); ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE = new ErrorCode(1_013_010_004, "拼团失败,原因:拼团活动已关闭"); + ErrorCode COMBINATION_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_010_005, "拼团失败,原因:拼团活动商品不存在"); + ErrorCode COMBINATION_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1_013_010_006, "拼团失败,原因:拼团活动商品库存不足"); // ========== 拼团记录 1-013-011-000 ========== ErrorCode COMBINATION_RECORD_NOT_EXISTS = new ErrorCode(1_013_011_000, "拼团不存在"); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java index 8f7ce2e24..a32d35e29 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.promotion.api.combination; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; import org.springframework.stereotype.Service; @@ -50,4 +51,9 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { userId, orderId, startTime); } + @Override + public CombinationValidateJoinRespDTO validateJoinCombination(Long activityId, Long userId, Long skuId, Integer count) { + return recordService.validateJoinCombination(activityId, userId, skuId, count); + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java index 558d93cbd..3f243275d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO; import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; @@ -108,8 +107,6 @@ public interface CombinationActivityConvert { .setPicUrl(sku.getPicUrl()); } - List convert(List bean); - List convertAppList(List list); default List convertAppList(List list, List spuList) { diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java index e3efbfaa5..20f5e5fbd 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java @@ -100,4 +100,13 @@ public interface CombinationActivityService { */ PageResult getCombinationActivityPage(PageParam pageParam); + /** + * 获取指定活动指定 sku 编号的商品 + * + * @param activityId 活动编号 + * @param skuId sku 编号 + * @return 活动商品信息 + */ + CombinationProductDO selectByActivityIdAndSkuId(Long activityId, Long skuId); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java index 41b72233a..0f4f2ccfb 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java @@ -216,4 +216,11 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic return combinationActivityMapper.selectPage(pageParam, CommonStatusEnum.ENABLE.getStatus()); } + @Override + public CombinationProductDO selectByActivityIdAndSkuId(Long activityId, Long skuId) { + return combinationProductMapper.selectOne( + CombinationProductDO::getActivityId, activityId, + CombinationProductDO::getSkuId, skuId); + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java index e2e26124b..bef9442f1 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java @@ -1,6 +1,10 @@ package cn.iocoder.yudao.module.promotion.service.combination; +import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; import java.time.LocalDateTime; @@ -30,8 +34,9 @@ public interface CombinationRecordService { * @param userId 用户编号 * @param skuId sku 编号 * @param count 数量 + * @return 返回拼团活动和拼团活动商品 */ - void validateCombinationRecord(Long activityId, Long userId, Long skuId, Integer count); + KeyValue validateCombinationRecord(Long activityId, Long userId, Long skuId, Integer count); /** * 创建拼团记录 @@ -68,4 +73,17 @@ public interface CombinationRecordService { */ List getRecordListByUserIdAndActivityId(Long userId, Long activityId); + /** + * 【下单前】校验是否满足拼团活动条件 + * + * 如果校验失败,则抛出业务异常 + * + * @param activityId 活动编号 + * @param userId 用户编号 + * @param skuId sku 编号 + * @param count 数量 + * @return 拼团信息 + */ + CombinationValidateJoinRespDTO validateJoinCombination(Long activityId, Long userId, Long skuId, Integer count); + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java index eef7d5992..7bec69330 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.combination; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; @@ -10,8 +11,10 @@ import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecordMapper; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; @@ -104,7 +107,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { // TODO @芋艿:在详细预览下; @Override - public void validateCombinationRecord(Long activityId, Long userId, Long skuId, Integer count) { + public KeyValue validateCombinationRecord(Long activityId, Long userId, Long skuId, Integer count) { // 1.1 校验拼团活动是否存在 CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(activityId); // 1.2 校验活动是否开启 @@ -115,10 +118,24 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { if (count > activity.getSingleLimitCount()) { throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); } + // 2.1、校验活动商品是否存在 + CombinationProductDO product = combinationActivityService.selectByActivityIdAndSkuId(activityId, skuId); + if (product == null) { + throw exception(COMBINATION_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS); + } + // 2.2、校验 sku 是否存在 + ProductSkuRespDTO sku = productSkuApi.getSku(skuId); + if (sku == null) { + throw exception(COMBINATION_JOIN_ACTIVITY_PRODUCT_NOT_EXISTS); + } + // 2.3、 校验库存是否充足 + if (count > sku.getStock()) { + throw exception(COMBINATION_ACTIVITY_UPDATE_STOCK_FAIL); + } // 3、校验是否有拼团记录 List recordList = getRecordListByUserIdAndActivityId(userId, activityId); if (CollUtil.isEmpty(recordList)) { - return; + return new KeyValue<>(activity, product); } // 4、校验是否超出总限购数量 Integer sumValue = getSumValue(convertList(recordList, CombinationRecordDO::getCount, @@ -129,7 +146,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { // 5、校验拼团记录是否存在未支付的订单(如果存在未支付的订单则不允许发起新的拼团) CombinationRecordDO record = findFirst(recordList, item -> ObjectUtil.equals(item.getStatus(), null)); if (record == null) { - return; + return new KeyValue<>(activity, product); } // 5.1、查询关联的订单是否已经支付 // 当前 activityId 已经有未支付的订单,不允许在发起新的;要么支付,要么去掉先; @@ -138,13 +155,14 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { if (ObjectUtil.equal(orderStatus, TradeOrderStatusEnum.UNPAID.getStatus())) { throw exception(COMBINATION_RECORD_FAILED_ORDER_STATUS_UNPAID); } + + return new KeyValue<>(activity, product); } // TODO 芋艿:在详细 review 下; @Override @Transactional(rollbackFor = Exception.class) public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) { - // 1.1、 校验拼团活动 CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(reqDTO.getActivityId()); // 1.2 校验是否超出单次限购数量 @@ -205,6 +223,15 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { return recordMapper.selectListByUserIdAndActivityId(userId, activityId); } + @Override + public CombinationValidateJoinRespDTO validateJoinCombination(Long activityId, Long userId, Long skuId, Integer count) { + KeyValue keyValue = validateCombinationRecord(activityId, userId, skuId, count); + return new CombinationValidateJoinRespDTO() + .setActivityId(keyValue.getKey().getId()) + .setName(keyValue.getKey().getName()) + .setCombinationPrice(keyValue.getValue().getCombinationPrice()); + } + /** * APP 端获取开团记录 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index d22674f6d..8d9d022eb 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -271,7 +271,7 @@ public interface TradeOrderConvert { @Mapping(target = "count", source = "item.count"), @Mapping(target = "orderId", source = "order.id"), @Mapping(target = "userId", source = "order.userId"), - @Mapping(target = "headId", source = "order.combinationRecordHeadId"), + @Mapping(target = "headId", source = "order.combinationHeadId"), @Mapping(target = "combinationPrice", source = "item.payPrice"), }) CombinationRecordCreateReqDTO convert(TradeOrderDO order, TradeOrderItemDO item); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index 9a0fa7678..275558994 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -312,7 +312,7 @@ public class TradeOrderDO extends BaseDO { private Long bargainRecordId; /** - * 拼团活动编号 TODO puhui999:价格计算后设置 + * 拼团活动编号 * * 关联 CombinationActivityDO 的 id 字段 */ @@ -322,6 +322,6 @@ public class TradeOrderDO extends BaseDO { * * 关联 CombinationRecordDO 的 id 字段 */ - private Long combinationRecordHeadId; + private Long combinationHeadId; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCombinationActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCombinationActivityPriceCalculator.java new file mode 100644 index 000000000..0fec9992a --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCombinationActivityPriceCalculator.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.trade.service.price.calculator; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +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; + +/** + * 拼团活动的 {@link TradePriceCalculator} 实现类 + * + * @author HUIHUI + */ +@Component +@Order(TradePriceCalculator.ORDER_COMBINATION_ACTIVITY) +public class TradeCombinationActivityPriceCalculator implements TradePriceCalculator { + + @Resource + private CombinationRecordApi combinationRecordApi; + + @Override + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { + // 1. 判断订单类型和是否具有拼团活动编号 + if (param.getCombinationActivityId() == null) { + return; + } + + Assert.isTrue(param.getItems().size() == 1, "拼团时,只允许选择一个商品"); + // 2. 校验是否可以参与拼团 + TradePriceCalculateRespBO.OrderItem orderItem = result.getItems().get(0); + CombinationValidateJoinRespDTO combinationActivity = combinationRecordApi.validateJoinCombination( + param.getCombinationActivityId(), param.getUserId(), + orderItem.getSkuId(), orderItem.getCount()); + + // 3.1 记录优惠明细 + Integer discountPrice = orderItem.getPayPrice() - combinationActivity.getCombinationPrice() * orderItem.getCount(); + TradePriceCalculatorHelper.addPromotion(result, orderItem, + param.getCombinationActivityId(), combinationActivity.getName(), PromotionTypeEnum.COMBINATION_ACTIVITY.getType(), + StrUtil.format("拼团活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)), + discountPrice); + // 3.2 更新 SKU 优惠金额 + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + discountPrice); + TradePriceCalculatorHelper.recountPayPrice(orderItem); + TradePriceCalculatorHelper.recountAllPrice(result); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java index 26be58faf..1fc7e6915 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java @@ -17,6 +17,7 @@ public interface TradePriceCalculator { int ORDER_SECKILL_ACTIVITY = 8; int ORDER_BARGAIN_ACTIVITY = 8; + int ORDER_COMBINATION_ACTIVITY = 8; int ORDER_DISCOUNT_ACTIVITY = 10; int ORDER_REWARD_ACTIVITY = 20;