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
This commit is contained in:
YunaiV 2023-09-02 00:45:26 +08:00
commit 9c0d0c809a
10 changed files with 93 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -202,4 +202,27 @@ public class CouponServiceImpl implements CouponService {
userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount()); 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 增加优惠券变动记录
}
} }

View File

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

View File

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

View File

@ -88,6 +88,11 @@ public interface TradeOrderConvert {
return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list)); 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); List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list);
@Mappings({ @Mappings({

View File

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

View File

@ -299,7 +299,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
// 1如果是秒杀商品额外扣减秒杀的库存 // 1如果是秒杀商品额外扣减秒杀的库存
// 2如果是拼团活动额外扣减拼团的库存 // 2如果是拼团活动额外扣减拼团的库存
// 3如果是砍价活动额外扣减砍价的库存 // 3如果是砍价活动额外扣减砍价的库存
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems)); productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
// 删除购物车商品 // 删除购物车商品
Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
@ -308,6 +308,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
} }
// 扣减积分 TODO 芋艿待实现需要前置 // 扣减积分 TODO 芋艿待实现需要前置
// 这个是不是应该放到支付成功之后如果支付后的话可能积分可以重复使用哈资源类都要预扣
// 有使用优惠券时更新 TODO 芋艿需要前置 // 有使用优惠券时更新 TODO 芋艿需要前置
if (createReqVO.getCouponId() != null) { if (createReqVO.getCouponId() != null) {
@ -670,6 +671,41 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
return comment; 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 发送订单变化的消息
}
/** /**
* 判断指定订单的所有订单项是不是都售后成功 * 判断指定订单的所有订单项是不是都售后成功
* *