|
@@ -34,70 +34,103 @@ public class CouponDiscountHandle implements DiscountService {
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- @Transactional
|
|
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
public void computeDiscount(ChargeOrder chargeOrder, Account account) {
|
|
public void computeDiscount(ChargeOrder chargeOrder, Account account) {
|
|
|
- int discountAmount = 0;
|
|
|
|
|
|
|
+ // 获取订单优惠券
|
|
|
|
|
+ var orderCoupon = orderCouponService.lambdaQuery()
|
|
|
|
|
+ .eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
|
|
+ .eq(OrderCoupon::getUserId, chargeOrder.getUserId())
|
|
|
|
|
+ .one();
|
|
|
|
|
+ if (orderCoupon == null) {
|
|
|
|
|
+ log.error("订单{}未绑定优惠券,跳过优惠处理", chargeOrder.getStartChargeSeq());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- // 获取订单优惠券
|
|
|
|
|
- var orderCoupon = orderCouponService.lambdaQuery()
|
|
|
|
|
|
|
+ // 查询用户优惠券信息(仅有效且未使用的券,防止一券多用)
|
|
|
|
|
+ var userCoupon = userCouponService.lambdaQuery()
|
|
|
|
|
+ .eq(UserCoupon::getId, orderCoupon.getUserCouponId())
|
|
|
|
|
+ .eq(UserCoupon::getUserId, chargeOrder.getUserId())
|
|
|
|
|
+ .eq(UserCoupon::getStatus, UserCoupon.STATUS_有效)
|
|
|
|
|
+ .eq(UserCoupon::getUsageStatus, UserCoupon.USAGE_STATUS_未使用)
|
|
|
|
|
+ .one();
|
|
|
|
|
+ if (userCoupon == null) {
|
|
|
|
|
+ // 券不存在或已使用/失效,标记订单优惠券使用失败
|
|
|
|
|
+ orderCouponService.lambdaUpdate()
|
|
|
|
|
+ .set(OrderCoupon::getStatus, OrderCoupon.STATUS_使用失败)
|
|
|
.eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
.eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
- .eq(OrderCoupon::getUserId, chargeOrder.getUserId())
|
|
|
|
|
- .one();
|
|
|
|
|
-
|
|
|
|
|
- // 查询用户优惠券信息
|
|
|
|
|
- var userCoupon = userCouponService.lambdaQuery()
|
|
|
|
|
- .eq(UserCoupon::getId, orderCoupon.getUserCouponId())
|
|
|
|
|
- .eq(UserCoupon::getUserId, chargeOrder.getUserId())
|
|
|
|
|
- .one();
|
|
|
|
|
-
|
|
|
|
|
- // 检查是否达到使用门槛
|
|
|
|
|
- if (chargeOrder.getServiceMoney() >= userCoupon.getMinServiceMoney()) {
|
|
|
|
|
- // 根据优惠券类型处理
|
|
|
|
|
- switch (userCoupon.getCouponType()) {
|
|
|
|
|
- case Coupon.COUPON_TYPE_满减券:
|
|
|
|
|
- discountAmount = userCoupon.getDiscount();
|
|
|
|
|
- break;
|
|
|
|
|
- case Coupon.COUPON_TYPE_折扣券:
|
|
|
|
|
- discountAmount = chargeOrder.getServiceMoney() * (100 - userCoupon.getDiscount()) / 100;
|
|
|
|
|
- break;
|
|
|
|
|
- default:
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .eq(OrderCoupon::getUserCouponId, orderCoupon.getUserCouponId())
|
|
|
|
|
+ .update();
|
|
|
|
|
+ log.error("订单使用优惠券失败:订单号:{},用户优惠券{}不存在或已使用/失效", chargeOrder.getStartChargeSeq(), orderCoupon.getUserCouponId());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 订单金额、优惠金额更新
|
|
|
|
|
- chargeOrder.setDiscountAmount(discountAmount);
|
|
|
|
|
- chargeOrder.setServiceMoneyDiscount(discountAmount);
|
|
|
|
|
- chargeOrder.setPayAmount(chargeOrder.getTotalMoney() - discountAmount);
|
|
|
|
|
|
|
+ // 检查是否达到使用门槛
|
|
|
|
|
+ if (chargeOrder.getServiceMoney() >= userCoupon.getMinServiceMoney()) {
|
|
|
|
|
+ // 根据优惠券类型处理
|
|
|
|
|
+ int discountAmount;
|
|
|
|
|
+ switch (userCoupon.getCouponType()) {
|
|
|
|
|
+ case Coupon.COUPON_TYPE_满减券:
|
|
|
|
|
+ // 满减金额不能超过服务费金额,防止payAmount为负
|
|
|
|
|
+ discountAmount = Math.min(userCoupon.getDiscount(), chargeOrder.getServiceMoney());
|
|
|
|
|
+ break;
|
|
|
|
|
+ case Coupon.COUPON_TYPE_折扣券:
|
|
|
|
|
+ discountAmount = Math.min(chargeOrder.getServiceMoney() * (100 - userCoupon.getDiscount()) / 100, chargeOrder.getServiceMoney());
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ // 未知的优惠券类型,标记使用失败
|
|
|
|
|
+ orderCouponService.lambdaUpdate()
|
|
|
|
|
+ .set(OrderCoupon::getStatus, OrderCoupon.STATUS_使用失败)
|
|
|
|
|
+ .eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
|
|
+ .eq(OrderCoupon::getUserCouponId, userCoupon.getId())
|
|
|
|
|
+ .update();
|
|
|
|
|
+ log.error("订单使用优惠券失败:订单号:{},优惠券id{}:未知优惠券类型{}", chargeOrder.getStartChargeSeq(), userCoupon.getCouponId(), userCoupon.getCouponType());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 更新用户优惠券信息
|
|
|
|
|
- userCouponService.lambdaUpdate()
|
|
|
|
|
- .set(UserCoupon::getStatus, UserCoupon.STATUS_无效)
|
|
|
|
|
- .set(UserCoupon::getUsageStatus, UserCoupon.USAGE_STATUS_已使用)
|
|
|
|
|
- .eq(UserCoupon::getId, userCoupon.getId())
|
|
|
|
|
- .update();
|
|
|
|
|
|
|
+ // 订单金额、优惠金额更新
|
|
|
|
|
+ chargeOrder.setDiscountAmount(discountAmount);
|
|
|
|
|
+ chargeOrder.setServiceMoneyDiscount(discountAmount);
|
|
|
|
|
+ chargeOrder.setPayAmount(Math.max(0, chargeOrder.getTotalMoney() - discountAmount));
|
|
|
|
|
|
|
|
- // 更新订单优惠券关联信息
|
|
|
|
|
- orderCouponService.lambdaUpdate()
|
|
|
|
|
- .set(OrderCoupon::getDiscountAmount, discountAmount)
|
|
|
|
|
- .set(OrderCoupon::getStatus, OrderCoupon.STATUS_使用成功)
|
|
|
|
|
- .eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
|
|
- .eq(OrderCoupon::getUserCouponId, userCoupon.getId())
|
|
|
|
|
- .update();
|
|
|
|
|
-
|
|
|
|
|
- // 优惠券使用情况数据
|
|
|
|
|
- couponService.usedQuantifyCount(userCoupon.getCouponId());
|
|
|
|
|
- } else {
|
|
|
|
|
|
|
+ // 条件核销优惠券:仅未使用状态可核销,防止并发一券多用
|
|
|
|
|
+ var redeemed = userCouponService.lambdaUpdate()
|
|
|
|
|
+ .set(UserCoupon::getStatus, UserCoupon.STATUS_无效)
|
|
|
|
|
+ .set(UserCoupon::getUsageStatus, UserCoupon.USAGE_STATUS_已使用)
|
|
|
|
|
+ .eq(UserCoupon::getId, userCoupon.getId())
|
|
|
|
|
+ .eq(UserCoupon::getUsageStatus, UserCoupon.USAGE_STATUS_未使用)
|
|
|
|
|
+ .update();
|
|
|
|
|
+ if (!redeemed) {
|
|
|
|
|
+ // 核销失败(已被并发使用),优惠回退为0并标记订单优惠券使用失败
|
|
|
|
|
+ chargeOrder.setDiscountAmount(0);
|
|
|
|
|
+ chargeOrder.setServiceMoneyDiscount(0);
|
|
|
|
|
+ chargeOrder.setPayAmount(chargeOrder.getTotalMoney());
|
|
|
orderCouponService.lambdaUpdate()
|
|
orderCouponService.lambdaUpdate()
|
|
|
|
|
+ .set(OrderCoupon::getDiscountAmount, 0)
|
|
|
.set(OrderCoupon::getStatus, OrderCoupon.STATUS_使用失败)
|
|
.set(OrderCoupon::getStatus, OrderCoupon.STATUS_使用失败)
|
|
|
.eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
.eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
.eq(OrderCoupon::getUserCouponId, userCoupon.getId())
|
|
.eq(OrderCoupon::getUserCouponId, userCoupon.getId())
|
|
|
.update();
|
|
.update();
|
|
|
- log.error("订单使用优惠券失败:订单号:{},优惠券id{}:服务费未达到优惠券使用门槛", chargeOrder.getStartChargeSeq(), userCoupon.getCouponId());
|
|
|
|
|
|
|
+ log.error("订单使用优惠券失败:订单号:{},优惠券id{}:核销时券已被使用", chargeOrder.getStartChargeSeq(), userCoupon.getCouponId());
|
|
|
|
|
+ return;
|
|
|
}
|
|
}
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- log.error("处理优惠券失败", e);
|
|
|
|
|
- // 可以添加一些错误处理逻辑,比如重试机制、发送告警等
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 更新订单优惠券关联信息
|
|
|
|
|
+ orderCouponService.lambdaUpdate()
|
|
|
|
|
+ .set(OrderCoupon::getDiscountAmount, discountAmount)
|
|
|
|
|
+ .set(OrderCoupon::getStatus, OrderCoupon.STATUS_使用成功)
|
|
|
|
|
+ .eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
|
|
+ .eq(OrderCoupon::getUserCouponId, userCoupon.getId())
|
|
|
|
|
+ .update();
|
|
|
|
|
+
|
|
|
|
|
+ // 优惠券使用情况数据
|
|
|
|
|
+ couponService.usedQuantifyCount(userCoupon.getCouponId());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ orderCouponService.lambdaUpdate()
|
|
|
|
|
+ .set(OrderCoupon::getStatus, OrderCoupon.STATUS_使用失败)
|
|
|
|
|
+ .eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
|
|
|
|
|
+ .eq(OrderCoupon::getUserCouponId, userCoupon.getId())
|
|
|
|
|
+ .update();
|
|
|
|
|
+ log.error("订单使用优惠券失败:订单号:{},优惠券id{}:服务费未达到优惠券使用门槛", chargeOrder.getStartChargeSeq(), userCoupon.getCouponId());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|