Ver código fonte

Merge branch 'mall_order_cancel' of https://gitee.com/CrazyWorld/ruoyi-vue-pro into feature/mall_product

 Conflicts:
	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java
	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
YunaiV 1 ano atrás
pai
commit
9c0d0c809a

+ 6 - 0
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java

@@ -28,4 +28,10 @@ public interface CouponApi {
      */
     CouponRespDTO validateCoupon(@Valid CouponValidReqDTO validReqDTO);
 
+    /**
+     * 退还已使用的优惠券
+     *
+     * @param id 优惠券编号
+     */
+    void returnUsedCoupon(Long id);
 }

+ 1 - 0
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java

@@ -37,6 +37,7 @@ public interface ErrorCodeConstants {
     ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1013005001, "回收优惠劵失败,优惠劵已被使用");
     ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1013005002, "优惠劵不处于待使用状态");
     ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1013005003, "优惠券不在使用时间范围内");
+    ErrorCode COUPON_STATUS_NOT_USED = new ErrorCode(1013005004, "优惠劵不是已使用状态");
 
     // ========== 满减送活动 1013006000 ==========
     ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1013006000, "满减送活动不存在");

+ 5 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java

@@ -34,4 +34,9 @@ public class CouponApiImpl implements CouponApi {
         return CouponConvert.INSTANCE.convert(coupon);
     }
 
+    @Override
+    public void returnUsedCoupon(Long id) {
+        couponService.returnUsedCoupon(id);
+    }
+
 }

+ 7 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java

@@ -116,4 +116,11 @@ public interface CouponService {
     default void takeCouponByRegister(Long templateId, Long userId) {
         takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER);
     }
+
+    /**
+     * 退还已使用的优惠券
+     *
+     * @param id 优惠券编号
+     */
+    void returnUsedCoupon(Long id);
 }

+ 23 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java

@@ -202,4 +202,27 @@ public class CouponServiceImpl implements CouponService {
         userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount());
     }
 
+    @Override
+    public void returnUsedCoupon(Long id) {
+        // 校验存在
+        CouponDO coupon = couponMapper.selectById(id);
+        if (coupon == null) {
+            throw exception(COUPON_NOT_EXISTS);
+        }
+
+        // 校验状态
+        if (!CouponStatusEnum.USED.getStatus().equals(coupon.getStatus())) {
+            throw exception(COUPON_STATUS_NOT_USED);
+        }
+
+        // 退还
+        Integer status = LocalDateTimeUtils.beforeNow(coupon.getValidEndTime())
+                // 退还时可能已经过期了
+                ? CouponStatusEnum.EXPIRE.getStatus()
+                : CouponStatusEnum.UNUSED.getStatus();
+        couponMapper.updateById(new CouponDO().setId(id).setStatus(status));
+
+        // TODO 增加优惠券变动记录?
+    }
+
 }

+ 1 - 0
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java

@@ -33,6 +33,7 @@ public interface ErrorCodeConstants {
     ErrorCode ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000022, "交易订单发货失败,拼团未成功");
     ErrorCode ORDER_DELIVERY_FAIL_BARGAIN_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000023, "交易订单发货失败,砍价未成功");
     ErrorCode ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS = new ErrorCode(1011000024, "交易订单发货失败,发货类型不是快递");
+    ErrorCode ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID = new ErrorCode(1011000025, "交易订单取消失败,订单不是【待支付】状态");
 
     // ==========  After Sale 模块 1011000100 ==========
     ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在");

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java

@@ -149,7 +149,7 @@ public class AppTradeOrderController {
     @Operation(summary = "取消交易订单")
     @Parameter(name = "id", description = "交易订单编号")
     public CommonResult<Boolean> cancelOrder(@RequestParam("id") Long id) {
-        // TODO @芋艿:未实现,mock 用
+        tradeOrderUpdateService.cancelOrder(getLoginUserId(), id);
         return success(true);
     }
 

+ 5 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java

@@ -88,6 +88,11 @@ public interface TradeOrderConvert {
         return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list));
     }
 
+    default ProductSkuUpdateStockReqDTO convertNegative(List<TradeOrderItemDO> list) {
+        List<ProductSkuUpdateStockReqDTO.Item> items = TradeOrderConvert.INSTANCE.convertList(list);
+        items.forEach(item -> item.setIncrCount(-item.getIncrCount()));
+        return new ProductSkuUpdateStockReqDTO(items);
+    }
     List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list);
 
     @Mappings({

+ 7 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java

@@ -117,4 +117,11 @@ public interface TradeOrderUpdateService {
      */
     Long createOrderItemComment(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO);
 
+    /**
+     * 【会员】取消订单
+     *
+     * @param userId 用户ID
+     * @param id     订单编号
+     */
+    void cancelOrder(Long userId, Long id);
 }

+ 37 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java

@@ -299,7 +299,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         // 1)如果是秒杀商品:额外扣减秒杀的库存;
         // 2)如果是拼团活动:额外扣减拼团的库存;
         // 3)如果是砍价活动:额外扣减砍价的库存;
-        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems));
+        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
 
         // 删除购物车商品
         Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
@@ -308,6 +308,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         }
 
         // 扣减积分 TODO 芋艿:待实现,需要前置;
+        // 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣
 
         // 有使用优惠券时更新 TODO 芋艿:需要前置;
         if (createReqVO.getCouponId() != null) {
@@ -670,6 +671,41 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         return comment;
     }
 
+    @Override
+    public void cancelOrder(Long userId, Long id) {
+        // 校验存在
+        TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(id, userId);
+        if (order == null) {
+            throw exception(ORDER_NOT_FOUND);
+        }
+        // 校验状态
+        if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus())) {
+            throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID);
+        }
+
+        // 1.更新 TradeOrderDO 状态为已取消
+        int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(),
+                new TradeOrderDO().setStatus(TradeOrderStatusEnum.CANCELED.getStatus())
+                        .setCancelTime(LocalDateTime.now())
+                        .setCancelType(TradeOrderCancelTypeEnum.MEMBER_CANCEL.getType()));
+        if (updateCount == 0) {
+            throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID);
+        }
+
+        // 2.回滚库存
+        List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
+        productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems));
+
+        // 3.回滚优惠券
+        couponApi.returnUsedCoupon(order.getCouponId());
+
+        // 4.回滚积分:积分是支付成功后才增加的吧?
+
+        // TODO 芋艿:OrderLog
+
+        // TODO 芋艿:lili 发送订单变化的消息
+    }
+
     /**
      * 判断指定订单的所有订单项,是不是都售后成功
      *