diff --git a/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/AbstractOrderPlacementStrategy.java b/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/AbstractOrderPlacementStrategy.java index 8143397..ebe2e53 100644 --- a/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/AbstractOrderPlacementStrategy.java +++ b/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/AbstractOrderPlacementStrategy.java @@ -7,6 +7,7 @@ import com.starry.admin.modules.order.module.dto.OrderPlacementCommand; import com.starry.admin.modules.order.module.dto.OrderPlacementResult; import com.starry.admin.modules.order.module.dto.PaymentInfo; import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity; +import java.math.BigDecimal; abstract class AbstractOrderPlacementStrategy implements OrderPlacementStrategy { @@ -26,16 +27,19 @@ abstract class AbstractOrderPlacementStrategy implements OrderPlacementStrategy throw new CustomException("支付信息不能为空"); } - PlayOrderInfoEntity order = service.createOrderRecord(context); - - if (command.isDeductBalance() && service.shouldDeductBalance(context)) { + BigDecimal netAmount = service.normalizeMoney(paymentInfo.getFinalAmount()); + boolean shouldDeduct = command.isDeductBalance() && service.shouldDeductBalance(context); + if (shouldDeduct) { + service.validateSufficientBalance(context.getPurchaserBy(), netAmount); service.deductCustomerBalance( context.getPurchaserBy(), - service.normalizeMoney(paymentInfo.getFinalAmount()), + netAmount, command.getBalanceOperationAction(), - order.getId()); + context.getOrderId()); } + PlayOrderInfoEntity order = service.createOrderRecord(context); + OrderAmountBreakdown amountBreakdown = breakdown != null ? breakdown : service.fallbackBreakdown(paymentInfo); return OrderPlacementResult.of(order, amountBreakdown); diff --git a/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/OrderLifecycleServiceImpl.java b/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/OrderLifecycleServiceImpl.java index 6847ad2..dc3c41f 100644 --- a/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/OrderLifecycleServiceImpl.java +++ b/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/OrderLifecycleServiceImpl.java @@ -162,6 +162,7 @@ public class OrderLifecycleServiceImpl implements IOrderLifecycleService { validateCouponUsage(context); + OrderConstant.RewardType rewardType = context.getRewardType() != null ? context.getRewardType() : OrderConstant.RewardType.NOT_APPLICABLE; @@ -278,6 +279,18 @@ public class OrderLifecycleServiceImpl implements IOrderLifecycleService { return OrderAmountBreakdown.of(grossAmount, discountAmount, netAmount); } + void validateSufficientBalance(String customerId, BigDecimal requiredAmount) { + PlayCustomUserInfoEntity customer = customUserInfoService.selectById(customerId); + if (customer == null) { + throw new CustomException("顾客不存在"); + } + BigDecimal before = normalizeMoney(customer.getAccountBalance()); + BigDecimal required = normalizeMoney(requiredAmount); + if (required.compareTo(before) > 0) { + throw new ServiceException("余额不足", 998); + } + } + void deductCustomerBalance( String customerId, BigDecimal netAmount, @@ -288,10 +301,11 @@ public class OrderLifecycleServiceImpl implements IOrderLifecycleService { throw new CustomException("顾客不存在"); } BigDecimal before = normalizeMoney(customer.getAccountBalance()); - if (netAmount.compareTo(before) > 0) { + BigDecimal amountToDeduct = normalizeMoney(netAmount); + if (amountToDeduct.compareTo(before) > 0) { throw new ServiceException("余额不足", 998); } - BigDecimal after = normalizeMoney(before.subtract(netAmount)); + BigDecimal after = normalizeMoney(before.subtract(amountToDeduct)); String action = StrUtil.isNotBlank(operationAction) ? operationAction : "下单"; customUserInfoService.updateAccountBalanceById( customerId, @@ -299,7 +313,7 @@ public class OrderLifecycleServiceImpl implements IOrderLifecycleService { after, BalanceOperationType.CONSUME.getCode(), action, - netAmount, + amountToDeduct, BigDecimal.ZERO, orderId); } diff --git a/play-admin/src/test/java/com/starry/admin/modules/order/service/impl/OrderLifecycleServiceImplTest.java b/play-admin/src/test/java/com/starry/admin/modules/order/service/impl/OrderLifecycleServiceImplTest.java index edce129..f59da95 100644 --- a/play-admin/src/test/java/com/starry/admin/modules/order/service/impl/OrderLifecycleServiceImplTest.java +++ b/play-admin/src/test/java/com/starry/admin/modules/order/service/impl/OrderLifecycleServiceImplTest.java @@ -733,6 +733,8 @@ private PlayOrderLogInfoMapper orderLogInfoMapper; assertThrows(ServiceException.class, () -> lifecycleService.placeOrder(command)); verify(customUserInfoService, never()).updateAccountBalanceById(anyString(), any(), any(), anyString(), anyString(), any(), any(), anyString()); + verify(orderInfoMapper, never()).insert(any()); + verify(customUserInfoService, never()).saveOrderInfo(any()); } @Test @@ -863,6 +865,8 @@ private PlayOrderLogInfoMapper orderLogInfoMapper; null); assertThrows(ServiceException.class, () -> lifecycleService.placeOrder(command)); + verify(orderInfoMapper, never()).insert(any()); + verify(customUserInfoService, never()).saveOrderInfo(any()); } @Test @@ -962,7 +966,7 @@ private PlayOrderLogInfoMapper orderLogInfoMapper; null, null)); - verify(customUserInfoService).selectById(context.getPurchaserBy()); + verify(customUserInfoService, times(2)).selectById(context.getPurchaserBy()); verify(customUserInfoService).updateAccountBalanceById( eq(customer.getId()), eq(customer.getAccountBalance()),