From aec8e853e492955884dc8b48272605809d87b3f5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 5 Oct 2023 23:24:44 +0800 Subject: [PATCH] =?UTF-8?q?trade=EF=BC=9A=E5=AE=8C=E5=96=84=E7=A0=8D?= =?UTF-8?q?=E4=BB=B7=E7=9A=84=E4=B8=8B=E5=8D=95=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/bargain/BargainRecordApi.java | 10 ++++++++ .../promotion/enums/ErrorCodeConstants.java | 1 + .../api/bargain/BargainRecordApiImpl.java | 10 ++++---- .../mysql/bargain/BargainActivityMapper.java | 8 ++++++ .../mysql/bargain/BargainRecordMapper.java | 14 +++++++++++ .../bargain/BargainActivityService.java | 2 ++ .../bargain/BargainActivityServiceImpl.java | 11 +------- .../service/bargain/BargainRecordService.java | 10 ++++++++ .../bargain/BargainRecordServiceImpl.java | 25 +++++++++++++++---- .../order/handler/TradeBargainHandler.java | 16 +++++++++++- .../TradeBargainActivityPriceCalculator.java | 5 +++- 11 files changed, 90 insertions(+), 22 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java index f8db9be21..fb0e3f02b 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java @@ -21,4 +21,14 @@ public interface BargainRecordApi { */ BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId); + /** + * 更新砍价记录的订单编号 + * + * 在砍价成功后,用户发起订单后,会记录该订单编号 + * + * @param id 砍价记录编号 + * @param orderId 订单编号 + */ + void updateBargainRecordOrderId(Long id, Long orderId); + } 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..cb419aee4 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 @@ -99,6 +99,7 @@ public interface ErrorCodeConstants { ErrorCode BARGAIN_RECORD_CREATE_FAIL_EXISTS = new ErrorCode(1_013_013_001, "参与失败,您已经参与当前砍价活动"); ErrorCode BARGAIN_RECORD_CREATE_FAIL_LIMIT = new ErrorCode(1_013_013_002, "参与失败,您已达到当前砍价活动的参与上限"); ErrorCode BARGAIN_JOIN_RECORD_NOT_SUCCESS = new ErrorCode(1_013_013_004, "下单失败,砍价未成功"); + ErrorCode BARGAIN_JOIN_RECORD_ALREADY_ORDER = new ErrorCode(1_013_013_005, "下单失败,该砍价已经下单"); // ========== 砍价助力 1-013-014-000 ========== ErrorCode BARGAIN_HELP_CREATE_FAIL_RECORD_NOT_IN_PROCESS = new ErrorCode(1_013_014_000, "助力失败,砍价记录不处于进行中"); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java index b1f544afe..a5d0121e5 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.promotion.api.bargain; -import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO; import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO; import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService; import org.springframework.stereotype.Service; @@ -18,13 +17,14 @@ public class BargainRecordApiImpl implements BargainRecordApi { @Resource private BargainRecordService bargainRecordService; - @Override - public void createBargainRecord(BargainRecordCreateReqDTO reqDTO) { - } - @Override public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) { return bargainRecordService.validateJoinBargain(userId, bargainRecordId, skuId); } + @Override + public void updateBargainRecordOrderId(Long id, Long orderId) { + bargainRecordService.updateBargainRecordOrderId(id, orderId); + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java index 47641f891..d3ea59983 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java @@ -39,6 +39,14 @@ public interface BargainActivityMapper extends BaseMapperX { * @return 影响的行数 */ default int updateStock(Long id, int count) { + // 情况一:增加库存 + if (count > 0) { + return update(null, new LambdaUpdateWrapper() + .eq(BargainActivityDO::getId, id) + .setSql("stock = stock + " + count)); + } + // 情况二:扣减库存 + count = -count; // 取正 return update(null, new LambdaUpdateWrapper() .eq(BargainActivityDO::getId, id) .ge(BargainActivityDO::getStock, count) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainRecordMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainRecordMapper.java index 92b946e32..51ca4d00d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainRecordMapper.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainRecordMapper.java @@ -93,4 +93,18 @@ public interface BargainRecordMapper extends BaseMapperX { .last("LIMIT " + count)); } + /** + * 更新砍价的订单编号,前提是 orderId 原本是空的 + * + * @param id 砍价记录编号 + * @param orderId 订单编号 + * @return 更新数量 + */ + default int updateOrderIdById(Long id, Long orderId) { + return update(new BargainRecordDO().setOrderId(orderId), + new LambdaQueryWrapper<>(BargainRecordDO.class) + .eq(BargainRecordDO::getId, id) + .isNull(BargainRecordDO::getOrderId)); + } + } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java index ad355d6d5..a57adc63f 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java @@ -36,6 +36,8 @@ public interface BargainActivityService { /** * 更新砍价活动库存 * + * 如果更新失败(库存不足),则抛出业务异常 + * * @param id 砍价活动编号 * @param count 购买数量 */ diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java index 46477b918..e14d5759e 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java @@ -83,16 +83,7 @@ public class BargainActivityServiceImpl implements BargainActivityService { @Override public void updateBargainActivityStock(Long id, Integer count) { - // 查询砍价活动 - BargainActivityDO activity = getBargainActivity(id); - if (activity == null) { - throw exception(BARGAIN_ACTIVITY_NOT_EXISTS); - } - if (count > activity.getStock()) { - throw exception(BARGAIN_ACTIVITY_STOCK_NOT_ENOUGH); - } - - // 更新砍价库存 + // 更新库存。如果更新失败,则抛出异常 int updateCount = bargainActivityMapper.updateStock(id, count); if (updateCount == 0) { throw exception(BARGAIN_ACTIVITY_STOCK_NOT_ENOUGH); diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java index 2e1169ea2..23e46abb3 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java @@ -55,6 +55,16 @@ public interface BargainRecordService { */ BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId); + /** + * 更新砍价记录的订单编号 + * + * 在砍价成功后,用户发起订单后,会记录该订单编号 + * + * @param id 砍价记录编号 + * @param orderId 订单编号 + */ + void updateBargainRecordOrderId(Long id, Long orderId); + /** * 获得砍价记录 * diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java index 079d89136..f6658f77d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordServiceImpl.java @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO; import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper; import cn.iocoder.yudao.module.promotion.enums.bargain.BargainRecordStatusEnum; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Nullable; @@ -42,7 +43,7 @@ public class BargainRecordServiceImpl implements BargainRecordService { @Override public Long createBargainRecord(Long userId, AppBargainRecordCreateReqVO reqVO) { - // 1. 校验砍价活动 + // 1. 校验砍价活动(包括库存) BargainActivityDO activity = bargainActivityService.validateBargainActivityCanJoin(reqVO.getActivityId()); // 2.1 校验当前是否已经有参与中的砍价活动 @@ -77,23 +78,37 @@ public class BargainRecordServiceImpl implements BargainRecordService { @Override public BargainValidateJoinRespDTO validateJoinBargain(Long userId, Long bargainRecordId, Long skuId) { - // 1.1 拼团记录不存在 + // 1.1 砍价记录不存在 BargainRecordDO record = bargainRecordMapper.selectByIdAndUserId(bargainRecordId, userId); if (record == null) { throw exception(BARGAIN_RECORD_NOT_EXISTS); } - // 1.2 拼团记录未在进行中 - if (ObjUtil.notEqual(record.getStatus(), BargainRecordStatusEnum.IN_PROGRESS)) { + // 1.2 砍价记录未在进行中 + if (ObjUtil.notEqual(record.getStatus(), BargainRecordStatusEnum.SUCCESS.getStatus())) { throw exception(BARGAIN_JOIN_RECORD_NOT_SUCCESS); } + // 1.3 砍价记录已经下单 + if (record.getOrderId() != null) { + throw exception(BARGAIN_JOIN_RECORD_ALREADY_ORDER); + } - // 2. 校验砍价活动 + // 2.1 校验砍价活动(包括库存) BargainActivityDO activity = bargainActivityService.validateBargainActivityCanJoin(record.getActivityId()); Assert.isTrue(Objects.equals(skuId, activity.getSkuId()), "砍价商品不匹配"); // 防御性校验 return new BargainValidateJoinRespDTO().setActivityId(activity.getId()).setName(activity.getName()) .setBargainPrice(record.getBargainPrice()); } + @Override + @Transactional(rollbackFor = Exception.class) + public void updateBargainRecordOrderId(Long id, Long orderId) { + // 更新失败,说明已经下单 + int updateCount = bargainRecordMapper.updateOrderIdById(id, orderId); + if (updateCount == 0) { + throw exception(BARGAIN_JOIN_RECORD_ALREADY_ORDER); + } + } + @Override public BargainRecordDO getBargainRecord(Long id) { return bargainRecordMapper.selectById(id); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java index 2ea1ec926..fc59d2d24 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.order.handler; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi; +import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; @@ -20,6 +21,8 @@ public class TradeBargainHandler implements TradeOrderHandler { @Resource private BargainActivityApi bargainActivityApi; + @Resource + private BargainRecordApi bargainRecordApi; @Override public void beforeOrderCreate(TradeOrderDO order, List orderItems) { @@ -28,7 +31,18 @@ public class TradeBargainHandler implements TradeOrderHandler { } // 扣减砍价活动的库存 bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(), - orderItems.get(0).getCount()); + -orderItems.get(0).getCount()); } + @Override + public void afterOrderCreate(TradeOrderDO order, List orderItems) { + if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), order.getType())) { + return; + } + // 记录砍价记录对应的订单编号 + bargainRecordApi.updateBargainRecordOrderId(order.getBargainRecordId(), order.getId()); + } + + // TODO 芋艿:取消订单时,需要增加库存 + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeBargainActivityPriceCalculator.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeBargainActivityPriceCalculator.java index 24468ba43..56b8e35d9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeBargainActivityPriceCalculator.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeBargainActivityPriceCalculator.java @@ -1,10 +1,12 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi; import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO; import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +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; @@ -28,7 +30,7 @@ public class TradeBargainActivityPriceCalculator implements TradePriceCalculator @Override public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { // 1. 判断订单类型和是否具有拼团记录编号 - if (param.getBargainRecordId() != null) { + if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.BARGAIN.getType())) { return; } Assert.isTrue(param.getItems().size() == 1, "砍价时,只允许选择一个商品"); @@ -40,6 +42,7 @@ public class TradeBargainActivityPriceCalculator implements TradePriceCalculator // 3.1 记录优惠明细 Integer discountPrice = orderItem.getPayPrice() - bargainActivity.getBargainPrice() * orderItem.getCount(); + // TODO 芋艿:极端情况,优惠金额为负数,需要处理 TradePriceCalculatorHelper.addPromotion(result, orderItem, param.getSeckillActivityId(), bargainActivity.getName(), PromotionTypeEnum.BARGAIN_ACTIVITY.getType(), StrUtil.format("砍价活动:省 {} 元", TradePriceCalculatorHelper.formatPrice(discountPrice)),