From b8150b021b842ead6388c8af3a6d2cdc28db7f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Fri, 22 Aug 2025 18:38:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(order):=20=E4=BC=98=E5=8C=96=E4=BC=98?= =?UTF-8?q?=E6=83=A0=E5=88=B8=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构优惠券处理流程,提高代码可读性和可维护性 - 增加优惠券有效性验证,包括用户归属、使用状态和有效期 -优化优惠金额计算逻辑,支持满减券、折扣券和免费券 - 新增标记优惠券为已使用功能 - 在订单创建流程中应用优惠券并更新相关金额 --- .../controller/ShopUserAddressController.java | 1 + .../shop/service/OrderBusinessService.java | 120 +++++++++++++++--- 2 files changed, 100 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/gxwebsoft/shop/controller/ShopUserAddressController.java b/src/main/java/com/gxwebsoft/shop/controller/ShopUserAddressController.java index 9eb7444..e2290f9 100644 --- a/src/main/java/com/gxwebsoft/shop/controller/ShopUserAddressController.java +++ b/src/main/java/com/gxwebsoft/shop/controller/ShopUserAddressController.java @@ -44,6 +44,7 @@ @GetMapping() public ApiResult> list(ShopUserAddressParam param) { // 使用关联查询 + param.setUserId(getLoginUser().getUserId()); return success(shopUserAddressService.listRel(param)); } diff --git a/src/main/java/com/gxwebsoft/shop/service/OrderBusinessService.java b/src/main/java/com/gxwebsoft/shop/service/OrderBusinessService.java index 1656582..d79908b 100644 --- a/src/main/java/com/gxwebsoft/shop/service/OrderBusinessService.java +++ b/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 */