Commit 708af92a0f5597527fddf166641c6b1bae0c1d4f
Committed by
Gitee
!660 优化订单 OrderHandler 实现
Merge pull request !660 from 芋道源码/feature/mall_product_tmp
Showing
14 changed files
with
481 additions
and
232 deletions
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
| ... | ... | @@ -41,7 +41,7 @@ public interface SeckillProductMapper extends BaseMapperX<SeckillProductDO> { |
| 41 | 41 | Assert.isTrue(count > 0); |
| 42 | 42 | return update(null, new LambdaUpdateWrapper<SeckillProductDO>() |
| 43 | 43 | .eq(SeckillProductDO::getId, id) |
| 44 | - .gt(SeckillProductDO::getStock, count) | |
| 44 | + .ge(SeckillProductDO::getStock, count) | |
| 45 | 45 | .setSql("stock = stock - " + count)); |
| 46 | 46 | } |
| 47 | 47 | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
| ... | ... | @@ -14,23 +14,12 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 14 | 14 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| 15 | 15 | import cn.iocoder.yudao.module.member.api.address.AddressApi; |
| 16 | 16 | import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; |
| 17 | -import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; | |
| 18 | -import cn.iocoder.yudao.module.member.api.point.MemberPointApi; | |
| 19 | -import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | |
| 20 | -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | |
| 21 | -import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; | |
| 22 | -import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; | |
| 23 | 17 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; |
| 24 | 18 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; |
| 25 | 19 | import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; |
| 26 | 20 | import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; |
| 27 | 21 | import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi; |
| 28 | 22 | import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; |
| 29 | -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | |
| 30 | -import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | |
| 31 | -import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; | |
| 32 | -import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; | |
| 33 | -import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; | |
| 34 | 23 | import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; |
| 35 | 24 | import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO; |
| 36 | 25 | import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderUpdateAddressReqVO; |
| ... | ... | @@ -40,7 +29,6 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettle |
| 40 | 29 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderSettlementRespVO; |
| 41 | 30 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; |
| 42 | 31 | import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; |
| 43 | -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; | |
| 44 | 32 | import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; |
| 45 | 33 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; |
| 46 | 34 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| ... | ... | @@ -48,15 +36,11 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 48 | 36 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; |
| 49 | 37 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; |
| 50 | 38 | import cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO; |
| 51 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | |
| 52 | 39 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; |
| 53 | 40 | import cn.iocoder.yudao.module.trade.enums.order.*; |
| 54 | 41 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 55 | 42 | import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog; |
| 56 | 43 | import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils; |
| 57 | -import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; | |
| 58 | -import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; | |
| 59 | -import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; | |
| 60 | 44 | import cn.iocoder.yudao.module.trade.service.cart.CartService; |
| 61 | 45 | import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; |
| 62 | 46 | import cn.iocoder.yudao.module.trade.service.message.TradeMessageService; |
| ... | ... | @@ -68,13 +52,15 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; |
| 68 | 52 | import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper; |
| 69 | 53 | import lombok.extern.slf4j.Slf4j; |
| 70 | 54 | import org.jetbrains.annotations.NotNull; |
| 71 | -import org.springframework.scheduling.annotation.Async; | |
| 72 | 55 | import org.springframework.stereotype.Service; |
| 73 | 56 | import org.springframework.transaction.annotation.Transactional; |
| 74 | 57 | |
| 75 | 58 | import javax.annotation.Resource; |
| 76 | 59 | import java.time.LocalDateTime; |
| 77 | -import java.util.*; | |
| 60 | +import java.util.ArrayList; | |
| 61 | +import java.util.List; | |
| 62 | +import java.util.Objects; | |
| 63 | +import java.util.Set; | |
| 78 | 64 | |
| 79 | 65 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 80 | 66 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| ... | ... | @@ -109,30 +95,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 109 | 95 | private DeliveryExpressService deliveryExpressService; |
| 110 | 96 | @Resource |
| 111 | 97 | private TradeMessageService tradeMessageService; |
| 112 | - @Resource | |
| 113 | - private BrokerageUserService brokerageUserService; | |
| 114 | - @Resource | |
| 115 | - private BrokerageRecordService brokerageRecordService; | |
| 116 | 98 | |
| 117 | 99 | @Resource |
| 118 | - private ProductSpuApi productSpuApi; | |
| 119 | - @Resource | |
| 120 | - private ProductSkuApi productSkuApi; | |
| 121 | - @Resource | |
| 122 | 100 | private PayOrderApi payOrderApi; |
| 123 | 101 | @Resource |
| 124 | 102 | private AddressApi addressApi; |
| 125 | 103 | @Resource |
| 126 | - private CouponApi couponApi; | |
| 127 | - @Resource | |
| 128 | - private CombinationRecordApi combinationRecordApi; | |
| 129 | - @Resource | |
| 130 | - private MemberUserApi memberUserApi; | |
| 131 | - @Resource | |
| 132 | - private MemberLevelApi memberLevelApi; | |
| 133 | - @Resource | |
| 134 | - private MemberPointApi memberPointApi; | |
| 135 | - @Resource | |
| 136 | 104 | private ProductCommentApi productCommentApi; |
| 137 | 105 | |
| 138 | 106 | @Resource |
| ... | ... | @@ -199,7 +167,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 199 | 167 | List<TradeOrderItemDO> orderItems = buildTradeOrderItems(order, calculateRespBO); |
| 200 | 168 | |
| 201 | 169 | // 2. 订单创建前的逻辑 |
| 202 | - beforeCreateTradeOrder(order, orderItems); | |
| 170 | + tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(order, orderItems)); | |
| 203 | 171 | |
| 204 | 172 | // 3. 保存订单 |
| 205 | 173 | tradeOrderMapper.insert(order); |
| ... | ... | @@ -234,11 +202,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 234 | 202 | order.setReceiverName(createReqVO.getReceiverName()).setReceiverMobile(createReqVO.getReceiverMobile()); |
| 235 | 203 | order.setPickUpVerifyCode(RandomUtil.randomNumbers(8)); // 随机一个核销码,长度为 8 位 |
| 236 | 204 | } |
| 237 | - // 设置订单推广人 | |
| 238 | - BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(order.getUserId()); | |
| 239 | - if (brokerageUser != null && brokerageUser.getBindUserId() != null) { | |
| 240 | - order.setBrokerageUserId(brokerageUser.getBindUserId()); | |
| 241 | - } | |
| 242 | 205 | return order; |
| 243 | 206 | } |
| 244 | 207 | |
| ... | ... | @@ -248,21 +211,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 248 | 211 | } |
| 249 | 212 | |
| 250 | 213 | /** |
| 251 | - * 订单创建前,执行前置逻辑 | |
| 252 | - * | |
| 253 | - * @param order 订单 | |
| 254 | - * @param orderItems 订单项 | |
| 255 | - */ | |
| 256 | - private void beforeCreateTradeOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 257 | - // 1. 执行订单创建前置处理器 | |
| 258 | - // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等 | |
| 259 | - tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(order, orderItems)); | |
| 260 | - | |
| 261 | - // 2. 下单时扣减商品库存 | |
| 262 | - productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems)); | |
| 263 | - } | |
| 264 | - | |
| 265 | - /** | |
| 266 | 214 | * 订单创建后,执行后置逻辑 |
| 267 | 215 | * <p> |
| 268 | 216 | * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 |
| ... | ... | @@ -276,27 +224,16 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 276 | 224 | // 1. 执行订单创建后置处理器 |
| 277 | 225 | tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(order, orderItems)); |
| 278 | 226 | |
| 279 | - // 2. 有使用优惠券时更新 | |
| 280 | - // 不在前置扣减的原因,是因为优惠劵要记录使用的订单号 | |
| 281 | - if (order.getCouponId() != null) { | |
| 282 | - couponApi.useCoupon(new CouponUseReqDTO().setId(order.getCouponId()).setUserId(order.getUserId()) | |
| 283 | - .setOrderId(order.getId())); | |
| 284 | - } | |
| 285 | - | |
| 286 | - // 3. 扣减积分(抵扣) | |
| 287 | - // 不在前置扣减的原因,是因为积分扣减时,需要记录关联业务 | |
| 288 | - reduceUserPoint(order.getUserId(), order.getUsePoint(), MemberPointBizTypeEnum.ORDER_USE, order.getId()); | |
| 289 | - | |
| 290 | - // 4. 删除购物车商品 | |
| 227 | + // 2. 删除购物车商品 | |
| 291 | 228 | Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); |
| 292 | 229 | if (CollUtil.isNotEmpty(cartIds)) { |
| 293 | 230 | cartService.deleteCart(order.getUserId(), cartIds); |
| 294 | 231 | } |
| 295 | 232 | |
| 296 | - // 5. 生成预支付 | |
| 233 | + // 3. 生成预支付 | |
| 297 | 234 | createPayOrder(order, orderItems); |
| 298 | 235 | |
| 299 | - // 6. 插入订单日志 | |
| 236 | + // 4. 插入订单日志 | |
| 300 | 237 | TradeOrderLogUtils.setOrderInfo(order.getId(), null, order.getStatus()); |
| 301 | 238 | |
| 302 | 239 | // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! |
| ... | ... | @@ -330,18 +267,11 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 330 | 267 | throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); |
| 331 | 268 | } |
| 332 | 269 | |
| 333 | - // 3、订单支付成功后 | |
| 270 | + // 3. 执行 TradeOrderHandler 的后置处理 | |
| 334 | 271 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id); |
| 335 | 272 | tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order, orderItems)); |
| 336 | 273 | |
| 337 | - // 4.1 增加用户积分(赠送) | |
| 338 | - addUserPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE, order.getId()); | |
| 339 | - // 4.2 增加用户经验 | |
| 340 | - getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId()); | |
| 341 | - // 4.3 增加用户佣金 | |
| 342 | - getSelf().addBrokerageAsync(order.getUserId(), order.getId()); | |
| 343 | - | |
| 344 | - // 5. 记录订单日志 | |
| 274 | + // 4. 记录订单日志 | |
| 345 | 275 | TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus()); |
| 346 | 276 | TradeOrderLogUtils.setUserInfo(order.getUserId(), UserTypeEnum.MEMBER.getValue()); |
| 347 | 277 | } |
| ... | ... | @@ -434,8 +364,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 434 | 364 | .put("logisticsNo", express != null ? deliveryReqVO.getLogisticsNo() : "").build()); |
| 435 | 365 | |
| 436 | 366 | // 4. 发送站内信 |
| 437 | - tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO().setOrderId(order.getId()) | |
| 438 | - .setUserId(order.getUserId()).setMessage(null)); | |
| 367 | + tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO() | |
| 368 | + .setOrderId(order.getId()).setUserId(order.getUserId()).setMessage(null)); | |
| 439 | 369 | } |
| 440 | 370 | |
| 441 | 371 | /** |
| ... | ... | @@ -448,18 +378,13 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 448 | 378 | */ |
| 449 | 379 | private TradeOrderDO validateOrderDeliverable(Long id) { |
| 450 | 380 | TradeOrderDO order = validateOrderExists(id); |
| 451 | - // 校验订单是否退款 | |
| 381 | + // 1. 校验订单是否未发货 | |
| 452 | 382 | if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) { |
| 453 | 383 | throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE); |
| 454 | 384 | } |
| 455 | - // 订单类型:拼团 | |
| 456 | - if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { | |
| 457 | - // 校验订单拼团是否成功 | |
| 458 | - if (!combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) { | |
| 459 | - throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS); | |
| 460 | - } | |
| 461 | - } | |
| 462 | 385 | |
| 386 | + // 2. 执行 TradeOrderHandler 前置处理 | |
| 387 | + tradeOrderHandlers.forEach(handler -> handler.beforeDeliveryOrder(order)); | |
| 463 | 388 | return order; |
| 464 | 389 | } |
| 465 | 390 | |
| ... | ... | @@ -616,30 +541,19 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 616 | 541 | * @param cancelType 取消类型 |
| 617 | 542 | */ |
| 618 | 543 | private void cancelOrder0(TradeOrderDO order, TradeOrderCancelTypeEnum cancelType) { |
| 619 | - Long id = order.getId(); | |
| 620 | 544 | // 1. 更新 TradeOrderDO 状态为已取消 |
| 621 | - int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), | |
| 545 | + int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), | |
| 622 | 546 | new TradeOrderDO().setStatus(TradeOrderStatusEnum.CANCELED.getStatus()) |
| 623 | 547 | .setCancelType(cancelType.getType()).setCancelTime(LocalDateTime.now())); |
| 624 | 548 | if (updateCount == 0) { |
| 625 | 549 | throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID); |
| 626 | 550 | } |
| 627 | 551 | |
| 628 | - List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id); | |
| 629 | - // 3. 回滚库存 | |
| 630 | - productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems)); | |
| 631 | - // 3.1、 活动相关的回滚 | |
| 632 | - tradeOrderHandlers.forEach(handler -> handler.cancelOrder(order, orderItems)); | |
| 633 | - | |
| 634 | - // 4. 回滚优惠券 | |
| 635 | - if (order.getCouponId() != null && order.getCouponId() > 0) { | |
| 636 | - couponApi.returnUsedCoupon(order.getCouponId()); | |
| 637 | - } | |
| 638 | - | |
| 639 | - // 5. 回滚积分(抵扣的) | |
| 640 | - addUserPoint(order.getUserId(), order.getUsePoint(), MemberPointBizTypeEnum.ORDER_CANCEL, order.getId()); | |
| 552 | + // 2. 执行 TradeOrderHandler 的后置处理 | |
| 553 | + List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(order.getId()); | |
| 554 | + tradeOrderHandlers.forEach(handler -> handler.afterCancelOrder(order, orderItems)); | |
| 641 | 555 | |
| 642 | - // 6. 增加订单日志 | |
| 556 | + // 3. 增加订单日志 | |
| 643 | 557 | TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus()); |
| 644 | 558 | } |
| 645 | 559 | |
| ... | ... | @@ -660,8 +574,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 660 | 574 | .setStatus(TradeOrderStatusEnum.CANCELED.getStatus()) |
| 661 | 575 | .setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now())); |
| 662 | 576 | |
| 663 | - // 2. 退还优惠券 | |
| 664 | - couponApi.returnUsedCoupon(order.getCouponId()); | |
| 577 | + // 2. 执行 TradeOrderHandler 的后置处理 | |
| 578 | + List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(order.getId()); | |
| 579 | + tradeOrderHandlers.forEach(handler -> handler.afterCancelOrder(order, orderItems)); | |
| 665 | 580 | } |
| 666 | 581 | |
| 667 | 582 | @Override |
| ... | ... | @@ -789,13 +704,15 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 789 | 704 | @Override |
| 790 | 705 | @Transactional(rollbackFor = Exception.class) |
| 791 | 706 | public void updateOrderItemWhenAfterSaleSuccess(Long id, Integer refundPrice) { |
| 792 | - // 1. 更新订单项 | |
| 707 | + // 1.1 更新订单项 | |
| 793 | 708 | updateOrderItemAfterSaleStatus(id, TradeOrderItemAfterSaleStatusEnum.APPLY.getStatus(), |
| 794 | 709 | TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus(), null); |
| 795 | - | |
| 796 | - // 2.1 更新订单的退款金额、积分 | |
| 710 | + // 1.2 执行 TradeOrderHandler 的后置处理 | |
| 797 | 711 | TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id); |
| 798 | 712 | TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId()); |
| 713 | + tradeOrderHandlers.forEach(handler -> handler.afterCancelOrderItem(order, orderItem)); | |
| 714 | + | |
| 715 | + // 2.1 更新订单的退款金额、积分 | |
| 799 | 716 | Integer orderRefundPrice = order.getRefundPrice() + refundPrice; |
| 800 | 717 | Integer orderRefundPoint = order.getRefundPoint() + orderItem.getUsePoint(); |
| 801 | 718 | Integer refundStatus = isAllOrderItemAfterSaleSuccess(order.getId()) ? |
| ... | ... | @@ -806,23 +723,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 806 | 723 | .setRefundPrice(orderRefundPrice).setRefundPoint(orderRefundPoint)); |
| 807 | 724 | // 2.2 如果全部退款,则进行取消订单 |
| 808 | 725 | getSelf().cancelOrderByAfterSale(order, orderRefundPrice); |
| 809 | - | |
| 810 | - | |
| 811 | - // 3. 回滚库存 | |
| 812 | - productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(Collections.singletonList(orderItem))); | |
| 813 | - // 3.1、 活动相关的回滚 | |
| 814 | - tradeOrderHandlers.forEach(handler -> handler.cancelOrder(order, Collections.singletonList(orderItem))); | |
| 815 | - | |
| 816 | - // 4.1 回滚积分:扣减用户积分(赠送的) | |
| 817 | - reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, orderItem.getAfterSaleId()); | |
| 818 | - // 4.2 回滚积分:增加用户积分(返还抵扣) | |
| 819 | - addUserPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.AFTER_SALE_REFUND_USED, orderItem.getAfterSaleId()); | |
| 820 | - | |
| 821 | - // 5. 回滚经验:扣减用户经验 | |
| 822 | - getSelf().reduceUserExperienceAsync(order.getUserId(), refundPrice, orderItem.getAfterSaleId()); | |
| 823 | - | |
| 824 | - // 6. 回滚佣金:更新分佣记录为已失效 | |
| 825 | - getSelf().cancelBrokerageAsync(order.getUserId(), id); | |
| 826 | 726 | } |
| 827 | 727 | |
| 828 | 728 | @Override |
| ... | ... | @@ -839,6 +739,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 839 | 739 | if (updateCount <= 0) { |
| 840 | 740 | throw exception(ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL); |
| 841 | 741 | } |
| 742 | + | |
| 842 | 743 | } |
| 843 | 744 | |
| 844 | 745 | /** |
| ... | ... | @@ -939,7 +840,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 939 | 840 | @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.SYSTEM_COMMENT) |
| 940 | 841 | public void createOrderItemCommentBySystemBySystem(TradeOrderDO order) { |
| 941 | 842 | // 1. 查询未评论的订单项 |
| 942 | - List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderIdAndCommentStatus(order.getId(), Boolean.FALSE); | |
| 843 | + List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderIdAndCommentStatus( | |
| 844 | + order.getId(), Boolean.FALSE); | |
| 943 | 845 | if (CollUtil.isEmpty(orderItems)) { |
| 944 | 846 | return; |
| 945 | 847 | } |
| ... | ... | @@ -982,73 +884,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 982 | 884 | |
| 983 | 885 | // =================== 营销相关的操作 =================== |
| 984 | 886 | |
| 985 | - @Async | |
| 986 | - protected void addUserExperienceAsync(Long userId, Integer payPrice, Long orderId) { | |
| 987 | - int bizType = MemberExperienceBizTypeEnum.ORDER.getType(); | |
| 988 | - memberLevelApi.addExperience(userId, payPrice, bizType, String.valueOf(orderId)); | |
| 989 | - } | |
| 990 | - | |
| 991 | - @Async | |
| 992 | - protected void reduceUserExperienceAsync(Long userId, Integer refundPrice, Long afterSaleId) { | |
| 993 | - int bizType = MemberExperienceBizTypeEnum.REFUND.getType(); | |
| 994 | - memberLevelApi.addExperience(userId, -refundPrice, bizType, String.valueOf(afterSaleId)); | |
| 995 | - } | |
| 996 | - | |
| 997 | - /** | |
| 998 | - * 添加用户积分 | |
| 999 | - * <p> | |
| 1000 | - * 目前是支付成功后,就会创建积分记录。 | |
| 1001 | - * <p> | |
| 1002 | - * 业内还有两种做法,可以根据自己的业务调整: | |
| 1003 | - * 1. 确认收货后,才创建积分记录 | |
| 1004 | - * 2. 支付 or 下单成功时,创建积分记录(冻结),确认收货解冻或者 n 天后解冻 | |
| 1005 | - * | |
| 1006 | - * @param userId 用户编号 | |
| 1007 | - * @param point 增加积分数量 | |
| 1008 | - * @param bizType 业务编号 | |
| 1009 | - * @param bizId 业务编号 | |
| 1010 | - */ | |
| 1011 | - protected void addUserPoint(Long userId, Integer point, MemberPointBizTypeEnum bizType, Long bizId) { | |
| 1012 | - if (point != null && point > 0) { | |
| 1013 | - memberPointApi.addPoint(userId, point, bizType.getType(), String.valueOf(bizId)); | |
| 1014 | - } | |
| 1015 | - } | |
| 1016 | - | |
| 1017 | - protected void reduceUserPoint(Long userId, Integer point, MemberPointBizTypeEnum bizType, Long bizId) { | |
| 1018 | - if (point != null && point > 0) { | |
| 1019 | - memberPointApi.reducePoint(userId, point, bizType.getType(), String.valueOf(bizId)); | |
| 1020 | - } | |
| 1021 | - } | |
| 1022 | - | |
| 1023 | - /** | |
| 1024 | - * 创建分销记录 | |
| 1025 | - * <p> | |
| 1026 | - * 目前是支付成功后,就会创建分销记录。 | |
| 1027 | - * <p> | |
| 1028 | - * 业内还有两种做法,可以根据自己的业务调整: | |
| 1029 | - * 1. 确认收货后,才创建分销记录 | |
| 1030 | - * 2. 支付 or 下单成功时,创建分销记录(冻结),确认收货解冻或者 n 天后解冻 | |
| 1031 | - * | |
| 1032 | - * @param userId 用户编号 | |
| 1033 | - * @param orderId 订单编号 | |
| 1034 | - */ | |
| 1035 | - @Async | |
| 1036 | - protected void addBrokerageAsync(Long userId, Long orderId) { | |
| 1037 | - MemberUserRespDTO user = memberUserApi.getUser(userId); | |
| 1038 | - Assert.notNull(user); | |
| 1039 | - // 每一个订单项,都会去生成分销记录 | |
| 1040 | - List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId); | |
| 1041 | - List<BrokerageAddReqBO> addList = convertList(orderItems, | |
| 1042 | - item -> TradeOrderConvert.INSTANCE.convert(user, item, | |
| 1043 | - productSpuApi.getSpu(item.getSpuId()), productSkuApi.getSku(item.getSkuId()))); | |
| 1044 | - brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList); | |
| 1045 | - } | |
| 1046 | - | |
| 1047 | - @Async | |
| 1048 | - protected void cancelBrokerageAsync(Long userId, Long orderItemId) { | |
| 1049 | - brokerageRecordService.cancelBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, String.valueOf(orderItemId)); | |
| 1050 | - } | |
| 1051 | - | |
| 1052 | 887 | /** |
| 1053 | 888 | * 获得自身的代理对象,解决 AOP 生效问题 |
| 1054 | 889 | * | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainOrderHandler.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.order.handler; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.hutool.core.lang.Assert; |
| 4 | 5 | import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi; |
| 5 | 6 | import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi; |
| ... | ... | @@ -12,12 +13,12 @@ import javax.annotation.Resource; |
| 12 | 13 | import java.util.List; |
| 13 | 14 | |
| 14 | 15 | /** |
| 15 | - * 砍价订单 handler 实现类 | |
| 16 | + * 砍价订单的 {@link TradeOrderHandler} 实现类 | |
| 16 | 17 | * |
| 17 | 18 | * @author HUIHUI |
| 18 | 19 | */ |
| 19 | 20 | @Component |
| 20 | -public class TradeBargainHandler implements TradeOrderHandler { | |
| 21 | +public class TradeBargainOrderHandler implements TradeOrderHandler { | |
| 21 | 22 | |
| 22 | 23 | @Resource |
| 23 | 24 | private BargainActivityApi bargainActivityApi; |
| ... | ... | @@ -26,7 +27,7 @@ public class TradeBargainHandler implements TradeOrderHandler { |
| 26 | 27 | |
| 27 | 28 | @Override |
| 28 | 29 | public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { |
| 29 | - if (TradeOrderTypeEnum.isBargain(order.getType())) { | |
| 30 | + if (!TradeOrderTypeEnum.isBargain(order.getType())) { | |
| 30 | 31 | return; |
| 31 | 32 | } |
| 32 | 33 | // 明确校验一下 |
| ... | ... | @@ -39,7 +40,7 @@ public class TradeBargainHandler implements TradeOrderHandler { |
| 39 | 40 | |
| 40 | 41 | @Override |
| 41 | 42 | public void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { |
| 42 | - if (TradeOrderTypeEnum.isBargain(order.getType())) { | |
| 43 | + if (!TradeOrderTypeEnum.isBargain(order.getType())) { | |
| 43 | 44 | return; |
| 44 | 45 | } |
| 45 | 46 | // 明确校验一下 |
| ... | ... | @@ -50,16 +51,28 @@ public class TradeBargainHandler implements TradeOrderHandler { |
| 50 | 51 | } |
| 51 | 52 | |
| 52 | 53 | @Override |
| 53 | - public void cancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 54 | - if (TradeOrderTypeEnum.isBargain(order.getType())) { | |
| 54 | + public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 55 | + if (!TradeOrderTypeEnum.isBargain(order.getType())) { | |
| 55 | 56 | return; |
| 56 | 57 | } |
| 57 | 58 | // 明确校验一下 |
| 58 | 59 | Assert.isTrue(orderItems.size() == 1, "砍价时,只允许选择一个商品"); |
| 59 | 60 | |
| 60 | - // 恢复砍价活动的库存 | |
| 61 | - bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(), | |
| 62 | - orderItems.get(0).getCount()); | |
| 61 | + // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚 | |
| 62 | + orderItems = filterOrderItemListByNoneAfterSale(orderItems); | |
| 63 | + if (CollUtil.isEmpty(orderItems)) { | |
| 64 | + return; | |
| 65 | + } | |
| 66 | + afterCancelOrderItem(order, orderItems.get(0)); | |
| 67 | + } | |
| 68 | + | |
| 69 | + @Override | |
| 70 | + public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) { | |
| 71 | + if (!TradeOrderTypeEnum.isBargain(order.getType())) { | |
| 72 | + return; | |
| 73 | + } | |
| 74 | + // 恢复(增加)砍价活动的库存 | |
| 75 | + bargainActivityApi.updateBargainActivityStock(order.getBargainActivityId(), orderItem.getCount()); | |
| 63 | 76 | } |
| 64 | 77 | |
| 65 | 78 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBrokerageOrderHandler.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.order.handler; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.hutool.core.lang.Assert; | |
| 5 | +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | |
| 6 | +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | |
| 7 | +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | |
| 8 | +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | |
| 9 | +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | |
| 10 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | |
| 11 | +import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; | |
| 12 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; | |
| 13 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | |
| 14 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | |
| 15 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | |
| 16 | +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; | |
| 17 | +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; | |
| 18 | +import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; | |
| 19 | +import org.springframework.stereotype.Component; | |
| 20 | + | |
| 21 | +import javax.annotation.Resource; | |
| 22 | +import java.util.List; | |
| 23 | + | |
| 24 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 25 | + | |
| 26 | +/** | |
| 27 | + * 订单分销的 {@link TradeOrderHandler} 实现类 | |
| 28 | + * | |
| 29 | + * @author 芋道源码 | |
| 30 | + */ | |
| 31 | +@Component | |
| 32 | +public class TradeBrokerageOrderHandler implements TradeOrderHandler { | |
| 33 | + | |
| 34 | + @Resource | |
| 35 | + private MemberUserApi memberUserApi; | |
| 36 | + @Resource | |
| 37 | + private ProductSpuApi productSpuApi; | |
| 38 | + @Resource | |
| 39 | + private ProductSkuApi productSkuApi; | |
| 40 | + | |
| 41 | + @Resource | |
| 42 | + private BrokerageRecordService brokerageRecordService; | |
| 43 | + @Resource | |
| 44 | + private BrokerageUserService brokerageUserService; | |
| 45 | + | |
| 46 | + @Override | |
| 47 | + public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 48 | + // 设置订单推广人 | |
| 49 | + BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(order.getUserId()); | |
| 50 | + if (brokerageUser != null && brokerageUser.getBindUserId() != null) { | |
| 51 | + order.setBrokerageUserId(brokerageUser.getBindUserId()); | |
| 52 | + } | |
| 53 | + } | |
| 54 | + | |
| 55 | + @Override | |
| 56 | + public void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 57 | + if (order.getBrokerageUserId() == null) { | |
| 58 | + return; | |
| 59 | + } | |
| 60 | + addBrokerage(order.getUserId(), orderItems); | |
| 61 | + } | |
| 62 | + | |
| 63 | + @Override | |
| 64 | + public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 65 | + // 如果是未支付的订单,不会产生分销结果,所以直接 return | |
| 66 | + if (!order.getPayStatus()) { | |
| 67 | + return; | |
| 68 | + } | |
| 69 | + if (order.getBrokerageUserId() == null) { | |
| 70 | + return; | |
| 71 | + } | |
| 72 | + | |
| 73 | + // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚 | |
| 74 | + orderItems = filterOrderItemListByNoneAfterSale(orderItems); | |
| 75 | + if (CollUtil.isEmpty(orderItems)) { | |
| 76 | + return; | |
| 77 | + } | |
| 78 | + orderItems.forEach(orderItem -> afterCancelOrderItem(order, orderItem)); | |
| 79 | + } | |
| 80 | + | |
| 81 | + @Override | |
| 82 | + public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) { | |
| 83 | + if (order.getBrokerageUserId() == null) { | |
| 84 | + return; | |
| 85 | + } | |
| 86 | + cancelBrokerage(order.getId(), orderItem.getOrderId()); | |
| 87 | + } | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * 创建分销记录 | |
| 91 | + * <p> | |
| 92 | + * 目前是支付成功后,就会创建分销记录。 | |
| 93 | + * <p> | |
| 94 | + * 业内还有两种做法,可以根据自己的业务调整: | |
| 95 | + * 1. 确认收货后,才创建分销记录 | |
| 96 | + * 2. 支付 or 下单成功时,创建分销记录(冻结),确认收货解冻或者 n 天后解冻 | |
| 97 | + * | |
| 98 | + * @param userId 用户编号 | |
| 99 | + * @param orderItems 订单项 | |
| 100 | + */ | |
| 101 | + protected void addBrokerage(Long userId, List<TradeOrderItemDO> orderItems) { | |
| 102 | + MemberUserRespDTO user = memberUserApi.getUser(userId); | |
| 103 | + Assert.notNull(user); | |
| 104 | + ProductSpuRespDTO spu = productSpuApi.getSpu(orderItems.get(0).getSpuId()); | |
| 105 | + Assert.notNull(spu); | |
| 106 | + ProductSkuRespDTO sku = productSkuApi.getSku(orderItems.get(0).getSkuId()); | |
| 107 | + | |
| 108 | + // 每一个订单项,都会去生成分销记录 | |
| 109 | + List<BrokerageAddReqBO> addList = convertList(orderItems, | |
| 110 | + item -> TradeOrderConvert.INSTANCE.convert(user, item, spu, sku)); | |
| 111 | + brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList); | |
| 112 | + } | |
| 113 | + | |
| 114 | + protected void cancelBrokerage(Long userId, Long orderItemId) { | |
| 115 | + brokerageRecordService.cancelBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, String.valueOf(orderItemId)); | |
| 116 | + } | |
| 117 | + | |
| 118 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationOrderHandler.java
| ... | ... | @@ -18,14 +18,15 @@ import java.util.List; |
| 18 | 18 | |
| 19 | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 20 | 20 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_CREATE_FAIL_EXIST_UNPAID; |
| 21 | +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS; | |
| 21 | 22 | |
| 22 | 23 | /** |
| 23 | - * 拼团订单 handler 接口实现类 | |
| 24 | + * 拼团订单的 {@link TradeOrderHandler} 实现类 | |
| 24 | 25 | * |
| 25 | 26 | * @author HUIHUI |
| 26 | 27 | */ |
| 27 | 28 | @Component |
| 28 | -public class TradeCombinationHandler implements TradeOrderHandler { | |
| 29 | +public class TradeCombinationOrderHandler implements TradeOrderHandler { | |
| 29 | 30 | |
| 30 | 31 | @Resource |
| 31 | 32 | @Lazy |
| ... | ... | @@ -41,16 +42,16 @@ public class TradeCombinationHandler implements TradeOrderHandler { |
| 41 | 42 | @Override |
| 42 | 43 | public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { |
| 43 | 44 | // 如果不是拼团订单则结束 |
| 44 | - if (TradeOrderTypeEnum.isCombination(order.getType())) { | |
| 45 | + if (!TradeOrderTypeEnum.isCombination(order.getType())) { | |
| 45 | 46 | return; |
| 46 | 47 | } |
| 47 | 48 | Assert.isTrue(orderItems.size() == 1, "拼团时,只允许选择一个商品"); |
| 48 | 49 | |
| 49 | - // 校验是否满足拼团活动相关限制 | |
| 50 | + // 1. 校验是否满足拼团活动相关限制 | |
| 50 | 51 | TradeOrderItemDO item = orderItems.get(0); |
| 51 | 52 | combinationRecordApi.validateCombinationRecord(order.getUserId(), order.getCombinationActivityId(), |
| 52 | 53 | order.getCombinationHeadId(), item.getSkuId(), item.getCount()); |
| 53 | - // 校验该用户是否存在未支付的拼团活动订单;就是还没支付的时候,重复下单了;需要校验下;不然的话,一个拼团可以下多个单子了; | |
| 54 | + // 2. 校验该用户是否存在未支付的拼团活动订单;就是还没支付的时候,重复下单了;需要校验下;不然的话,一个拼团可以下多个单子了; | |
| 54 | 55 | TradeOrderDO activityOrder = orderQueryService.getActivityOrderByUserIdAndActivityIdAndStatus( |
| 55 | 56 | order.getUserId(), order.getCombinationActivityId(), TradeOrderStatusEnum.UNPAID.getStatus()); |
| 56 | 57 | if (activityOrder != null) { |
| ... | ... | @@ -61,19 +62,32 @@ public class TradeCombinationHandler implements TradeOrderHandler { |
| 61 | 62 | @Override |
| 62 | 63 | public void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { |
| 63 | 64 | // 1.如果不是拼团订单则结束 |
| 64 | - if (TradeOrderTypeEnum.isCombination(order.getType())) { | |
| 65 | + if (!TradeOrderTypeEnum.isCombination(order.getType())) { | |
| 65 | 66 | return; |
| 66 | 67 | } |
| 67 | 68 | Assert.isTrue(orderItems.size() == 1, "拼团时,只允许选择一个商品"); |
| 68 | 69 | |
| 69 | - // 2.获取商品信息 | |
| 70 | + // 2. 创建拼团记录 | |
| 70 | 71 | TradeOrderItemDO item = orderItems.get(0); |
| 71 | - // 2.1.创建拼团记录 | |
| 72 | 72 | KeyValue<Long, Long> recordIdAndHeadId = combinationRecordApi.createCombinationRecord( |
| 73 | 73 | TradeOrderConvert.INSTANCE.convert(order, item)); |
| 74 | - // 3.更新拼团相关信息到订单 | |
| 74 | + | |
| 75 | + // 3. 更新拼团相关信息到订单 | |
| 76 | + // TODO 芋艿,只需要更新 record | |
| 75 | 77 | orderUpdateService.updateOrderCombinationInfo(order.getId(), order.getCombinationActivityId(), |
| 76 | 78 | recordIdAndHeadId.getKey(), recordIdAndHeadId.getValue()); |
| 77 | 79 | } |
| 78 | 80 | |
| 81 | + @Override | |
| 82 | + public void beforeDeliveryOrder(TradeOrderDO order) { | |
| 83 | + if (!TradeOrderTypeEnum.isCombination(order.getType())) { | |
| 84 | + return; | |
| 85 | + } | |
| 86 | + // 校验订单拼团是否成功 | |
| 87 | + if (!combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) { | |
| 88 | + throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS); | |
| 89 | + } | |
| 90 | + } | |
| 91 | + | |
| 79 | 92 | } |
| 93 | + | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCouponOrderHandler.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.order.handler; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; | |
| 4 | +import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; | |
| 5 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | |
| 6 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | |
| 7 | +import org.springframework.stereotype.Component; | |
| 8 | + | |
| 9 | +import javax.annotation.Resource; | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 12 | +/** | |
| 13 | + * 优惠劵的 {@link TradeOrderHandler} 实现类 | |
| 14 | + * | |
| 15 | + * @author 芋道源码 | |
| 16 | + */ | |
| 17 | +@Component | |
| 18 | +public class TradeCouponOrderHandler implements TradeOrderHandler { | |
| 19 | + | |
| 20 | + @Resource | |
| 21 | + private CouponApi couponApi; | |
| 22 | + | |
| 23 | + @Override | |
| 24 | + public void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 25 | + if (order.getCouponId() == null || order.getCouponId() <= 0) { | |
| 26 | + return; | |
| 27 | + } | |
| 28 | + // 不在前置扣减的原因,是因为优惠劵要记录使用的订单号 | |
| 29 | + couponApi.useCoupon(new CouponUseReqDTO().setId(order.getCouponId()).setUserId(order.getUserId()) | |
| 30 | + .setOrderId(order.getId())); | |
| 31 | + } | |
| 32 | + | |
| 33 | + @Override | |
| 34 | + public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 35 | + if (order.getCouponId() == null || order.getCouponId() <= 0) { | |
| 36 | + return; | |
| 37 | + } | |
| 38 | + // 退回优惠劵 | |
| 39 | + couponApi.returnUsedCoupon(order.getCouponId()); | |
| 40 | + } | |
| 41 | + | |
| 42 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeMemberPointOrderHandler.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.order.handler; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; | |
| 5 | +import cn.iocoder.yudao.module.member.api.point.MemberPointApi; | |
| 6 | +import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; | |
| 7 | +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; | |
| 8 | +import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO; | |
| 9 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | |
| 10 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | |
| 11 | +import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleService; | |
| 12 | +import org.springframework.stereotype.Component; | |
| 13 | + | |
| 14 | +import javax.annotation.Resource; | |
| 15 | +import java.util.List; | |
| 16 | + | |
| 17 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * 会员积分、等级的 {@link TradeOrderHandler} 实现类 | |
| 21 | + * | |
| 22 | + * @author owen | |
| 23 | + */ | |
| 24 | +@Component | |
| 25 | +public class TradeMemberPointOrderHandler implements TradeOrderHandler { | |
| 26 | + | |
| 27 | + @Resource | |
| 28 | + private MemberPointApi memberPointApi; | |
| 29 | + @Resource | |
| 30 | + private MemberLevelApi memberLevelApi; | |
| 31 | + | |
| 32 | + @Resource | |
| 33 | + private AfterSaleService afterSaleService; | |
| 34 | + | |
| 35 | + @Override | |
| 36 | + public void afterOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 37 | + // 扣减用户积分(订单抵扣)。不在前置扣减的原因,是因为积分扣减时,需要记录关联业务 | |
| 38 | + reducePoint(order.getUserId(), order.getUsePoint(), MemberPointBizTypeEnum.ORDER_USE, order.getId()); | |
| 39 | + } | |
| 40 | + | |
| 41 | + @Override | |
| 42 | + public void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 43 | + // 增加用户积分(订单赠送) | |
| 44 | + addPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE, | |
| 45 | + order.getId()); | |
| 46 | + | |
| 47 | + // 增加用户经验 | |
| 48 | + memberLevelApi.addExperience(order.getUserId(), order.getPayPrice(), | |
| 49 | + MemberExperienceBizTypeEnum.ORDER_GIVE.getType(), String.valueOf(order.getId())); | |
| 50 | + } | |
| 51 | + | |
| 52 | + @Override | |
| 53 | + public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 54 | + // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚 | |
| 55 | + orderItems = filterOrderItemListByNoneAfterSale(orderItems); | |
| 56 | + if (CollUtil.isEmpty(orderItems)) { | |
| 57 | + return; | |
| 58 | + } | |
| 59 | + | |
| 60 | + // 增加(回滚)用户积分(订单抵扣) | |
| 61 | + Integer usePoint = getSumValue(orderItems, TradeOrderItemDO::getUsePoint, Integer::sum); | |
| 62 | + addPoint(order.getUserId(), usePoint, MemberPointBizTypeEnum.ORDER_USE_CANCEL, | |
| 63 | + order.getId()); | |
| 64 | + | |
| 65 | + // 如下的返还,需要经过支持,也就是经历 afterPayOrder 流程 | |
| 66 | + if (!order.getPayStatus()) { | |
| 67 | + return; | |
| 68 | + } | |
| 69 | + // 扣减(回滚)积分(订单赠送) | |
| 70 | + Integer givePoint = getSumValue(orderItems, TradeOrderItemDO::getGivePoint, Integer::sum); | |
| 71 | + reducePoint(order.getUserId(), givePoint, MemberPointBizTypeEnum.ORDER_GIVE_CANCEL, | |
| 72 | + order.getId()); | |
| 73 | + // 扣减(回滚)用户经验 | |
| 74 | + int payPrice = order.getPayPrice() - order.getRefundPrice(); | |
| 75 | + memberLevelApi.addExperience(order.getUserId(), payPrice, | |
| 76 | + MemberExperienceBizTypeEnum.ORDER_GIVE_CANCEL.getType(), String.valueOf(order.getId())); | |
| 77 | + } | |
| 78 | + | |
| 79 | + @Override | |
| 80 | + public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) { | |
| 81 | + // 扣减(回滚)积分(订单赠送) | |
| 82 | + reducePoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.ORDER_GIVE_CANCEL_ITEM, | |
| 83 | + orderItem.getId()); | |
| 84 | + // 增加(回滚)积分(订单抵扣) | |
| 85 | + addPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.ORDER_USE_CANCEL_ITEM, | |
| 86 | + orderItem.getId()); | |
| 87 | + | |
| 88 | + // 扣减(回滚)用户经验 | |
| 89 | + AfterSaleDO afterSale = afterSaleService.getAfterSale(orderItem.getAfterSaleId()); | |
| 90 | + memberLevelApi.reduceExperience(order.getUserId(), afterSale.getRefundPrice(), | |
| 91 | + MemberExperienceBizTypeEnum.ORDER_GIVE_CANCEL_ITEM.getType(), String.valueOf(orderItem.getId())); | |
| 92 | + } | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * 添加用户积分 | |
| 96 | + * <p> | |
| 97 | + * 目前是支付成功后,就会创建积分记录。 | |
| 98 | + * <p> | |
| 99 | + * 业内还有两种做法,可以根据自己的业务调整: | |
| 100 | + * 1. 确认收货后,才创建积分记录 | |
| 101 | + * 2. 支付 or 下单成功时,创建积分记录(冻结),确认收货解冻或者 n 天后解冻 | |
| 102 | + * | |
| 103 | + * @param userId 用户编号 | |
| 104 | + * @param point 增加积分数量 | |
| 105 | + * @param bizType 业务编号 | |
| 106 | + * @param bizId 业务编号 | |
| 107 | + */ | |
| 108 | + protected void addPoint(Long userId, Integer point, MemberPointBizTypeEnum bizType, Long bizId) { | |
| 109 | + if (point != null && point > 0) { | |
| 110 | + memberPointApi.addPoint(userId, point, bizType.getType(), String.valueOf(bizId)); | |
| 111 | + } | |
| 112 | + } | |
| 113 | + | |
| 114 | + protected void reducePoint(Long userId, Integer point, MemberPointBizTypeEnum bizType, Long bizId) { | |
| 115 | + if (point != null && point > 0) { | |
| 116 | + memberPointApi.reducePoint(userId, point, bizType.getType(), String.valueOf(bizId)); | |
| 117 | + } | |
| 118 | + } | |
| 119 | + | |
| 120 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeOrderHandler.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.order.handler; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 3 | 4 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 4 | 5 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 6 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; | |
| 5 | 7 | |
| 6 | 8 | import java.util.List; |
| 7 | 9 | |
| ... | ... | @@ -35,16 +37,42 @@ public interface TradeOrderHandler { |
| 35 | 37 | * @param order 订单 |
| 36 | 38 | * @param orderItems 订单项 |
| 37 | 39 | */ |
| 38 | - default void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 39 | - } | |
| 40 | + default void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {} | |
| 40 | 41 | |
| 41 | 42 | /** |
| 42 | - * 订单取消 | |
| 43 | + * 订单取消后 | |
| 43 | 44 | * |
| 44 | 45 | * @param order 订单 |
| 45 | 46 | * @param orderItems 订单项 |
| 46 | 47 | */ |
| 47 | - default void cancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 48 | + default void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {} | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * 订单项取消后 | |
| 52 | + * | |
| 53 | + * @param order 订单 | |
| 54 | + * @param orderItem 订单项 | |
| 55 | + */ | |
| 56 | + default void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) {} | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * 订单发货前 | |
| 60 | + * | |
| 61 | + * @param order 订单 | |
| 62 | + */ | |
| 63 | + default void beforeDeliveryOrder(TradeOrderDO order) {} | |
| 64 | + | |
| 65 | + // ========== 公用方法 ========== | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * 过滤“未售后”的订单项列表 | |
| 69 | + * | |
| 70 | + * @param orderItems 订单项列表 | |
| 71 | + * @return 过滤后的订单项列表 | |
| 72 | + */ | |
| 73 | + default List<TradeOrderItemDO> filterOrderItemListByNoneAfterSale(List<TradeOrderItemDO> orderItems) { | |
| 74 | + return CollectionUtils.filterList(orderItems, | |
| 75 | + item -> TradeOrderItemAfterSaleStatusEnum.isNone(item.getAfterSaleStatus())); | |
| 48 | 76 | } |
| 49 | 77 | |
| 50 | 78 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeProductSkuOrderHandler.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.order.handler; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | |
| 5 | +import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; | |
| 6 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | |
| 7 | +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | |
| 8 | +import org.springframework.stereotype.Component; | |
| 9 | + | |
| 10 | +import javax.annotation.Resource; | |
| 11 | +import java.util.List; | |
| 12 | + | |
| 13 | +import static java.util.Collections.singletonList; | |
| 14 | + | |
| 15 | +/** | |
| 16 | + * 商品 SKU 库存的 {@link TradeOrderHandler} 实现类 | |
| 17 | + * | |
| 18 | + * @author 芋道源码 | |
| 19 | + */ | |
| 20 | +@Component | |
| 21 | +public class TradeProductSkuOrderHandler implements TradeOrderHandler { | |
| 22 | + | |
| 23 | + @Resource | |
| 24 | + private ProductSkuApi productSkuApi; | |
| 25 | + | |
| 26 | + @Override | |
| 27 | + public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 28 | + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems)); | |
| 29 | + } | |
| 30 | + | |
| 31 | + @Override | |
| 32 | + public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 33 | + // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚 | |
| 34 | + orderItems = filterOrderItemListByNoneAfterSale(orderItems); | |
| 35 | + if (CollUtil.isEmpty(orderItems)) { | |
| 36 | + return; | |
| 37 | + } | |
| 38 | + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems)); | |
| 39 | + } | |
| 40 | + | |
| 41 | + @Override | |
| 42 | + public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) { | |
| 43 | + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(singletonList(orderItem))); | |
| 44 | + } | |
| 45 | + | |
| 46 | +} | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeSeckillHandler.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeSeckillOrderHandler.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.service.order.handler; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.hutool.core.lang.Assert; |
| 4 | 5 | import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi; |
| 5 | 6 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| ... | ... | @@ -11,19 +12,19 @@ import javax.annotation.Resource; |
| 11 | 12 | import java.util.List; |
| 12 | 13 | |
| 13 | 14 | /** |
| 14 | - * 秒杀订单 handler 实现类 | |
| 15 | + * 秒杀订单的 {@link TradeOrderHandler} 实现类 | |
| 15 | 16 | * |
| 16 | 17 | * @author HUIHUI |
| 17 | 18 | */ |
| 18 | 19 | @Component |
| 19 | -public class TradeSeckillHandler implements TradeOrderHandler { | |
| 20 | +public class TradeSeckillOrderHandler implements TradeOrderHandler { | |
| 20 | 21 | |
| 21 | 22 | @Resource |
| 22 | 23 | private SeckillActivityApi seckillActivityApi; |
| 23 | 24 | |
| 24 | 25 | @Override |
| 25 | 26 | public void beforeOrderCreate(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { |
| 26 | - if (TradeOrderTypeEnum.isSeckill(order.getType())) { | |
| 27 | + if (!TradeOrderTypeEnum.isSeckill(order.getType())) { | |
| 27 | 28 | return; |
| 28 | 29 | } |
| 29 | 30 | // 明确校验一下 |
| ... | ... | @@ -35,16 +36,29 @@ public class TradeSeckillHandler implements TradeOrderHandler { |
| 35 | 36 | } |
| 36 | 37 | |
| 37 | 38 | @Override |
| 38 | - public void cancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 39 | - if (TradeOrderTypeEnum.isSeckill(order.getType())) { | |
| 39 | + public void afterCancelOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) { | |
| 40 | + if (!TradeOrderTypeEnum.isSeckill(order.getType())) { | |
| 40 | 41 | return; |
| 41 | 42 | } |
| 42 | 43 | // 明确校验一下 |
| 43 | 44 | Assert.isTrue(orderItems.size() == 1, "秒杀时,只允许选择一个商品"); |
| 44 | 45 | |
| 46 | + // 售后的订单项,已经在 afterCancelOrderItem 回滚库存,所以这里不需要重复回滚 | |
| 47 | + orderItems = filterOrderItemListByNoneAfterSale(orderItems); | |
| 48 | + if (CollUtil.isEmpty(orderItems)) { | |
| 49 | + return; | |
| 50 | + } | |
| 51 | + afterCancelOrderItem(order, orderItems.get(0)); | |
| 52 | + } | |
| 53 | + | |
| 54 | + @Override | |
| 55 | + public void afterCancelOrderItem(TradeOrderDO order, TradeOrderItemDO orderItem) { | |
| 56 | + if (!TradeOrderTypeEnum.isSeckill(order.getType())) { | |
| 57 | + return; | |
| 58 | + } | |
| 45 | 59 | // 恢复秒杀活动的库存 |
| 46 | 60 | seckillActivityApi.updateSeckillStockIncr(order.getSeckillActivityId(), |
| 47 | - orderItems.get(0).getSkuId(), orderItems.get(0).getCount()); | |
| 61 | + orderItem.getSkuId(), orderItem.getCount()); | |
| 48 | 62 | } |
| 49 | 63 | |
| 50 | 64 | } | ... | ... |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApi.java
| ... | ... | @@ -28,4 +28,14 @@ public interface MemberLevelApi { |
| 28 | 28 | */ |
| 29 | 29 | void addExperience(Long userId, Integer experience, Integer bizType, String bizId); |
| 30 | 30 | |
| 31 | + /** | |
| 32 | + * 扣减会员经验 | |
| 33 | + * | |
| 34 | + * @param userId 会员ID | |
| 35 | + * @param experience 经验 | |
| 36 | + * @param bizType 业务类型 {@link MemberExperienceBizTypeEnum} | |
| 37 | + * @param bizId 业务编号 | |
| 38 | + */ | |
| 39 | + void reduceExperience(Long userId, Integer experience, Integer bizType, String bizId); | |
| 40 | + | |
| 31 | 41 | } | ... | ... |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberExperienceBizTypeEnum.java
| ... | ... | @@ -20,10 +20,11 @@ public enum MemberExperienceBizTypeEnum { |
| 20 | 20 | */ |
| 21 | 21 | ADMIN(0, "管理员调整", "管理员调整获得 {} 经验", true), |
| 22 | 22 | INVITE_REGISTER(1, "邀新奖励", "邀请好友获得 {} 经验", true), |
| 23 | - ORDER(2, "下单奖励", "下单获得 {} 经验", true), | |
| 24 | - REFUND(3, "退单扣除", "退单获得 {} 经验", false), | |
| 25 | 23 | SIGN_IN(4, "签到奖励", "签到获得 {} 经验", true), |
| 26 | 24 | LOTTERY(5, "抽奖奖励", "抽奖获得 {} 经验", true), |
| 25 | + ORDER_GIVE(11, "下单奖励", "下单获得 {} 经验", true), | |
| 26 | + ORDER_GIVE_CANCEL(12, "下单奖励(整单取消)", "取消订单获得 {} 经验", false), // ORDER_GIVE 的取消 | |
| 27 | + ORDER_GIVE_CANCEL_ITEM(13, "下单奖励(单个退款)", "退款订单获得 {} 经验", false), // ORDER_GIVE 的取消 | |
| 27 | 28 | ; |
| 28 | 29 | |
| 29 | 30 | /** | ... | ... |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java
| ... | ... | @@ -18,11 +18,14 @@ public enum MemberPointBizTypeEnum implements IntArrayValuable { |
| 18 | 18 | |
| 19 | 19 | SIGN(1, "签到", "签到获得 {} 积分", true), |
| 20 | 20 | ADMIN(2, "管理员修改", "管理员修改 {} 积分", true), |
| 21 | - ORDER_GIVE(10, "订单奖励", "下单获得 {} 积分", true), // 支付订单时,赠送积分 | |
| 22 | - ORDER_CANCEL(11, "订单取消", "订单取消,退还 {} 积分", true), // 取消订单时,退回积分 | |
| 23 | - ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 下单时,扣减积分 | |
| 24 | - AFTER_SALE_REFUND_USED(13, "订单退款", "订单退款,退还 {} 积分", true), // 售后订单成功时,退回积分(对应 ORDER_USE 操作) | |
| 25 | - AFTER_SALE_DEDUCT_GIVE(14, "订单退款", "订单退款,扣除赠送的 {} 积分", false), // 售后订单成功时,扣减积分(对应 ORDER_GIVE 操作) | |
| 21 | + | |
| 22 | + ORDER_USE(11, "订单积分抵扣", "下单使用 {} 积分", false), // 下单时,扣减积分 | |
| 23 | + ORDER_USE_CANCEL(12, "订单积分抵扣(整单取消)", "订单取消,退还 {} 积分", true), // ORDER_USE 的取消 | |
| 24 | + ORDER_USE_CANCEL_ITEM(13, "订单积分抵扣(单个退款)", "订单退款,退还 {} 积分", true), // ORDER_USE 的取消 | |
| 25 | + | |
| 26 | + ORDER_GIVE(21, "订单积分奖励", "下单获得 {} 积分", true), // 支付订单时,赠送积分 | |
| 27 | + ORDER_GIVE_CANCEL(22, "订单积分奖励(整单取消)", "订单取消,退还 {} 积分", false), // ORDER_GIVE 的取消 | |
| 28 | + ORDER_GIVE_CANCEL_ITEM(23, "订单积分奖励(单个退款)", "订单退款,扣除赠送的 {} 积分", false) // ORDER_GIVE 的取消 | |
| 26 | 29 | ; |
| 27 | 30 | |
| 28 | 31 | /** | ... | ... |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/level/MemberLevelApiImpl.java
| ... | ... | @@ -38,4 +38,9 @@ public class MemberLevelApiImpl implements MemberLevelApi { |
| 38 | 38 | memberLevelService.addExperience(userId, experience, bizTypeEnum, bizId); |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | + @Override | |
| 42 | + public void reduceExperience(Long userId, Integer experience, Integer bizType, String bizId) { | |
| 43 | + addExperience(userId, -experience, bizType, bizId); | |
| 44 | + } | |
| 45 | + | |
| 41 | 46 | } | ... | ... |