skyline před 2 roky
rodič
revize
119d0422d2

+ 26 - 0
entity/src/main/java/com/kym/entity/miniapp/other/DiscountCompute.java

@@ -0,0 +1,26 @@
+package com.kym.entity.miniapp.other;
+
+import com.kym.entity.miniapp.Account;
+import com.kym.entity.miniapp.ChargeOrder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 优惠计算介质
+ *
+ * @author skyline
+ */
+@Data
+public class DiscountCompute {
+    public ChargeOrder chargeOrder;
+    public Account account;
+    public LocalDateTime endTime;
+    public int discountAmount;
+
+    public DiscountCompute(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
+        this.chargeOrder = chargeOrder;
+        this.account = account;
+        this.endTime = endTime;
+    }
+}

+ 31 - 187
service/src/main/java/com/kym/service/enplus/impl/EnNotifyServiceImpl.java

@@ -7,28 +7,34 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.kym.common.cache.ConnectorStatusCache;
 import com.kym.common.config.RedisDBChangeUtil;
 import com.kym.entity.admin.ConnectorInfo;
-import com.kym.entity.admin.Coupon;
 import com.kym.entity.admin.EquipmentInfo;
 import com.kym.entity.admin.MonitorLog;
 import com.kym.entity.common.RedisKeys;
 import com.kym.entity.enplus.EnConnectorStatusInfo;
-import com.kym.entity.miniapp.*;
+import com.kym.entity.miniapp.Account;
+import com.kym.entity.miniapp.ChargeOrder;
+import com.kym.entity.miniapp.WalletDetail;
+import com.kym.entity.miniapp.other.DiscountCompute;
 import com.kym.service.admin.ConnectorInfoService;
 import com.kym.service.admin.EquipmentInfoService;
 import com.kym.service.admin.MonitorLogService;
 import com.kym.service.cache.KymCache;
 import com.kym.service.enplus.EnNotifyService;
 import com.kym.service.enplus.EnPlusService;
-import com.kym.service.miniapp.*;
+import com.kym.service.factory.DiscountStrategyFactory;
+import com.kym.service.miniapp.AccountService;
+import com.kym.service.miniapp.ChargeOrderService;
+import com.kym.service.miniapp.ChargeService;
+import com.kym.service.miniapp.WalletDetailService;
 import jakarta.annotation.PostConstruct;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.stream.Collectors;
