Browse Source

feat(order): 优化优惠券处理逻辑

- 重构优惠券处理流程,提高代码可读性和可维护性
- 增加优惠券有效性验证,包括用户归属、使用状态和有效期
-优化优惠金额计算逻辑,支持满减券、折扣券和免费券
- 新增标记优惠券为已使用功能
- 在订单创建流程中应用优惠券并更新相关金额
main
科技小王子 2 days ago
parent
commit
b8150b021b
  1. 1
      src/main/java/com/gxwebsoft/shop/controller/ShopUserAddressController.java
  2. 120
      src/main/java/com/gxwebsoft/shop/service/OrderBusinessService.java

1
src/main/java/com/gxwebsoft/shop/controller/ShopUserAddressController.java

@ -44,6 +44,7 @@
@GetMapping()
public ApiResult<List<ShopUserAddress>> list(ShopUserAddressParam param) {
// 使用关联查询
param.setUserId(getLoginUser().getUserId());
return success(shopUserAddressService.listRel(param));
}

120
src/main/java/com/gxwebsoft/shop/service/OrderBusinessService.java

@ -81,7 +81,12 @@ public class OrderBusinessService {
// 6. 保存订单商品
saveOrderGoods(request, shopOrder);
// 7. 创建微信支付订单
// 7. 标记优惠券为已使用
if (shopOrder.getCouponId() != null && shopOrder.getCouponId() > 0) {
markCouponAsUsed(shopOrder.getCouponId(), shopOrder.getOrderId());
}
// 8. 创建微信支付订单
try {
return shopOrderService.createWxOrder(shopOrder);
} catch (Exception e) {
@ -277,32 +282,87 @@ public class OrderBusinessService {
shopOrder.setPayType(1); // 默认微信支付
}
// 优惠券
// 优惠券处理
if (shopOrder.getCouponId() != null && shopOrder.getCouponId() > 0) {
ShopUserCoupon coupon = shopUserCouponService.getById(shopOrder.getCouponId());
if (coupon != null) {
BigDecimal reducePrice = BigDecimal.ZERO;
boolean doReduce = true;
if (coupon.getType().equals(10)) {
reducePrice = coupon.getReducePrice();
if (shopOrder.getTotalPrice().compareTo(coupon.getMinPrice()) < 0) doReduce = false;
} else if (coupon.getType().equals(20)) {
reducePrice = shopOrder.getTotalPrice()
.multiply(BigDecimal.valueOf(coupon.getDiscount()).divide(new BigDecimal(100), RoundingMode.HALF_UP));
} else if (coupon.getType().equals(30)) {
reducePrice = shopOrder.getTotalPrice();
}
if (doReduce) {
shopOrder.setReducePrice(shopOrder.getReducePrice().add(reducePrice));
shopOrder.setPayPrice(shopOrder.getPayPrice().subtract(reducePrice));
}
// todo 商品/分类限制
}
processCoupon(shopOrder, loginUser);
}
return shopOrder;
}
/**
* 处理优惠券
*/
private void processCoupon(ShopOrder shopOrder, User loginUser) {
ShopUserCoupon coupon = shopUserCouponService.getById(shopOrder.getCouponId());
if (coupon == null) {
throw new BusinessException("优惠券不存在");
}
// 验证优惠券是否属于当前用户
if (!coupon.getUserId().equals(loginUser.getUserId())) {
throw new BusinessException("优惠券不属于当前用户");
}
// 验证优惠券是否已使用
if (coupon.getIsUse() != null && coupon.getIsUse().equals(1)) {
throw new BusinessException("优惠券已使用");
}
// 验证优惠券是否过期
if (coupon.getIsExpire() != null && coupon.getIsExpire().equals(1)) {
throw new BusinessException("优惠券已过期");
}
// 计算优惠金额
BigDecimal reducePrice = BigDecimal.ZERO;
boolean canUse = true;
if (coupon.getType().equals(10)) {
// 满减券
reducePrice = coupon.getReducePrice() != null ? coupon.getReducePrice() : BigDecimal.ZERO;
BigDecimal minPrice = coupon.getMinPrice() != null ? coupon.getMinPrice() : BigDecimal.ZERO;
if (shopOrder.getTotalPrice().compareTo(minPrice) < 0) {
canUse = false;
throw new BusinessException("订单金额不满足优惠券使用条件,最低消费:" + minPrice + "元");
}
} else if (coupon.getType().equals(20)) {
// 折扣券 - 计算减免金额(不是折扣后金额)
Integer discount = coupon.getDiscount() != null ? coupon.getDiscount() : 100;
if (discount < 0 || discount > 100) {
throw new BusinessException("优惠券折扣率异常");
}
// 减免金额 = 原价 * (100 - 折扣率) / 100
reducePrice = shopOrder.getTotalPrice()
.multiply(new BigDecimal(100 - discount))
.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
} else if (coupon.getType().equals(30)) {
// 免费券
reducePrice = shopOrder.getTotalPrice();
} else {
throw new BusinessException("不支持的优惠券类型");
}
if (canUse && reducePrice.compareTo(BigDecimal.ZERO) > 0) {
// 确保减免金额不超过订单总额
if (reducePrice.compareTo(shopOrder.getTotalPrice()) > 0) {
reducePrice = shopOrder.getTotalPrice();
}
// 应用优惠
shopOrder.setReducePrice(shopOrder.getReducePrice().add(reducePrice));
shopOrder.setPayPrice(shopOrder.getPayPrice().subtract(reducePrice));
// 确保实付金额不为负数
if (shopOrder.getPayPrice().compareTo(BigDecimal.ZERO) < 0) {
shopOrder.setPayPrice(BigDecimal.ZERO);
}
log.info("应用优惠券成功 - 优惠券ID:{},类型:{},减免金额:{},实付金额:{}",
coupon.getId(), coupon.getType(), reducePrice, shopOrder.getPayPrice());
}
}
/**
* 处理收货地址信息
* 优先级前端传入地址 > 指定地址ID > 用户默认地址
@ -588,6 +648,24 @@ public class OrderBusinessService {
log.info("库存扣减完成");
}
/**
* 标记优惠券为已使用
*/
private void markCouponAsUsed(Integer couponId, Integer orderId) {
try {
ShopUserCoupon coupon = shopUserCouponService.getById(couponId);
if (coupon != null) {
// 使用实体类提供的方法标记为已使用
coupon.markAsUsed(orderId, null); // orderNo 在这里可以为null,因为已经有orderId了
shopUserCouponService.updateById(coupon);
log.info("优惠券标记为已使用 - 优惠券ID:{},订单ID:{}", couponId, orderId);
}
} catch (Exception e) {
log.error("标记优惠券为已使用失败 - 优惠券ID:{},订单ID:{}", couponId, orderId, e);
// 不抛出异常,避免影响订单创建流程
}
}
/**
* 检查是否为测试账号11
*/

Loading…
Cancel
Save