Commit 9c0d0c809a340169816183b5874ebdfb5544295d
Merge branch 'mall_order_cancel' of https://gitee.com/CrazyWorld/ruoyi-vue-pro i…
…nto 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
Showing
10 changed files
with
93 additions
and
2 deletions
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 { | @@ -28,4 +28,10 @@ public interface CouponApi { | ||
| 28 | */ | 28 | */ |
| 29 | CouponRespDTO validateCoupon(@Valid CouponValidReqDTO validReqDTO); | 29 | CouponRespDTO validateCoupon(@Valid CouponValidReqDTO validReqDTO); |
| 30 | 30 | ||
| 31 | + /** | ||
| 32 | + * 退还已使用的优惠券 | ||
| 33 | + * | ||
| 34 | + * @param id 优惠券编号 | ||
| 35 | + */ | ||
| 36 | + void returnUsedCoupon(Long id); | ||
| 31 | } | 37 | } |
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 { | @@ -37,6 +37,7 @@ public interface ErrorCodeConstants { | ||
| 37 | ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1013005001, "回收优惠劵失败,优惠劵已被使用"); | 37 | ErrorCode COUPON_DELETE_FAIL_USED = new ErrorCode(1013005001, "回收优惠劵失败,优惠劵已被使用"); |
| 38 | ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1013005002, "优惠劵不处于待使用状态"); | 38 | ErrorCode COUPON_STATUS_NOT_UNUSED = new ErrorCode(1013005002, "优惠劵不处于待使用状态"); |
| 39 | ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1013005003, "优惠券不在使用时间范围内"); | 39 | ErrorCode COUPON_VALID_TIME_NOT_NOW = new ErrorCode(1013005003, "优惠券不在使用时间范围内"); |
| 40 | + ErrorCode COUPON_STATUS_NOT_USED = new ErrorCode(1013005004, "优惠劵不是已使用状态"); | ||
| 40 | 41 | ||
| 41 | // ========== 满减送活动 1013006000 ========== | 42 | // ========== 满减送活动 1013006000 ========== |
| 42 | ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1013006000, "满减送活动不存在"); | 43 | ErrorCode REWARD_ACTIVITY_NOT_EXISTS = new ErrorCode(1013006000, "满减送活动不存在"); |
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 { | @@ -34,4 +34,9 @@ public class CouponApiImpl implements CouponApi { | ||
| 34 | return CouponConvert.INSTANCE.convert(coupon); | 34 | return CouponConvert.INSTANCE.convert(coupon); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | + @Override | ||
| 38 | + public void returnUsedCoupon(Long id) { | ||
| 39 | + couponService.returnUsedCoupon(id); | ||
| 40 | + } | ||
| 41 | + | ||
| 37 | } | 42 | } |
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 { | @@ -116,4 +116,11 @@ public interface CouponService { | ||
| 116 | default void takeCouponByRegister(Long templateId, Long userId) { | 116 | default void takeCouponByRegister(Long templateId, Long userId) { |
| 117 | takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); | 117 | takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); |
| 118 | } | 118 | } |
| 119 | + | ||
| 120 | + /** | ||
| 121 | + * 退还已使用的优惠券 | ||
| 122 | + * | ||
| 123 | + * @param id 优惠券编号 | ||
| 124 | + */ | ||
| 125 | + void returnUsedCoupon(Long id); | ||
| 119 | } | 126 | } |
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 { | @@ -202,4 +202,27 @@ public class CouponServiceImpl implements CouponService { | ||
| 202 | userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount()); | 202 | userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount()); |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | + @Override | ||
| 206 | + public void returnUsedCoupon(Long id) { | ||
| 207 | + // 校验存在 | ||
| 208 | + CouponDO coupon = couponMapper.selectById(id); | ||
| 209 | + if (coupon == null) { | ||
| 210 | + throw exception(COUPON_NOT_EXISTS); | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + // 校验状态 | ||
| 214 | + if (!CouponStatusEnum.USED.getStatus().equals(coupon.getStatus())) { | ||
| 215 | + throw exception(COUPON_STATUS_NOT_USED); | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + // 退还 | ||
| 219 | + Integer status = LocalDateTimeUtils.beforeNow(coupon.getValidEndTime()) | ||
| 220 | + // 退还时可能已经过期了 | ||
| 221 | + ? CouponStatusEnum.EXPIRE.getStatus() | ||
| 222 | + : CouponStatusEnum.UNUSED.getStatus(); | ||
| 223 | + couponMapper.updateById(new CouponDO().setId(id).setStatus(status)); | ||
| 224 | + | ||
| 225 | + // TODO 增加优惠券变动记录? | ||
| 226 | + } | ||
| 227 | + | ||
| 205 | } | 228 | } |
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 { | @@ -33,6 +33,7 @@ public interface ErrorCodeConstants { | ||
| 33 | ErrorCode ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000022, "交易订单发货失败,拼团未成功"); | 33 | ErrorCode ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000022, "交易订单发货失败,拼团未成功"); |
| 34 | ErrorCode ORDER_DELIVERY_FAIL_BARGAIN_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000023, "交易订单发货失败,砍价未成功"); | 34 | ErrorCode ORDER_DELIVERY_FAIL_BARGAIN_RECORD_STATUS_NOT_SUCCESS = new ErrorCode(1011000023, "交易订单发货失败,砍价未成功"); |
| 35 | ErrorCode ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS = new ErrorCode(1011000024, "交易订单发货失败,发货类型不是快递"); | 35 | ErrorCode ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS = new ErrorCode(1011000024, "交易订单发货失败,发货类型不是快递"); |
| 36 | + ErrorCode ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID = new ErrorCode(1011000025, "交易订单取消失败,订单不是【待支付】状态"); | ||
| 36 | 37 | ||
| 37 | // ========== After Sale 模块 1011000100 ========== | 38 | // ========== After Sale 模块 1011000100 ========== |
| 38 | ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); | 39 | ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); |
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 { | @@ -149,7 +149,7 @@ public class AppTradeOrderController { | ||
| 149 | @Operation(summary = "取消交易订单") | 149 | @Operation(summary = "取消交易订单") |
| 150 | @Parameter(name = "id", description = "交易订单编号") | 150 | @Parameter(name = "id", description = "交易订单编号") |
| 151 | public CommonResult<Boolean> cancelOrder(@RequestParam("id") Long id) { | 151 | public CommonResult<Boolean> cancelOrder(@RequestParam("id") Long id) { |
| 152 | - // TODO @芋艿:未实现,mock 用 | 152 | + tradeOrderUpdateService.cancelOrder(getLoginUserId(), id); |
| 153 | return success(true); | 153 | return success(true); |
| 154 | } | 154 | } |
| 155 | 155 |
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 { | @@ -88,6 +88,11 @@ public interface TradeOrderConvert { | ||
| 88 | return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list)); | 88 | return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list)); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | + default ProductSkuUpdateStockReqDTO convertNegative(List<TradeOrderItemDO> list) { | ||
| 92 | + List<ProductSkuUpdateStockReqDTO.Item> items = TradeOrderConvert.INSTANCE.convertList(list); | ||
| 93 | + items.forEach(item -> item.setIncrCount(-item.getIncrCount())); | ||
| 94 | + return new ProductSkuUpdateStockReqDTO(items); | ||
| 95 | + } | ||
| 91 | List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list); | 96 | List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list); |
| 92 | 97 | ||
| 93 | @Mappings({ | 98 | @Mappings({ |
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 { | @@ -117,4 +117,11 @@ public interface TradeOrderUpdateService { | ||
| 117 | */ | 117 | */ |
| 118 | Long createOrderItemComment(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO); | 118 | Long createOrderItemComment(Long userId, AppTradeOrderItemCommentCreateReqVO createReqVO); |
| 119 | 119 | ||
| 120 | + /** | ||
| 121 | + * 【会员】取消订单 | ||
| 122 | + * | ||
| 123 | + * @param userId 用户ID | ||
| 124 | + * @param id 订单编号 | ||
| 125 | + */ | ||
| 126 | + void cancelOrder(Long userId, Long id); | ||
| 120 | } | 127 | } |
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 { | @@ -299,7 +299,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 299 | // 1)如果是秒杀商品:额外扣减秒杀的库存; | 299 | // 1)如果是秒杀商品:额外扣减秒杀的库存; |
| 300 | // 2)如果是拼团活动:额外扣减拼团的库存; | 300 | // 2)如果是拼团活动:额外扣减拼团的库存; |
| 301 | // 3)如果是砍价活动:额外扣减砍价的库存; | 301 | // 3)如果是砍价活动:额外扣减砍价的库存; |
| 302 | - productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems)); | 302 | + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems)); |
| 303 | 303 | ||
| 304 | // 删除购物车商品 | 304 | // 删除购物车商品 |
| 305 | Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); | 305 | Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); |
| @@ -308,6 +308,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -308,6 +308,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 308 | } | 308 | } |
| 309 | 309 | ||
| 310 | // 扣减积分 TODO 芋艿:待实现,需要前置; | 310 | // 扣减积分 TODO 芋艿:待实现,需要前置; |
| 311 | + // 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣 | ||
| 311 | 312 | ||
| 312 | // 有使用优惠券时更新 TODO 芋艿:需要前置; | 313 | // 有使用优惠券时更新 TODO 芋艿:需要前置; |
| 313 | if (createReqVO.getCouponId() != null) { | 314 | if (createReqVO.getCouponId() != null) { |
| @@ -670,6 +671,41 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -670,6 +671,41 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 670 | return comment; | 671 | return comment; |
| 671 | } | 672 | } |
| 672 | 673 | ||
| 674 | + @Override | ||
| 675 | + public void cancelOrder(Long userId, Long id) { | ||
| 676 | + // 校验存在 | ||
| 677 | + TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(id, userId); | ||
| 678 | + if (order == null) { | ||
| 679 | + throw exception(ORDER_NOT_FOUND); | ||
| 680 | + } | ||
| 681 | + // 校验状态 | ||
| 682 | + if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.UNPAID.getStatus())) { | ||
| 683 | + throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID); | ||
| 684 | + } | ||
| 685 | + | ||
| 686 | + // 1.更新 TradeOrderDO 状态为已取消 | ||
| 687 | + int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), | ||
| 688 | + new TradeOrderDO().setStatus(TradeOrderStatusEnum.CANCELED.getStatus()) | ||
| 689 | + .setCancelTime(LocalDateTime.now()) | ||
| 690 | + .setCancelType(TradeOrderCancelTypeEnum.MEMBER_CANCEL.getType())); | ||
| 691 | + if (updateCount == 0) { | ||
| 692 | + throw exception(ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID); | ||
| 693 | + } | ||
| 694 | + | ||
| 695 | + // 2.回滚库存 | ||
| 696 | + List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id); | ||
| 697 | + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems)); | ||
| 698 | + | ||
| 699 | + // 3.回滚优惠券 | ||
| 700 | + couponApi.returnUsedCoupon(order.getCouponId()); | ||
| 701 | + | ||
| 702 | + // 4.回滚积分:积分是支付成功后才增加的吧? | ||
| 703 | + | ||
| 704 | + // TODO 芋艿:OrderLog | ||
| 705 | + | ||
| 706 | + // TODO 芋艿:lili 发送订单变化的消息 | ||
| 707 | + } | ||
| 708 | + | ||
| 673 | /** | 709 | /** |
| 674 | * 判断指定订单的所有订单项,是不是都售后成功 | 710 | * 判断指定订单的所有订单项,是不是都售后成功 |
| 675 | * | 711 | * |