@@ -59,15 +65,8 @@ public class EnNotifyServiceImpl implements EnNotifyService {
 
     private final ConnectorInfoService connectorInfoService;
 
-    private final UserRechargeRightsService userRechargeRightsService;
 
-    private final OrderRechargeRightsService orderRechargeRightsService;
-
-    private final OrderCouponService orderCouponService;
-
-    private final UserCouponService userCouponService;
-
-    private final RedisDBChangeUtil redisDBChangeUtil;
+    public final StringRedisTemplate redisTemplate;
 
     @Value("${kym.notify-email}")
     private String notifyEmail;
@@ -75,7 +74,7 @@ public class EnNotifyServiceImpl implements EnNotifyService {
     public EnNotifyServiceImpl(EnPlusService enPlusService, ChargeOrderService chargeOrderService,
                                ChargeService chargeService, AccountService accountService, WalletDetailService walletDetailService,
                                MonitorLogService monitorLogService, EquipmentInfoService equipmentInfoService,
-                               ConnectorInfoService connectorInfoService, UserRechargeRightsService userRechargeRightsService, OrderRechargeRightsService orderRechargeRightsService, OrderCouponService orderCouponService, UserCouponService userCouponService, RedisDBChangeUtil redisDBChangeUtil) {
+                               ConnectorInfoService connectorInfoService, StringRedisTemplate redisTemplate) {
         this.enPlusService = enPlusService;
         this.chargeOrderService = chargeOrderService;
         this.chargeService = chargeService;
@@ -84,11 +83,7 @@ public class EnNotifyServiceImpl implements EnNotifyService {
         this.monitorLogService = monitorLogService;
         this.equipmentInfoService = equipmentInfoService;
         this.connectorInfoService = connectorInfoService;
-        this.userRechargeRightsService = userRechargeRightsService;
-        this.orderRechargeRightsService = orderRechargeRightsService;
-        this.orderCouponService = orderCouponService;
-        this.userCouponService = userCouponService;
-        this.redisDBChangeUtil = redisDBChangeUtil;
+        this.redisTemplate = redisTemplate;
     }
 
     @PostConstruct
@@ -122,8 +117,6 @@ public class EnNotifyServiceImpl implements EnNotifyService {
                 .set(ConnectorInfo::getStatus, connectorStatusInfo.getStatus())
                 .update();
 
-        // 切换到admin对应的db
-        redisDBChangeUtil.setDataBase(0);
 
         var connectorStatus = connectorStatusInfo.getStatus();
 
@@ -139,11 +132,11 @@ public class EnNotifyServiceImpl implements EnNotifyService {
             monitorLogService.save(monitorLog);
 
             // 离线设备放入队列,5分钟之后如果还未恢复则放入长时间离线设备集合中并发送提醒,上线后发送提醒
-            redisDBChangeUtil.redisTemplate.opsForZSet().add(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId(), System.currentTimeMillis() + 5 * 60 * 1000);
+            redisTemplate.opsForZSet().add(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId(), System.currentTimeMillis() + 5 * 60 * 1000);
         } else {
             // 先删除离线设备队列的记录,再删除离线超时队列中的记录
-            var isDelete = redisDBChangeUtil.redisTemplate.opsForZSet().remove(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId());
-            var exist = redisDBChangeUtil.redisTemplate.opsForSet().remove(RedisKeys.OFFLINE_EXPIRED, connectorStatusInfo.getConnectorId());
+            var isDelete = redisTemplate.opsForZSet().remove(RedisKeys.OFFLINE, connectorStatusInfo.getConnectorId());
+            var exist = redisTemplate.opsForSet().remove(RedisKeys.OFFLINE_EXPIRED, connectorStatusInfo.getConnectorId());
             if ((isDelete != null && isDelete > 0) || (exist != null && exist > 0)) {
                 // 更新设备监控表
                 monitorLogService.lambdaUpdate()
@@ -304,13 +297,16 @@ public class EnNotifyServiceImpl implements EnNotifyService {
             // 结束时间
             var endTime = LocalDateTime.parse(data.getString("EndTime"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
 
-            // todo 判断适用哪种优惠
+            // 处理充值权益优惠逻辑/优惠券优惠逻辑
+            // 优惠金额
+            var discountCompute = DiscountStrategyFactory.getDiscountStrategy(chargeOrder.getDiscountType()).computeDiscount(new DiscountCompute(chargeOrder, account, endTime));
 
-            // 处理充值权益优惠逻辑
-            handleRechargeRights(chargeOrder, account, endTime);
+            // 更新订单优惠金额
+            updateOrderDiscount(chargeOrder, discountCompute);
+
+            // 扣费等资金操作
+            deductions(discountCompute.chargeOrder, discountCompute.account, endTime);
 
-            // 处理优惠券优惠逻辑
-            handleCoupon(chargeOrder, account, endTime);
         }
         return """
                 {
@@ -321,179 +317,27 @@ public class EnNotifyServiceImpl implements EnNotifyService {
                 """.formatted(startChargeSeq, chargeOrder.getConnectorId(), 0);
     }
 
-    private void handleCoupon(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
-        try {
-            if (chargeOrder.getServiceMoney() <= 0) {
-                LOGGER.info("订单:{} 服务费不合法", chargeOrder.getStartChargeSeq());
-                return; // 服务费不合法,直接返回
-            }
-
-            // 获取订单优惠券
-            var orderCoupon = orderCouponService.lambdaQuery()
-                    .eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
-                    .eq(OrderCoupon::getUserId, chargeOrder.getUserId())
-                    .one();
-            if (orderCoupon == null) {
-                return; // 没有优惠券,直接返回
-            }
-
-            // 查询用户优惠券信息
-            var userCoupon = userCouponService.lambdaQuery()
-                    .eq(UserCoupon::getId, orderCoupon.getCouponId()) // 假设COUPON_ID是通用的,否则需要根据类型查询不同的字段
-                    .eq(UserCoupon::getUserId, chargeOrder.getUserId())
-                    .one();
-            if (userCoupon == null) {
-                return; // 没有找到用户优惠券,直接返回
-            }
-
-            // 检查是否达到使用门槛
-            if (chargeOrder.getServiceMoney() < userCoupon.getMinServiceMoney()) {
-                LOGGER.info("订单:{}优惠券{}使用失败:服务费未达到优惠券使用门槛", chargeOrder.getStartChargeSeq(), userCoupon.getCouponId());
-                return;
-            }
-
-            // 根据优惠券类型处理
-            processCouponDiscount(chargeOrder, userCoupon, orderCoupon.getCouponType());
-
-            // 执行账户扣费等操作
-            deductions(chargeOrder, account, endTime);
-        } catch (Exception e) {
-            LOGGER.error("处理优惠券失败", e);
-            // 可以添加一些错误处理逻辑,比如重试机制、发送告警等
-        }
-    }
 
     /**
-     * 处理优惠券优惠逻辑
+     * 更新订单优惠金额
      *
      * @param chargeOrder
-     * @param userCoupon
-     * @param couponType
+     * @param discountCompute
      */
-    private void processCouponDiscount(ChargeOrder chargeOrder, UserCoupon userCoupon, String couponType) {
-        int discountAmount;
-        switch (couponType) {
-            case Coupon.COUPON_TYPE_折扣券:
-                discountAmount = chargeOrder.getServiceMoney() * (100 - userCoupon.getDiscount()) / 100;
-                updateOrderAndCoupon(chargeOrder, userCoupon, discountAmount);
-                break;
-            case Coupon.COUPON_TYPE_满减券:
-                discountAmount = chargeOrder.getServiceMoney() - userCoupon.getDiscount();
-                updateOrderAndCoupon(chargeOrder, userCoupon, discountAmount);
-                break;
-        }
-    }
-
-    /**
-     * 更新订单和优惠券信息
-     *
-     * @param chargeOrder
-     * @param userCoupon
-     * @param discountAmount
-     */
-    private void updateOrderAndCoupon(ChargeOrder chargeOrder, UserCoupon userCoupon, int discountAmount) {
-        chargeOrder.setDiscountAmount(discountAmount);
-        chargeOrder.setServiceMoneyDiscount(discountAmount);
+    void updateOrderDiscount(ChargeOrder chargeOrder, DiscountCompute discountCompute) {
+        chargeOrder.setDiscountAmount(discountCompute.discountAmount);
+        chargeOrder.setServiceMoneyDiscount(discountCompute.discountAmount);
         chargeOrderService.updateById(chargeOrder);
-        userCoupon.setDiscount(discountAmount);
-        userCouponService.updateById(userCoupon);
-    }
-
-
-    /**
-     * 处理订单权益
-     *
-     * @param chargeOrder
-     * @param account
-     * @param endTime
-     */
-    private void handleRechargeRights(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
-        // 获取订单权益,计算订单优惠金额,实付金额,服务费优惠金额
-        var orderRechargeRights = orderRechargeRightsService.lambdaQuery()
-                .eq(OrderRechargeRights::getStartChargeSeq, chargeOrder.getStartChargeSeq())
-                .eq(OrderRechargeRights::getUserId, chargeOrder.getUserId())
-                .one();
-        if (orderRechargeRights != null) {
-            // 获取折扣,计算优惠
-            var discount = orderRechargeRights.getDiscount();
-            // 服务费优惠金额只保留到分,分以下不进行四舍五入
-            var serviceMoneyDiscount = (int) (chargeOrder.getServiceMoney() * (BigDecimal.valueOf(1).subtract(BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100)))).doubleValue());
-            chargeOrder
-                    .setPayAmount(chargeOrder.getTotalMoney() - serviceMoneyDiscount)
-                    .setDiscountAmount(serviceMoneyDiscount)
-                    .setServiceMoneyDiscount(serviceMoneyDiscount);
-
-            orderRechargeRights.setDiscountAmount(serviceMoneyDiscount);
-
-            // 用户充值权益
-            var userRechargeRights = userRechargeRightsService.lambdaQuery()
-                    .eq(UserRechargeRights::getId, orderRechargeRights.getUserRightsId())
-                    .eq(UserRechargeRights::getUserId, chargeOrder.getUserId())
-                    .eq(UserRechargeRights::getRightsId, orderRechargeRights.getRightsId())
-                    .one();
-
-            // 用户当前权益金余额是否足够支付本次充电费用
-            if (userRechargeRights.getStatus() == UserRechargeRights.STATUS_有效) {
-                if (chargeOrder.getPayAmount() <= userRechargeRights.getRightsBalance()) {
-                    userRechargeRights
-                            // 用户权益包余额扣减当前订单实付金额
-                            .setRightsBalance(userRechargeRights.getRightsBalance() - chargeOrder.getPayAmount())
-                            .setDiscountAmount(userRechargeRights.getDiscountAmount() + serviceMoneyDiscount);
-
-                    // 账户设置优惠不可退金额
-                    account.setDiscountAmount(account.getDiscountAmount() + serviceMoneyDiscount);
-                    if (chargeOrder.getPayAmount().intValue() == userRechargeRights.getRightsBalance().intValue()) {
-                        userRechargeRights.setStatus(UserRechargeRights.STATUS_无效);
-                    }
-                } else {
-                    // 不足(用户当前权益金余额是否足够支付本次充电费用)
-                    // 如果优惠后的实付金额大于权益金余额,那么实际优惠金额需要通过权益金余额反推
-                    // 通过权益金余额,反推最多扣减多少服务费
-                    // rightBalance = elecMoney + serviceMoney * (1-discount)
-                    // 订单中elecMoney与serviceMoney的比值是一定的
-                    var ratio = BigDecimal.valueOf(chargeOrder.getElecMoney()).divide(BigDecimal.valueOf(chargeOrder.getServiceMoney()), 2, RoundingMode.HALF_UP);
-                    // (ratio * realServiceMoney) + (realServiceMoney * (100 - discount)/100) = rightBalance
-                    var discountRate = BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
-                    var userRightBalance = BigDecimal.valueOf(userRechargeRights.getRightsBalance());
-                    // 真实可以覆盖的服务费金额
-                    var realServiceMoney = userRightBalance.divide(ratio.add(BigDecimal.valueOf(1)).subtract(discountRate), 2, RoundingMode.HALF_UP);
-                    // 实际优惠金额 = 实际可以覆盖的服务费金额 * 折扣率
-                    var realDiscountAmount = realServiceMoney.multiply(BigDecimal.valueOf(1).subtract(discountRate)).intValue();
-                    chargeOrder
-                            // 实付金额
-                            .setPayAmount(chargeOrder.getTotalMoney() - realDiscountAmount)
-                            .setDiscountAmount(realDiscountAmount)
-                            .setServiceMoneyDiscount(realDiscountAmount);
-                    // 余额扣完,总优惠金额加上最后一次真实优惠金额,此条用户权益结束,状态设置为无效
-                    userRechargeRights
-                            .setRightsBalance(0)
-                            .setDiscountAmount(userRechargeRights.getDiscountAmount() + realDiscountAmount)
-                            .setStatus(UserRechargeRights.STATUS_无效);
-
-                    orderRechargeRights.setDiscountAmount(realDiscountAmount);
-                    // 此权益包消耗完毕,账户设置优惠不可退金额
-                    account.setDiscountAmount(account.getDiscountAmount() + realDiscountAmount);
-                }
-            }
-
-            // 更新订单权益的最终优惠金额
-            orderRechargeRightsService.updateById(orderRechargeRights);
-            // 更新用户权益金等
-            userRechargeRightsService.updateById(userRechargeRights);
-
-            // 执行账户扣费等操作
-            deductions(chargeOrder, account, endTime);
-        }
     }
 
     /**
-     * 账户扣费等操作
+     * 扣费等资金操作
      *
      * @param chargeOrder
      * @param account
      * @param endTime
      */
-    private void deductions(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
+    void deductions(ChargeOrder chargeOrder, Account account, LocalDateTime endTime) {
         // 订单成功
         chargeOrder.setOrderStatus(ChargeOrder.ORDER_STATUS_成功);
         // 充电结束

+ 26 - 0
service/src/main/java/com/kym/service/factory/DiscountStrategyFactory.java

@@ -0,0 +1,26 @@
+package com.kym.service.factory;
+
+import com.kym.common.exception.BusinessException;
+import com.kym.entity.admin.Activity;
+import com.kym.service.miniapp.DiscountService;
+import com.kym.service.miniapp.impl.CouponDiscountHandle;
+import com.kym.service.miniapp.impl.RechargeRightsDiscountHandle;
+import org.springframework.stereotype.Component;
+
+/**
+ * 优惠策略工厂
+ *
+ * @author skyline
+ */
+@Component
+public class DiscountStrategyFactory {
+    public static DiscountService getDiscountStrategy(String discountType) {
+        if (Activity.DISCOUNT_TYPE_优惠券.equals(discountType)) {
+            return new CouponDiscountHandle();
+        } else if (Activity.DISCOUNT_TYPE_服务费折扣权益.equals(discountType)) {
+            return new RechargeRightsDiscountHandle();
+        } else {
+            throw new BusinessException("未配置相关策略");
+        }
+    }
+}

+ 7 - 0
service/src/main/java/com/kym/service/miniapp/DiscountService.java

@@ -0,0 +1,7 @@
+package com.kym.service.miniapp;
+
+import com.kym.entity.miniapp.other.DiscountCompute;
+
+public interface DiscountService {
+    DiscountCompute computeDiscount(DiscountCompute discountCompute);
+}

+ 75 - 0
service/src/main/java/com/kym/service/miniapp/impl/CouponDiscountHandle.java

@@ -0,0 +1,75 @@
+package com.kym.service.miniapp.impl;
+
+import com.kym.entity.admin.Coupon;
+import com.kym.entity.miniapp.OrderCoupon;
+import com.kym.entity.miniapp.UserCoupon;
+import com.kym.entity.miniapp.other.DiscountCompute;
+import com.kym.service.miniapp.DiscountService;
+import com.kym.service.miniapp.OrderCouponService;
+import com.kym.service.miniapp.UserCouponService;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 优惠券计算
+ *
+ * @author skyline
+ */
+@Service
+@Slf4j
+public class CouponDiscountHandle implements DiscountService {
+    @Resource
+    private OrderCouponService orderCouponService;
+    @Resource
+    private UserCouponService userCouponService;
+
+
+    @Override
+    public DiscountCompute computeDiscount(DiscountCompute discountCompute) {
+        var chargeOrder = discountCompute.chargeOrder;
+        int discountAmount = discountCompute.discountAmount;
+
+        try {
+            // 获取订单优惠券
+            var orderCoupon = orderCouponService.lambdaQuery()
+                    .eq(OrderCoupon::getStartChargeSeq, chargeOrder.getStartChargeSeq())
+                    .eq(OrderCoupon::getUserId, chargeOrder.getUserId())
+                    .one();
+
+            // 查询用户优惠券信息
+            var userCoupon = userCouponService.lambdaQuery()
+                    .eq(UserCoupon::getId, orderCoupon.getCouponId())
+                    .eq(UserCoupon::getUserId, chargeOrder.getUserId())
+                    .one();
+
+            // 检查是否达到使用门槛
+            if (chargeOrder.getServiceMoney() < userCoupon.getMinServiceMoney()) {
+                log.info("订单:{}优惠券{}使用失败:服务费未达到优惠券使用门槛", chargeOrder.getStartChargeSeq(), userCoupon.getCouponId());
+            }
+
+            // 根据优惠券类型处理
+            switch (userCoupon.getCouponType()) {
+                case Coupon.COUPON_TYPE_满减券:
+                    discountAmount = chargeOrder.getServiceMoney() - userCoupon.getDiscount();
+                    break;
+                case Coupon.COUPON_TYPE_折扣券:
+                    discountAmount = chargeOrder.getServiceMoney() * (100 - userCoupon.getDiscount());
+                    break;
+                default:
+                    // 其他类型券
+                    break;
+            }
+            // 更新用户优惠券信息
+            userCoupon.setDiscount(discountAmount);
+            userCouponService.updateById(userCoupon);
+        } catch (Exception e) {
+            log.error("处理优惠券失败", e);
+            // 可以添加一些错误处理逻辑,比如重试机制、发送告警等
+        }
+
+        return discountCompute;
+    }
+
+
+}

+ 124 - 0
service/src/main/java/com/kym/service/miniapp/impl/RechargeRightsDiscountHandle.java

@@ -0,0 +1,124 @@
+package com.kym.service.miniapp.impl;
+
+import com.kym.entity.miniapp.OrderRechargeRights;
+import com.kym.entity.miniapp.UserRechargeRights;
+import com.kym.entity.miniapp.other.DiscountCompute;
+import com.kym.service.miniapp.DiscountService;
+import com.kym.service.miniapp.OrderRechargeRightsService;
+import com.kym.service.miniapp.UserRechargeRightsService;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * 充值优惠计算
+ *
+ * @author skyline
+ */
+@Service
+@Slf4j
+public class RechargeRightsDiscountHandle implements DiscountService {
+
+
+    @Resource
+    private OrderRechargeRightsService orderRechargeRightsService;
+    @Resource
+    private UserRechargeRightsService userRechargeRightsService;
+
+    @Override
+    public DiscountCompute computeDiscount(DiscountCompute discountCompute) {
+        var chargeOrder = discountCompute.chargeOrder;
+        var account = discountCompute.account;
+        int discountAmount = discountCompute.discountAmount;
+
+        try {
+            // 获取订单权益,计算订单优惠金额,实付金额,服务费优惠金额
+            var orderRechargeRights = orderRechargeRightsService.lambdaQuery()
+                    .eq(OrderRechargeRights::getStartChargeSeq, chargeOrder.getStartChargeSeq())
+                    .eq(OrderRechargeRights::getUserId, chargeOrder.getUserId())
+                    .one();
+            if (orderRechargeRights != null) {
+                // 获取折扣,计算优惠
+                var discount = orderRechargeRights.getDiscount();
+                // 服务费优惠金额只保留到分,分以下不进行四舍五入
+                var serviceMoneyDiscount = (int) (chargeOrder.getServiceMoney() * (BigDecimal.valueOf(1).subtract(BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100)))).doubleValue());
+                chargeOrder
+                        .setPayAmount(chargeOrder.getTotalMoney() - serviceMoneyDiscount)
+                        .setDiscountAmount(serviceMoneyDiscount)
+                        .setServiceMoneyDiscount(serviceMoneyDiscount);
+
+                orderRechargeRights.setDiscountAmount(serviceMoneyDiscount);
+
+                // 用户充值权益
+                var userRechargeRights = userRechargeRightsService.lambdaQuery()
+                        .eq(UserRechargeRights::getId, orderRechargeRights.getUserRightsId())
+                        .eq(UserRechargeRights::getUserId, chargeOrder.getUserId())
+                        .eq(UserRechargeRights::getRightsId, orderRechargeRights.getRightsId())
+                        .one();
+
+                // 用户当前权益金余额是否足够支付本次充电费用
+                if (userRechargeRights.getStatus() == UserRechargeRights.STATUS_有效) {
+                    if (chargeOrder.getPayAmount() <= userRechargeRights.getRightsBalance()) {
+                        userRechargeRights
+                                // 用户权益包余额扣减当前订单实付金额
+                                .setRightsBalance(userRechargeRights.getRightsBalance() - chargeOrder.getPayAmount())
+                                .setDiscountAmount(userRechargeRights.getDiscountAmount() + serviceMoneyDiscount);
+
+                        // 账户设置优惠不可退金额
+                        discountAmount = account.getDiscountAmount() + serviceMoneyDiscount;
+                        account.setDiscountAmount(discountAmount);
+                        if (chargeOrder.getPayAmount().intValue() == userRechargeRights.getRightsBalance().intValue()) {
+                            userRechargeRights.setStatus(UserRechargeRights.STATUS_无效);
+                        }
+                    } else {
+                        // 不足(用户当前权益金余额是否足够支付本次充电费用)
+                        // 如果优惠后的实付金额大于权益金余额,那么实际优惠金额需要通过权益金余额反推
+                        // 通过权益金余额,反推最多扣减多少服务费
+                        // rightBalance = elecMoney + serviceMoney * (1-discount)
+                        // 订单中elecMoney与serviceMoney的比值是一定的
+                        var ratio = BigDecimal.valueOf(chargeOrder.getElecMoney()).divide(BigDecimal.valueOf(chargeOrder.getServiceMoney()), 2, RoundingMode.HALF_UP);
+                        // (ratio * realServiceMoney) + (realServiceMoney * (100 - discount)/100) = rightBalance
+                        var discountRate = BigDecimal.valueOf(discount).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
+                        var userRightBalance = BigDecimal.valueOf(userRechargeRights.getRightsBalance());
+                        // 真实可以覆盖的服务费金额
+                        var realServiceMoney = userRightBalance.divide(ratio.add(BigDecimal.valueOf(1)).subtract(discountRate), 2, RoundingMode.HALF_UP);
+                        // 实际优惠金额 = 实际可以覆盖的服务费金额 * 折扣率
+                        var realDiscountAmount = realServiceMoney.multiply(BigDecimal.valueOf(1).subtract(discountRate)).intValue();
+                        chargeOrder
+                                // 实付金额
+                                .setPayAmount(chargeOrder.getTotalMoney() - realDiscountAmount)
+                                .setDiscountAmount(realDiscountAmount)
+                                .setServiceMoneyDiscount(realDiscountAmount);
+                        // 余额扣完,总优惠金额加上最后一次真实优惠金额,此条用户权益结束,状态设置为无效
+                        userRechargeRights
+                                .setRightsBalance(0)
+                                .setDiscountAmount(userRechargeRights.getDiscountAmount() + realDiscountAmount)
+                                .setStatus(UserRechargeRights.STATUS_无效);
+
+                        orderRechargeRights.setDiscountAmount(realDiscountAmount);
+                        // 此权益包消耗完毕,账户设置优惠不可退金额
+                        discountAmount = account.getDiscountAmount() + realDiscountAmount;
+                        account.setDiscountAmount(discountAmount);
+                    }
+                }
+
+                // 更新订单权益的最终优惠金额
+                orderRechargeRightsService.updateById(orderRechargeRights);
+                // 更新用户权益金等
+                userRechargeRightsService.updateById(userRechargeRights);
+            }
+
+
+        } catch (Exception e) {
+            log.error("处理优惠券失败", e);
+            // 可以添加一些错误处理逻辑,比如重试机制、发送告警等
+        }
+
+        return discountCompute;
+    }
+
+
+}