liujie
2026-06-05 5b8dc7912678e63a255d771157033c3ed6c5c047
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -9,6 +9,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.api.feignClient.*;
import com.ruoyi.account.api.model.*;
import com.ruoyi.account.api.vo.AppUserWhitelistMatchVO;
import com.ruoyi.account.api.vo.GetAppUserVipDetail;
import com.ruoyi.account.api.vo.GetInviteUser;
import com.ruoyi.chargingPile.api.dto.GetSiteListDTO;
@@ -18,6 +19,7 @@
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.dto.ChargingOrderGroup;
import com.ruoyi.common.core.dto.ChargingPercentProvinceDto;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.domain.BasePojo;
import com.ruoyi.common.core.web.page.PageInfo;
@@ -69,9 +71,7 @@
import com.ruoyi.payment.api.feignClient.AliPaymentClient;
import com.ruoyi.payment.api.feignClient.H5AliPaymentClient;
import com.ruoyi.payment.api.feignClient.WxPaymentClient;
import com.ruoyi.payment.api.model.RefundReq;
import com.ruoyi.payment.api.model.RefundResp;
import com.ruoyi.payment.api.model.WxPaymentRefundModel;
import com.ruoyi.payment.api.model.*;
import com.ruoyi.payment.api.vo.*;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
@@ -115,7 +115,10 @@
public class TChargingOrderServiceImpl extends ServiceImpl<TChargingOrderMapper, TChargingOrder> implements TChargingOrderService {
   
   private Logger log = LoggerFactory.getLogger(TChargingOrderServiceImpl.class);
   private static final int WHITELIST_BENEFIT_ALL_FREE = 1;
   private static final int WHITELIST_BENEFIT_ELECTRIC_FREE = 2;
   private static final int WHITELIST_BENEFIT_SERVICE_FREE = 3;
   @Resource
   private ChargingGunClient chargingGunClient;
   @Resource
@@ -149,7 +152,9 @@
   
   @Resource
   private AppCouponClient appCouponClient;
   @Resource
   private AppUserWhitelistClient appUserWhitelistClient;
   @Resource
   private AppUserVipDetailClient appUserVipDetailClient;
   
@@ -205,7 +210,7 @@
   private VipClient vipClient;
   @Resource
   private OtherClient otherClient;
   @Resource
   private UserTagClient userTagClient;
   
@@ -421,15 +426,53 @@
    * @param addChargingOrder
    * @return
    */
    /**
     * 判断订单是否使用余额或余额组合支付
     *
     * @param payMethod 支付方式
     * @return true=余额相关支付方式
     */
    private boolean isBalancePayMode(Integer payMethod) {
        return payMethod != null && (payMethod == 1 || payMethod == 2);
    }
    /**
     * 将金额空值统一转换为两位小数,避免白名单退款和余额退款计算出现空指针
     *
     * @param amount 原始金额
     * @return 非空两位小数金额
     */
    private BigDecimal money(BigDecimal amount) {
        return amount == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : amount.setScale(2, RoundingMode.HALF_UP);
    }
    /**
     * 获取第三方实付金额,兼容早期未写入third_pay_amount的纯第三方支付订单。
     *
     * @param order 充电订单
     * @return 第三方可退款本金
     */
    private BigDecimal getRefundableThirdPayAmount(TChargingOrder order) {
        if (order == null || isWhitelistAllFreeOrder(order)) {
            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        }
        BigDecimal thirdPayAmount = money(order.getThirdPayAmount());
        if (thirdPayAmount.compareTo(BigDecimal.ZERO) > 0) {
            return thirdPayAmount;
        }
        if (Integer.valueOf(3).equals(order.getPayMethod())) {
            return money(order.getRechargeAmount());
        }
        return thirdPayAmount;
    }
    /**
     * 调整用户余额
     *
     * @param userId 用户ID
     * @param delta 余额变动金额
     */
    private void changeUserBalance(Long userId, BigDecimal delta) {
        if (userId == null || delta == null || delta.compareTo(BigDecimal.ZERO) == 0) {
            return;
@@ -443,6 +486,12 @@
    }
    /**
     * 记录兑换码余额消费流水
     *
     * @param chargingOrder 充电订单
     * @param consumeAmount 消费金额
     */
    private void recordBalanceConsume(TChargingOrder chargingOrder, BigDecimal consumeAmount) {
        if (chargingOrder == null || chargingOrder.getAppUserId() == null || chargingOrder.getId() == null
                || consumeAmount == null || consumeAmount.compareTo(BigDecimal.ZERO) <= 0) {
@@ -458,6 +507,13 @@
        }
    }
    /**
     * 记录兑换码余额退款流水
     *
     * @param chargingOrder 充电订单
     * @param refundAmount 退款金额
     * @param refundNo 退款单号
     */
    private void recordBalanceRefund(TChargingOrder chargingOrder, BigDecimal refundAmount, String refundNo) {
        if (chargingOrder == null || chargingOrder.getAppUserId() == null || chargingOrder.getId() == null
                || refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
@@ -474,8 +530,17 @@
        }
    }
    private void finishManualChargingRefund(TChargingOrder chargingOrder, TChargingOrderRefund refund,
                                            BigDecimal refundAmount, BigDecimal balanceRefundAmount, BigDecimal thirdRefundAmount) {
   /**
    * 完成人工退款结果落库,并同步余额退款流水
    *
    * @param chargingOrder 充电订单
    * @param refund 退款记录
    * @param refundAmount 退款总金额
    * @param balanceRefundAmount 余额退款金额
    * @param thirdRefundAmount 三方退款金额
    */
   private void finishManualChargingRefund(TChargingOrder chargingOrder, TChargingOrderRefund refund,
                                               BigDecimal refundAmount, BigDecimal balanceRefundAmount, BigDecimal thirdRefundAmount) {
        chargingOrder.setRefundStatus(2);
        chargingOrder.setRefundAmount(money(chargingOrder.getRefundAmount()).add(refundAmount));
        chargingOrder.setBalanceRefundAmount(money(chargingOrder.getBalanceRefundAmount()).add(balanceRefundAmount));
@@ -489,12 +554,67 @@
        }
    }
    /**
     * 判断订单是否为白名单订单
     *
     * @param chargingOrder 充电订单
     * @return true=白名单订单
     */
    private boolean isWhitelistOrder(TChargingOrder chargingOrder) {
        return chargingOrder != null && Integer.valueOf(1).equals(chargingOrder.getIsWhitelist());
    }
    /**
     * 判断订单是否为白名单全部免费权益
     *
     * @param chargingOrder 充电订单
     * @return true=全部免费白名单订单
     */
    private boolean isWhitelistAllFreeOrder(TChargingOrder chargingOrder) {
        return isWhitelistOrder(chargingOrder)
                && Integer.valueOf(WHITELIST_BENEFIT_ALL_FREE).equals(chargingOrder.getWhitelistBenefitType());
    }
    /**
     * 按白名单权益拆分电费和服务费减免金额,财务统计需要分开展示两类退款金额
     *
     * @param chargingOrder 充电订单
     * @param electrovalence 原始电费
     * @param serviceCharge 原始服务费
     * @return 数组下标0=电费减免,下标1=服务费减免
     */
    private BigDecimal[] calculateWhitelistRefundSplit(TChargingOrder chargingOrder, BigDecimal electrovalence, BigDecimal serviceCharge) {
        BigDecimal electricDiscount = BigDecimal.ZERO;
        BigDecimal serviceDiscount = BigDecimal.ZERO;
        if (!isWhitelistOrder(chargingOrder)) {
            return new BigDecimal[]{electricDiscount, serviceDiscount};
        }
        if (Integer.valueOf(WHITELIST_BENEFIT_ALL_FREE).equals(chargingOrder.getWhitelistBenefitType())) {
            electricDiscount = electrovalence == null ? BigDecimal.ZERO : electrovalence;
            serviceDiscount = serviceCharge == null ? BigDecimal.ZERO : serviceCharge;
        } else if (Integer.valueOf(WHITELIST_BENEFIT_ELECTRIC_FREE).equals(chargingOrder.getWhitelistBenefitType())) {
            electricDiscount = electrovalence == null ? BigDecimal.ZERO : electrovalence;
        } else if (Integer.valueOf(WHITELIST_BENEFIT_SERVICE_FREE).equals(chargingOrder.getWhitelistBenefitType())) {
            serviceDiscount = serviceCharge == null ? BigDecimal.ZERO : serviceCharge;
        }
        return new BigDecimal[]{electricDiscount, serviceDiscount};
    }
   @Override
   public AjaxResult paymentChargingOrder(AddChargingOrder addChargingOrder) {
      Long userId = tokenService.getLoginUserApplet().getUserId();
      TAppUser appUser = appUserClient.getUserById(userId).getData();
      Integer payMethod = addChargingOrder.getPayMethod() == null ? 3 : addChargingOrder.getPayMethod();
      BigDecimal rechargeAmount = money(addChargingOrder.getPaymentAmount());
      TChargingGun tChargingGun = chargingGunClient.getChargingGunById(addChargingOrder.getId()).getData();
      TChargingPile chargingPile = chargingPileClient.getChargingPileById(tChargingGun.getChargingPileId()).getData();
      AppUserWhitelistMatchVO whitelist = appUserWhitelistClient.matchWhitelist(userId, tChargingGun.getSiteId()).getData();
      boolean whitelistMatched = whitelist != null && Boolean.TRUE.equals(whitelist.getMatched());
      if (whitelistMatched) {
         payMethod = 3;
         addChargingOrder.setPayMethod(3);
         addChargingOrder.setAppUserCouponId(null);
      }
      BigDecimal userBalance = money(appUser.getBalance());
      BigDecimal balancePayAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
      BigDecimal thirdPayAmount = rechargeAmount;
@@ -509,6 +629,12 @@
         }
         balancePayAmount = payMethod == 1 ? rechargeAmount : userBalance.min(rechargeAmount).setScale(2, RoundingMode.HALF_UP);
         thirdPayAmount = rechargeAmount.subtract(balancePayAmount).setScale(2, RoundingMode.HALF_UP);
      }
      if (whitelistMatched) {
         balancePayAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
         thirdPayAmount = Integer.valueOf(WHITELIST_BENEFIT_ALL_FREE).equals(whitelist.getBenefitType())
               ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
               : rechargeAmount;
      }
      //查询待支付状态的订单,没有支付则删除订单
      List<TChargingOrder> list = this.list(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, userId)
@@ -620,8 +746,6 @@
            chargingOrder.setPlateNum(userCar.getLicensePlate());
         }
      }
      TChargingGun tChargingGun = chargingGunClient.getChargingGunById(addChargingOrder.getId()).getData();
      TChargingPile chargingPile = chargingPileClient.getChargingPileById(tChargingGun.getChargingPileId()).getData();
      chargingOrder.setSiteId(tChargingGun.getSiteId());
      chargingOrder.setChargingPileId(tChargingGun.getChargingPileId());
      chargingOrder.setChargingGunId(addChargingOrder.getId());
@@ -634,6 +758,12 @@
      chargingOrder.setThirdRefundAmount(BigDecimal.ZERO);
      chargingOrder.setRechargeAmount(rechargeAmount);
      chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId());
      chargingOrder.setIsWhitelist(whitelistMatched ? 1 : 0);
      chargingOrder.setWhitelistId(whitelistMatched ? whitelist.getWhitelistId() : null);
      chargingOrder.setWhitelistBenefitType(whitelistMatched ? whitelist.getBenefitType() : null);
      chargingOrder.setWhitelistDiscountAmount(BigDecimal.ZERO);
      chargingOrder.setWhitelistElectricRefundAmount(BigDecimal.ZERO);
      chargingOrder.setWhitelistServiceRefundAmount(BigDecimal.ZERO);
      chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
      chargingOrder.setOrderSource(1);
      chargingOrder.setTitle("【充电桩充电】" + chargingPile.getNumber() + "号桩/" + tChargingGun.getCode() + "号枪");
@@ -647,7 +777,7 @@
      TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
      
      //直营站点才可以享受会员折扣
      if (!isBalancePayMode(payMethod) && null != appUser.getVipId() && 1 == site.getBusinessCategory()) {
      if (!whitelistMatched && !isBalancePayMode(payMethod) && null != appUser.getVipId() && 1 == site.getBusinessCategory()) {
         TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
         BigDecimal discount = null;
         if (1 == vip.getType()) {
@@ -692,7 +822,7 @@
         recordBalanceConsume(chargingOrder, balancePayAmount);
      }
      if (thirdPayAmount.compareTo(BigDecimal.ZERO) == 0) {
         return chargingOrderCallback(addChargingOrder.getPaymentType(), chargingOrder.getCode(), "BALANCE", null);
         return chargingOrderCallback(addChargingOrder.getPaymentType(), chargingOrder.getCode(), whitelistMatched ? "WHITELIST" : "BALANCE", null);
      }
      //会员优惠折扣将其计入增加充电时长(增加总充电金额)
      //如果充电总金额未使用完,则需要退回费用=(原金额/总金额)*(总金额-实际充电金额)
@@ -774,6 +904,7 @@
      preChargeCheck.setInsulationTesting(false);
      preChargeCheck.setSecureConnectionDetection(false);
      preChargeCheck.setStartupSuccess(1);
        preChargeCheck.setAddTime(LocalDateTime.now());
      String key = "AQJC_" + chargingOrder.getChargingGunId();
      redisService.setCacheObject(key, preChargeCheck, 24L, TimeUnit.HOURS);
      
@@ -795,7 +926,7 @@
      
      TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
      //判断会员是否还有充电优惠次数,计算会员优惠的折扣金额
      if (null != appUser.getVipId()) {
      if (!isWhitelistOrder(chargingOrder) && null != appUser.getVipId()) {
         GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
         getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
         getAppUserVipDetail.setVipId(appUser.getVipId());
@@ -1162,22 +1293,22 @@
                TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code));
                if (chargingOrder.getOrderSource() == 1 && chargingOrder.getStatus() == 2
                        && (chargingOrder.getRefundStatus() == null || chargingOrder.getRefundStatus() != 2)) {
                    Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
                    BigDecimal rechargeAmount = money(chargingOrder.getRechargeAmount());
                    BigDecimal totalRefundAmount = isBalancePayMode(chargingOrder.getPayMethod())
                            ? money(chargingOrder.getBalancePayAmount()).add(money(chargingOrder.getThirdPayAmount())).setScale(2, RoundingMode.HALF_UP)
                            : rechargeAmount;
                    BigDecimal thirdRefundAmount = totalRefundAmount.min(money(chargingOrder.getThirdPayAmount())).setScale(2, RoundingMode.HALF_UP);
                    if (!isBalancePayMode(chargingOrder.getPayMethod())) {
                        thirdRefundAmount = totalRefundAmount;
                    }
                    BigDecimal balanceRefundAmount = totalRefundAmount.subtract(thirdRefundAmount).min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                       Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
                       BigDecimal rechargeAmount = money(chargingOrder.getRechargeAmount());
                       BigDecimal totalRefundAmount = isBalancePayMode(chargingOrder.getPayMethod())
                               ? money(chargingOrder.getBalancePayAmount()).add(money(chargingOrder.getThirdPayAmount())).setScale(2, RoundingMode.HALF_UP)
                               : rechargeAmount;
                       // 白名单全部免费启动失败同样只记录预估金额,避免未支付订单进入实际退款流程。
                       BigDecimal recordedRefundAmount = isWhitelistAllFreeOrder(chargingOrder) ? rechargeAmount : totalRefundAmount;
                       BigDecimal channelRefundAmount = isWhitelistAllFreeOrder(chargingOrder) ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : totalRefundAmount;
                    BigDecimal thirdRefundAmount = channelRefundAmount.min(getRefundableThirdPayAmount(chargingOrder)).setScale(2, RoundingMode.HALF_UP);
                       BigDecimal balanceRefundAmount = channelRefundAmount.subtract(thirdRefundAmount).min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                    //构建退款明细
                    TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
                    chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                    chargingOrderRefund.setRefundCode("CDF" + sdf.format(new Date()) + Double.valueOf(Math.random() * 1000).intValue());
                    chargingOrderRefund.setRefundAmount(totalRefundAmount);
                    chargingOrderRefund.setRefundAmount(recordedRefundAmount);
                    chargingOrderRefund.setBalanceRefundAmount(balanceRefundAmount);
                    chargingOrderRefund.setThirdRefundAmount(thirdRefundAmount);
                    chargingOrderRefund.setRefundStatus(1);
@@ -1187,12 +1318,12 @@
                    chargingOrderRefund.setRefundTitle("充电失败");
                    chargingOrderRefund.setRefundContent("充电失败");
                    chargingOrderRefund.setRefundReason("充电失败");
                    chargingOrderRefund.setRefundRemark("全额退款");
                    chargingOrderRefund.setRefundTotalAmount(totalRefundAmount);
                    chargingOrderRefund.setRefundRemark(isWhitelistAllFreeOrder(chargingOrder) ? "白名单全部免费,启动失败记录预估退款金额" : "全额退款");
                    chargingOrderRefund.setRefundTotalAmount(recordedRefundAmount);
                    chargingOrderRefund.setPayAmount(rechargeAmount);
                    chargingOrder.setBalanceRefundAmount(balanceRefundAmount);
                    chargingOrder.setThirdRefundAmount(thirdRefundAmount);
                    chargingOrder.setRefundAmount(totalRefundAmount);
                    chargingOrder.setRefundAmount(recordedRefundAmount);
                    chargingOrder.setRefundStatus(thirdRefundAmount.compareTo(BigDecimal.ZERO) > 0 ? 1 : 2);
                    if (thirdRefundAmount.compareTo(BigDecimal.ZERO) == 0) {
                        if (balanceRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
@@ -1200,7 +1331,7 @@
                            recordBalanceRefund(chargingOrder, balanceRefundAmount, chargingOrderRefund.getRefundCode());
                        }
                        chargingOrderRefund.setRefundStatus(2);
                        chargingOrderRefund.setRefundSerialNumber("BALANCE");
                        chargingOrderRefund.setRefundSerialNumber(isWhitelistAllFreeOrder(chargingOrder) ? "WHITELIST" : "BALANCE");
                        chargingOrderRefund.setRefundTime(LocalDateTime.now());
                        chargingOrderRefundService.save(chargingOrderRefund);
                        this.updateById(chargingOrder);
@@ -1215,7 +1346,7 @@
                        model.setNotify_url("/payment/wx/refund/notify");
                        WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
                        amount.setRefund(thirdRefundAmount.multiply(new BigDecimal(100)).intValue());
                        amount.setTotal((isBalancePayMode(chargingOrder.getPayMethod()) ? money(chargingOrder.getThirdPayAmount()) : rechargeAmount).multiply(new BigDecimal(100)).intValue());
                        amount.setTotal(getRefundableThirdPayAmount(chargingOrder).multiply(new BigDecimal(100)).intValue());
                        amount.setCurrency("CNY");
                        model.setAmount(amount);
                        R<Map<String, Object>> orderR = wxPaymentClient.refundOrderR(model);
@@ -1366,7 +1497,7 @@
            model.setNotify_url("/payment/wx/refund/notify");
            WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
            amount.setRefund(thirdRefundAmount.multiply(new BigDecimal(100)).intValue());
            amount.setTotal((isBalancePayMode(chargingOrder.getPayMethod()) ? money(chargingOrder.getThirdPayAmount()) : rechargeAmount).multiply(new BigDecimal(100)).intValue());
            amount.setTotal(getRefundableThirdPayAmount(chargingOrder).multiply(new BigDecimal(100)).intValue());
            amount.setCurrency("CNY");
            model.setAmount(amount);
            R<Map<String, Object>> orderR = wxPaymentClient.refundOrderR(model);
@@ -1873,6 +2004,9 @@
         return tCharingOrderVO;
      }
      /**
       * 填充充电桩订单列表余额收入,余额收入按真实充值余额统计,赠送余额单独展示。
       */
      private void fillChargingOrderBalanceIncome(List<ChargingOrderVO> list) {
         if (list == null || list.isEmpty()) {
            return;
@@ -1897,7 +2031,7 @@
            item.setBalanceGiftIncome(getSummaryDecimal(row, "balanceGiftIncome"));
         }
      }
      private void setChargingOrderAuthSiteIds(ChargingOrderQuery dto, SysUser sysUser, Long userId, Integer roleType) {
      List<Integer> siteIds = new ArrayList<>();
      if (dto.getSiteId() == null) {
@@ -1929,6 +2063,9 @@
      dto.setSiteIds(siteIds);
   }
   /**
    * 查询充电桩订单余额收入明细,余额收入按真实充值余额统计,赠送收入单独展示。
    */
   @Override
   public List<ChargingOrderBalanceIncomeDetailVO> balanceIncomeDetail(ChargingOrderQuery dto) {
      String startTime1 = null;
@@ -2012,6 +2149,9 @@
      tCharingOrderVO.setWhitelistRefund(BigDecimal.ZERO);
   }
   /**
    * 汇总充电桩订单余额收入,兑换码使用记录的usedAmount包含赠送余额,SQL中需扣除giftUsedAmount。
    */
   private Map<String, Object> getExchangeCodeBalanceSummary(ChargingOrderQuery dto, String startTime1, String startTime2, String endTime1, String endTime2) {
      Map<String, Object> totalMap = new HashMap<>();
      totalMap.put("balanceIncome", BigDecimal.ZERO);
@@ -2114,7 +2254,112 @@
   public Map<String, Object> countAll(List<Integer> siteIds) {
      return this.baseMapper.countAll(siteIds);
   }
   /**
    * 统计近六月订单收入支付方式占比;服务层聚合避免复杂CASE SQL在当前数据库驱动中转换异常。
    */
   @Override
   public List<SixIncomeCircleDto> payTypeCircle(LocalDate sixBefore, List<Integer> siteIds) {
      if (siteIds == null || siteIds.isEmpty()) {
         return buildPayTypeCircleData(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
      }
      List<TChargingOrder> orders = this.lambdaQuery()
            .select(TChargingOrder::getRechargePaymentType, TChargingOrder::getPayMethod,
                  TChargingOrder::getThirdPayAmount, TChargingOrder::getThirdRefundAmount,
                  TChargingOrder::getBalancePayAmount, TChargingOrder::getBalanceRefundAmount,
                  TChargingOrder::getPaymentAmount, TChargingOrder::getRechargeAmount,
                  TChargingOrder::getRefundAmount)
            .eq(TChargingOrder::getDelFlag, 0)
            .eq(TChargingOrder::getRechargePaymentStatus, 2)
            .eq(TChargingOrder::getStatus, 5)
            .ge(sixBefore != null, TChargingOrder::getCreateTime, sixBefore == null ? null : sixBefore.atStartOfDay())
            .in(TChargingOrder::getSiteId, siteIds)
            .list();
      BigDecimal wechatAmount = BigDecimal.ZERO;
      BigDecimal alipayAmount = BigDecimal.ZERO;
      BigDecimal balanceAmount = BigDecimal.ZERO;
      for (TChargingOrder order : orders) {
         BigDecimal thirdPayAmount = getThirdPayNetAmount(order);
         BigDecimal balancePayAmount = getBalancePayNetAmount(order);
         Integer rechargePaymentType = order.getRechargePaymentType();
         if (Integer.valueOf(1).equals(rechargePaymentType)) {
            wechatAmount = wechatAmount.add(thirdPayAmount);
         }
         if (Integer.valueOf(2).equals(rechargePaymentType) || Integer.valueOf(3).equals(rechargePaymentType)) {
            alipayAmount = alipayAmount.add(thirdPayAmount);
         }
         Integer payMethod = order.getPayMethod();
         if (Integer.valueOf(1).equals(payMethod) || Integer.valueOf(2).equals(payMethod)) {
            balanceAmount = balanceAmount.add(balancePayAmount);
         }
      }
      return buildPayTypeCircleData(wechatAmount, alipayAmount, balanceAmount);
   }
   /**
    * 构造固定三类支付方式数据,保证前端饼图在无订单时也有稳定结构。
    */
   private List<SixIncomeCircleDto> buildPayTypeCircleData(BigDecimal wechatAmount, BigDecimal alipayAmount, BigDecimal balanceAmount) {
      List<SixIncomeCircleDto> data = new ArrayList<>();
      data.add(buildIncomeCircleDto("微信支付", wechatAmount));
      data.add(buildIncomeCircleDto("支付宝支付", alipayAmount));
      data.add(buildIncomeCircleDto("余额支付", balanceAmount));
      return data;
   }
   /**
    * 构造单个饼图项并统一金额精度。
    */
   private SixIncomeCircleDto buildIncomeCircleDto(String name, BigDecimal paymentAmount) {
      SixIncomeCircleDto dto = new SixIncomeCircleDto();
      dto.setName(name);
      dto.setPaymentAmount(nullToZero(paymentAmount).setScale(2, RoundingMode.HALF_EVEN));
      return dto;
   }
   /**
    * 计算第三方渠道实收:优先使用拆分字段,兼容旧订单回退到paymentAmount/rechargeAmount。
    */
   private BigDecimal getThirdPayNetAmount(TChargingOrder order) {
      BigDecimal payAmount = order.getThirdPayAmount();
      if (payAmount == null && Integer.valueOf(3).equals(order.getPayMethod())) {
         payAmount = firstNonNull(order.getPaymentAmount(), order.getRechargeAmount());
      }
      BigDecimal refundAmount = order.getThirdRefundAmount();
      if (refundAmount == null && Integer.valueOf(3).equals(order.getPayMethod())) {
         refundAmount = order.getRefundAmount();
      }
      return nonNegative(nullToZero(payAmount).subtract(nullToZero(refundAmount)));
   }
   /**
    * 计算余额渠道实收:组合支付优先使用拆分字段,兼容旧余额订单回退到paymentAmount。
    */
   private BigDecimal getBalancePayNetAmount(TChargingOrder order) {
      BigDecimal payAmount = order.getBalancePayAmount();
      Integer payMethod = order.getPayMethod();
      if (payAmount == null && (Integer.valueOf(1).equals(payMethod) || Integer.valueOf(2).equals(payMethod))) {
         payAmount = order.getPaymentAmount();
      }
      BigDecimal refundAmount = order.getBalanceRefundAmount();
      if (refundAmount == null && (Integer.valueOf(1).equals(payMethod) || Integer.valueOf(2).equals(payMethod))) {
         refundAmount = order.getRefundAmount();
      }
      return nonNegative(nullToZero(payAmount).subtract(nullToZero(refundAmount)));
   }
   private BigDecimal firstNonNull(BigDecimal first, BigDecimal second) {
      return first != null ? first : second;
   }
   private BigDecimal nullToZero(BigDecimal value) {
      return value == null ? BigDecimal.ZERO : value;
   }
   private BigDecimal nonNegative(BigDecimal value) {
      return value.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : value;
   }
   @Override
   public List<Map<String, Object>> getSumByType(LocalDate start, LocalDate end, List<Integer> siteIds) {
      LocalDateTime start1 = start.atStartOfDay();
@@ -2315,6 +2560,11 @@
         if(null != map.get("licensePlate")){
            chargingOrderListVO.setLicensePlate(map.get("licensePlate").toString());
         }
         chargingOrderListVO.setIsWhitelist(null == map.get("isWhitelist") ? 0 : Integer.valueOf(map.get("isWhitelist").toString()));
         // 白名单退款金额由电费退款和服务费退款组成,列表展示总额,财务导出继续保留拆分字段。
         chargingOrderListVO.setWhitelistElectricRefundAmount(getSummaryDecimal(map, "whitelistElectricRefundAmount"));
         chargingOrderListVO.setWhitelistServiceRefundAmount(getSummaryDecimal(map, "whitelistServiceRefundAmount"));
         chargingOrderListVO.setWhitelistRefundAmount(getSummaryDecimal(map, "whitelistRefundAmount"));
         BigDecimal jian = null == map.get("jian") ? BigDecimal.ZERO : new BigDecimal(map.get("jian").toString());
         BigDecimal feng = null == map.get("feng") ? BigDecimal.ZERO : new BigDecimal(map.get("feng").toString());
         BigDecimal ping = null == map.get("ping") ? BigDecimal.ZERO : new BigDecimal(map.get("ping").toString());
@@ -2517,9 +2767,38 @@
      }
      dto.setSiteIds(siteIds);
      List<ChargingOrderListVO> list1 = this.baseMapper.chargingList(dto, startTime1, startTime2, endTime1, endTime2);
      fillChargingPeriodExportBalanceIncome(list1);
      return list1;
   }
   /**
    * 充电时段统计导出补充余额收入;兑换码usedAmount包含赠送金额,需沿用订单列表口径拆分。
    */
   private void fillChargingPeriodExportBalanceIncome(List<ChargingOrderListVO> list) {
      if (list == null || list.isEmpty()) {
         return;
      }
      List<Long> orderIds = list.stream().map(ChargingOrderListVO::getId).filter(Objects::nonNull).collect(Collectors.toList());
      if (orderIds.isEmpty()) {
         return;
      }
      Map<Long, Map<String, Object>> incomeMap = new HashMap<>();
      List<Map<String, Object>> rows = this.baseMapper.exchangeCodeBalanceIncomeByOrderIds(orderIds);
      if (rows != null) {
         for (Map<String, Object> row : rows) {
            Long orderId = getSummaryLong(row, "orderId");
            if (orderId != null) {
               incomeMap.put(orderId, row);
            }
         }
      }
      for (ChargingOrderListVO item : list) {
         Map<String, Object> row = incomeMap.get(item.getId());
         item.setBalanceIncome(getSummaryDecimal(row, "balanceIncome"));
         item.setBalanceGiftIncome(getSummaryDecimal(row, "balanceGiftIncome"));
      }
   }
   
   @Override
   public ChargingOrderListInfoVO chargingInfo(String uid) {
@@ -2713,6 +2992,12 @@
      RLock lock = redissonClient.getLock("endOrder:" + vo.getTransaction_serial_number());
      try {
            boolean tryLock = lock.tryLock(60, 60, TimeUnit.SECONDS);
            //添加redis缓存数据,过期时间,用于防止处理缓慢且硬件重复发送报文导致的重复退款
            Boolean hasKey = redisService.hasKey("END_ORDER:" + vo.getTransaction_serial_number());
            if(hasKey){
                return R.fail("不能重复退款");
            }
            redisService.setCacheObject("END_ORDER:" + vo.getTransaction_serial_number(), System.currentTimeMillis() + "", 10L, TimeUnit.MINUTES);
            if(tryLock){
                TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, vo.getTransaction_serial_number()));
                if (null == chargingOrder) {
@@ -2959,7 +3244,7 @@
                //计算优惠券
                BigDecimal couponDiscount = BigDecimal.ZERO;
                if (!isBalancePayMode(chargingOrder.getPayMethod()) && null != chargingOrder.getAppCouponId()) {
                if (!isWhitelistOrder(chargingOrder) && !isBalancePayMode(chargingOrder.getPayMethod()) && null != chargingOrder.getAppCouponId()) {
                    //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。
                    TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData();
                    String couponJson = appCoupon.getCouponJson();
@@ -3007,6 +3292,17 @@
                        }
                    }
                }
                BigDecimal[] whitelistRefundSplit = calculateWhitelistRefundSplit(chargingOrder, periodElectricPrice_total, serviceCharge_total);
                BigDecimal electricDiscount = whitelistRefundSplit[0];
                BigDecimal serviceDiscount = whitelistRefundSplit[1];
                BigDecimal whitelistDiscount = electricDiscount.add(serviceDiscount).setScale(4, RoundingMode.HALF_EVEN);
                if (whitelistDiscount.compareTo(BigDecimal.ZERO) > 0) {
                    // 白名单退款按权益拆分入库,订单金额仍沿用原有应收减免逻辑。
                    periodElectricPrice_total = periodElectricPrice_total.subtract(electricDiscount).max(BigDecimal.ZERO);
                    serviceCharge_total = serviceCharge_total.subtract(serviceDiscount).max(BigDecimal.ZERO);
                    refundAmount = refundAmount.add(whitelistDiscount);
                    payAmount = payAmount.subtract(whitelistDiscount).max(BigDecimal.ZERO);
                }
                //优惠券优惠金额
                couponDiscount = couponDiscount.setScale(4, RoundingMode.HALF_EVEN);
                //退款金额+优惠券
@@ -3017,20 +3313,34 @@
                    serviceCharge_total = serviceCharge_total.subtract(couponDiscount);
                }
                chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setWhitelistDiscountAmount(whitelistDiscount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setWhitelistElectricRefundAmount(electricDiscount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setWhitelistServiceRefundAmount(serviceDiscount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setElectrovalence(periodElectricPrice_total.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN));
                refundAmount = refundAmount.max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
                // 白名单全部免费无需实际渠道退款,但财务展示需要将预估预充金额记录到订单退款金额。
                BigDecimal recordedRefundAmount = isWhitelistAllFreeOrder(chargingOrder)
                        ? money(chargingOrder.getRechargeAmount())
                        : refundAmount;
                Integer payMethod = chargingOrder.getPayMethod();
                BigDecimal thirdRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
                BigDecimal balanceRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
                BigDecimal refundableThirdPayAmount = getRefundableThirdPayAmount(chargingOrder);
                BigDecimal refundableAmount = refundableThirdPayAmount.add(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                // 全部免费订单启动时未拉起支付,渠道可退金额固定为0,避免误触发微信/支付宝/余额退款。
                BigDecimal channelRefundAmount = isWhitelistAllFreeOrder(chargingOrder)
                        ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
                        : refundAmount.min(refundableAmount).setScale(2, RoundingMode.HALF_UP);
                if (Integer.valueOf(1).equals(payMethod)) {
                    balanceRefundAmount = refundAmount.min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                    balanceRefundAmount = channelRefundAmount.min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                } else if (Integer.valueOf(2).equals(payMethod)) {
                    thirdRefundAmount = refundAmount.min(money(chargingOrder.getThirdPayAmount())).setScale(2, RoundingMode.HALF_UP);
                    balanceRefundAmount = refundAmount.subtract(thirdRefundAmount).min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                    thirdRefundAmount = channelRefundAmount.min(refundableThirdPayAmount).setScale(2, RoundingMode.HALF_UP);
                    balanceRefundAmount = channelRefundAmount.subtract(thirdRefundAmount).min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                } else {
                    thirdRefundAmount = refundAmount;
                    thirdRefundAmount = channelRefundAmount.min(refundableThirdPayAmount).setScale(2, RoundingMode.HALF_UP);
                }
                BigDecimal actualThirdPayAmount = money(chargingOrder.getThirdPayAmount()).subtract(thirdRefundAmount);
                BigDecimal actualThirdPayAmount = refundableThirdPayAmount.subtract(thirdRefundAmount);
                if (actualThirdPayAmount.compareTo(BigDecimal.ZERO) < 0) {
                    actualThirdPayAmount = BigDecimal.ZERO;
                }
@@ -3038,12 +3348,13 @@
                if (actualBalancePayAmount.compareTo(BigDecimal.ZERO) < 0) {
                    actualBalancePayAmount = BigDecimal.ZERO;
                }
                refundAmount = thirdRefundAmount.add(balanceRefundAmount);
                refundAmount = recordedRefundAmount;
                chargingOrder.setBalanceRefundAmount(balanceRefundAmount.setScale(2, RoundingMode.HALF_UP));
                chargingOrder.setThirdRefundAmount(thirdRefundAmount.setScale(2, RoundingMode.HALF_UP));
                chargingOrder.setPaymentAmount(actualThirdPayAmount.setScale(2, RoundingMode.HALF_EVEN));
                // paymentAmount用于小程序展示实际消费金额,需包含第三方实扣和余额实扣,不能只取第三方渠道金额。
                chargingOrder.setPaymentAmount(actualThirdPayAmount.add(actualBalancePayAmount).setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setRefundAmount(refundAmount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setRefundStatus(1);
                chargingOrder.setRefundStatus(channelRefundAmount.compareTo(BigDecimal.ZERO) > 0 ? 1 : 2);
                UploadRealTimeMonitoringData asc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "asc");
                UploadRealTimeMonitoringData desc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "desc");
                if(null != asc){
@@ -3146,7 +3457,7 @@
                    //开始构建退款费用
                    refundAmount = refundAmount.setScale(2, RoundingMode.HALF_EVEN);
                    Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
                    if (refundAmount.compareTo(BigDecimal.ZERO) > 0) {
                    if (channelRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
                        //构建退款明细
                        TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
                        chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
@@ -3185,7 +3496,7 @@
                            model.setNotify_url("/payment/wx/refund/notify");
                            WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
                            amount.setRefund(thirdRefundAmount.multiply(new BigDecimal(100)).intValue());
                            amount.setTotal((isBalancePayMode(chargingOrder.getPayMethod()) ? money(chargingOrder.getThirdPayAmount()) : rechargeAmount).multiply(new BigDecimal(100)).intValue());
                            amount.setTotal(getRefundableThirdPayAmount(chargingOrder).multiply(new BigDecimal(100)).intValue());
                            amount.setCurrency("CNY");
                            model.setAmount(amount);
                            R<Map<String, Object>> result = wxPaymentClient.refundOrderR(model);
@@ -3222,7 +3533,31 @@
                                this.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                            }
                        }
                    }else{
                    } else if (recordedRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
                        TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
                        chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
                        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                        chargingOrderRefund.setRefundCode("CDF" + sdf1.format(new Date()) + (Double.valueOf(Math.random() * 1000).intValue()));
                        chargingOrderRefund.setRefundAmount(recordedRefundAmount);
                        chargingOrderRefund.setBalanceRefundAmount(balanceRefundAmount);
                        chargingOrderRefund.setThirdRefundAmount(thirdRefundAmount);
                        chargingOrderRefund.setRefundStatus(2);
                        chargingOrderRefund.setRefundSerialNumber(isWhitelistAllFreeOrder(chargingOrder) ? "WHITELIST" : "BALANCE");
                        chargingOrderRefund.setPayType(rechargePaymentType);
                        chargingOrderRefund.setCode(chargingOrder.getCode());
                        chargingOrderRefund.setRefundTitle("充电完成退款");
                        chargingOrderRefund.setRefundContent("充电完成退款");
                        chargingOrderRefund.setRefundReason("充电完成退款");
                        chargingOrderRefund.setRefundRemark(isWhitelistAllFreeOrder(chargingOrder) ? "白名单全部免费,记录预估退款金额" : "实际充电消费金额:" + chargingOrder.getPaymentAmount());
                        chargingOrderRefund.setRefundTotalAmount(recordedRefundAmount);
                        chargingOrderRefund.setPayAmount(rechargeAmount);
                        chargingOrderRefund.setRefundTime(LocalDateTime.now());
                        chargingOrderRefundService.save(chargingOrderRefund);
                        chargingOrder.setRefundStatus(2);
                        chargingOrder.setRefundTime(LocalDateTime.now());
                        this.updateById(chargingOrder);
                    } else {
                        //构建退款明细
                        TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
                        chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
@@ -3429,7 +3764,7 @@
         }
         chargingOrderRefund.setBalanceRefundAmount(balanceRefundAmount);
         chargingOrderRefund.setThirdRefundAmount(thirdRefundAmount);
         if (thirdRefundAmount.compareTo(BigDecimal.ZERO) == 0) {
            chargingOrderRefund.setRefundSerialNumber("BALANCE");
            finishManualChargingRefund(tChargingOrder, chargingOrderRefund, manualRefundAmount, balanceRefundAmount, thirdRefundAmount);
@@ -3443,7 +3778,7 @@
            model.setNotify_url("/payment/wx/refund/notify");
            WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
            amount.setRefund(thirdRefundAmount.multiply(new BigDecimal(100)).intValue());
            amount.setTotal((isBalancePayMode(tChargingOrder.getPayMethod()) ? money(tChargingOrder.getThirdPayAmount()) : money(tChargingOrder.getRechargeAmount())).multiply(new BigDecimal(100)).intValue());
            amount.setTotal(getRefundableThirdPayAmount(tChargingOrder).multiply(new BigDecimal(100)).intValue());
            amount.setCurrency("CNY");
            model.setAmount(amount);
            R<Map<String, Object>> orderR = wxPaymentClient.refundOrderR(model);
@@ -3519,7 +3854,7 @@
         shoppingOrderRefund.setRefundRemark(payOrderQueryDto.getRemark());
         shoppingOrderRefund.setRefundTotalAmount(shoppingOrder.getRefundAmount().add(payOrderQueryDto.getRefundAmount()));
         shoppingOrderRefund.setPayAmount(shoppingOrder.getPaymentAmount());
         if (1 == shoppingOrder.getPaymentType()) {
            WxPaymentRefundModel model = new WxPaymentRefundModel();
            model.setOut_trade_no(shoppingOrder.getCode());
@@ -4629,6 +4964,7 @@
      preChargeCheck.setInsulationTesting(false);
      preChargeCheck.setSecureConnectionDetection(false);
      preChargeCheck.setStartupSuccess(1);
        preChargeCheck.setAddTime(LocalDateTime.now());
      String key = "AQJC_" + chargingOrder.getChargingGunId();
      redisService.setCacheObject(key, preChargeCheck, 24L, TimeUnit.HOURS);
      
@@ -4940,4 +5276,634 @@
   public List<Map<String, Object>> getAccountSettlementStatement(String startTime, String endTime, Integer rechargePaymentType) {
      return this.baseMapper.getAccountSettlementStatement(startTime, endTime, rechargePaymentType);
   }
    /**
     * 手动处理退款数据
     * @param refund_out_trade_no 退款商户单号
     */
    @Override
    public void orderQueryRefund(Long orderId, String refund_out_trade_no) {
        TChargingOrder chargingOrder = this.getById(orderId);
        BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
        List<TChargingOrderRefund> orderRefunds = chargingOrderRefundService.list(new QueryWrapper<TChargingOrderRefund>().eq("charging_order_id", orderId));
        List<String> collect = orderRefunds.stream().map(TChargingOrderRefund::getRefundCode).collect(Collectors.toList());
        if(!collect.contains(refund_out_trade_no)){
            if(1 == chargingOrder.getRechargePaymentType()){
                Map<String, Object> data = wxPaymentClient.queryRefund(refund_out_trade_no).getData();
                if(null == data){
                    throw new ServiceException("退款查询失败");
                }
                log.info("退款查询结果:{}", JSON.toJSONString(data));
                Map<String, Object> amount = (Map<String, Object>)data.get("amount");
                TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
                chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
                chargingOrderRefund.setRefundCode(refund_out_trade_no);
                chargingOrderRefund.setRefundAmount(new BigDecimal(amount.get("refund").toString()).divide(new BigDecimal(100)));
                chargingOrderRefund.setRefundStatus(2);
                chargingOrderRefund.setPayType(1);
                chargingOrderRefund.setRefundSerialNumber(data.get("refund_id").toString());
                String success_time = data.get("success_time").toString();
                success_time = success_time.replace("T", " ");
                success_time = success_time.substring(0, success_time.lastIndexOf("+"));
                chargingOrderRefund.setRefundTime(LocalDateTime.parse(success_time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                chargingOrderRefund.setCode(chargingOrder.getCode());
                chargingOrderRefund.setRefundTitle(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
                chargingOrderRefund.setRefundContent(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
                chargingOrderRefund.setRefundReason(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
                chargingOrderRefund.setRefundRemark(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
                chargingOrderRefund.setRefundTotalAmount(new BigDecimal(amount.get("refund").toString()).divide(new BigDecimal(100)));
                chargingOrderRefund.setPayAmount(rechargeAmount);
                chargingOrderRefund.setCreateTime(chargingOrderRefund.getRefundTime());
                chargingOrderRefundService.save(chargingOrderRefund);
                if(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0){
                    chargingOrder.setStatus(-1);
                }else{
                    chargingOrder.setStatus(5);
                }
                this.updateById(chargingOrder);
            }
            if(2 == chargingOrder.getRechargePaymentType()){
                QueryRefundReq dto = new QueryRefundReq();
                dto.setOutTradeNo(refund_out_trade_no);
                QueryRefundResp data = aliPaymentClient.queryRefund(dto).getData();
                if(null == data){
                    throw new ServiceException("退款查询失败");
                }
                TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
                chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
                chargingOrderRefund.setRefundCode(refund_out_trade_no);
                chargingOrderRefund.setRefundAmount(new BigDecimal(data.getRefundAmount()));
                chargingOrderRefund.setRefundStatus(2);
                chargingOrderRefund.setPayType(1);
                chargingOrderRefund.setRefundSerialNumber(data.getOutRequestNo());
                chargingOrderRefund.setRefundTime(LocalDateTime.parse(data.getRefundTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                chargingOrderRefund.setCode(chargingOrder.getCode());
                chargingOrderRefund.setRefundTitle(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
                chargingOrderRefund.setRefundContent(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
                chargingOrderRefund.setRefundReason(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
                chargingOrderRefund.setRefundRemark(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0 ? "充电失败" : "充电完成退款");
                chargingOrderRefund.setRefundTotalAmount(new BigDecimal(data.getRefundAmount()));
                chargingOrderRefund.setPayAmount(rechargeAmount);
                chargingOrderRefund.setCreateTime(chargingOrderRefund.getRefundTime());
                chargingOrderRefundService.save(chargingOrderRefund);
                if(rechargeAmount.compareTo(chargingOrderRefund.getRefundAmount()) == 0){
                    chargingOrder.setStatus(-1);
                }else{
                    chargingOrder.setStatus(5);
                }
                this.updateById(chargingOrder);
            }
        }
    }
    /**
     * 手动添加完善订单费用明细
     * @param orderId
     */
    @Override
    public void addOrderExpenseBreakdown(Long orderId) {
        try {
            TChargingOrder chargingOrder = this.getById(orderId);
            TransactionRecord one = transactionRecordService.findOne(chargingOrder.getCode());
            if(null != one){
                TransactionRecordMessageVO vo = new TransactionRecordMessageVO();
                BeanUtils.copyProperties(one, vo);
                //如果使用优惠券需要判断优惠券是否满足使用条件
                //退款金额=优惠券金额+剩余充电金额
                BigDecimal periodElectricPrice_total = BigDecimal.ZERO;
                BigDecimal periodServicePrice_total = BigDecimal.ZERO;
                BigDecimal vipDiscountAmount_total = BigDecimal.ZERO;
                BigDecimal serviceCharge_total = BigDecimal.ZERO;
                BigDecimal total = BigDecimal.ZERO;
                //获取订单的计费策略
                List<AccountingStrategyDetailOrder> accountingStrategyDetailOrderList = accountingStrategyDetailOrderClient.getAllAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
                if (accountingStrategyDetailOrderList.isEmpty()) {
                    throw new ServiceException("计费策略为空,无法计算费用");
                }
                accountingStrategyDetailOrderList.get(accountingStrategyDetailOrderList.size() - 1).setEndTime("23:59");
                //开始处理计费明细数据和优惠数据
                chargingOrderAccountingStrategyService.remove(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()));
                SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                List<AccountingStrategyDetailOrderVo> lists = new ArrayList<>();
                List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
                if(!dataList.isEmpty()){
                    vo.setStart_time(sdfs.format(dataList.get(dataList.size() - 1).getCreate_time()) + ".00");
                    vo.setEnd_time(sdfs.format(dataList.get(0).getCreate_time()) + ".00");
                }
                //跨天
                if (!vo.getStart_time().split(" ")[0].equals(vo.getEnd_time().split(" ")[0])) {
                    //当天的
                    //开始通过计费策略遍历解析每个时段的费用明细
                    String start_time = vo.getStart_time();
                    String end_time = vo.getEnd_time();
                    long start = sdfs.parse(start_time).getTime();
                    long end = sdfs.parse(end_time).getTime();
                    Class<? extends TransactionRecordMessageVO> clazz = vo.getClass();
                    /**
                     * "start_time": "2025-01-03 23:06:43.00",
                     *    "end_time": "2025-01-04 00:39:39.00",
                     */
                    for (int i = accountingStrategyDetailOrderList.size(); i > 0; i--) {
                        AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderList.get(i - 1);
                        long time = sdfs.parse(start_time.split(" ")[0] + " " + strategyDetail.getEndTime() + ":00").getTime();
                        if (time < start) {
                            break;
                        }
                        //阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)
                        Object invoke = null;
                        switch (strategyDetail.getType()) {
                            case 1:
                                //充电度数
                                invoke = clazz.getMethod("getSpike_charge" + (i)).invoke(vo);
                                break;
                            case 2:
                                //充电度数
                                invoke = clazz.getMethod("getPeak_charge" + (i)).invoke(vo);
                                break;
                            case 3:
                                //充电度数
                                invoke = clazz.getMethod("getFlat_charge" + (i)).invoke(vo);
                                break;
                            case 4:
                                //充电度数
                                invoke = clazz.getMethod("getValley_charge" + (i)).invoke(vo);
                                break;
                        }
                        if (null == invoke || Double.valueOf(invoke.toString()) == 0) {
                            continue;
                        }
                        BigDecimal sharp_peak_charge = new BigDecimal(invoke.toString());
                        AccountingStrategyDetailOrderVo vo1 = new AccountingStrategyDetailOrderVo();
                        BeanUtils.copyProperties(strategyDetail, vo1);
                        vo1.setChargingCapacity(sharp_peak_charge);
                        lists.add(0, vo1);
                    }
                    //第二天的
                    //开始通过计费策略遍历解析每个时段的费用明细
                    for (int i = 0; i < accountingStrategyDetailOrderList.size(); i++) {
                        AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderList.get(i);
                        long time = sdfs.parse(end_time.split(" ")[0] + " " + strategyDetail.getStartTime() + ":00").getTime();
                        if (time > end) {
                            break;
                        }
                        //阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)
                        Object invoke = null;
                        switch (strategyDetail.getType()) {
                            case 1:
                                //充电度数
                                invoke = clazz.getMethod("getSpike_charge" + (i + 1)).invoke(vo);
                                break;
                            case 2:
                                //充电度数
                                invoke = clazz.getMethod("getPeak_charge" + (i + 1)).invoke(vo);
                                break;
                            case 3:
                                //充电度数
                                invoke = clazz.getMethod("getFlat_charge" + (i + 1)).invoke(vo);
                                break;
                            case 4:
                                //充电度数
                                invoke = clazz.getMethod("getValley_charge" + (i + 1)).invoke(vo);
                                break;
                        }
                        if (null == invoke || Double.valueOf(invoke.toString()) == 0) {
                            continue;
                        }
                        BigDecimal sharp_peak_charge = new BigDecimal(invoke.toString());
                        AccountingStrategyDetailOrderVo vo1 = new AccountingStrategyDetailOrderVo();
                        BeanUtils.copyProperties(strategyDetail, vo1);
                        vo1.setChargingCapacity(sharp_peak_charge);
                        lists.add(vo1);
                    }
                } else {
                    for (int i = 0; i < accountingStrategyDetailOrderList.size(); i++) {
                        Class<? extends TransactionRecordMessageVO> clazz = vo.getClass();
                        AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderList.get(i);
                        //阶段(1=尖阶段,2=峰阶段,3=平阶段,4=谷阶段)
                        Object invoke = null;
                        switch (strategyDetail.getType()) {
                            case 1:
                                //充电度数
                                invoke = clazz.getMethod("getSpike_charge" + (i + 1)).invoke(vo);
                                break;
                            case 2:
                                //充电度数
                                invoke = clazz.getMethod("getPeak_charge" + (i + 1)).invoke(vo);
                                break;
                            case 3:
                                //充电度数
                                invoke = clazz.getMethod("getFlat_charge" + (i + 1)).invoke(vo);
                                break;
                            case 4:
                                //充电度数
                                invoke = clazz.getMethod("getValley_charge" + (i + 1)).invoke(vo);
                                break;
                        }
                        if (null == invoke || Double.valueOf(invoke.toString()) == 0) {
                            continue;
                        }
                        BigDecimal sharp_peak_charge = new BigDecimal(invoke.toString());
                        AccountingStrategyDetailOrderVo vo1 = new AccountingStrategyDetailOrderVo();
                        BeanUtils.copyProperties(strategyDetail, vo1);
                        vo1.setChargingCapacity(sharp_peak_charge);
                        lists.add(vo1);
                    }
                }
                //开始处理明细
                for (int i = 0; i < lists.size(); i++) {
                    AccountingStrategyDetailOrderVo strategyDetail = lists.get(i);
                    BigDecimal sharp_peak_charge = strategyDetail.getChargingCapacity();
                    TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy();
                    chargingOrderAccountingStrategy.setChargingOrderId(chargingOrder.getId());
                    chargingOrderAccountingStrategy.setAccountingStrategyDetailId(strategyDetail.getId());
                    chargingOrderAccountingStrategy.setType(strategyDetail.getType());
                    chargingOrderAccountingStrategy.setElectrovalence(strategyDetail.getElectrovalence());
                    chargingOrderAccountingStrategy.setServiceCharge(strategyDetail.getServiceCharge());
                    chargingOrderAccountingStrategy.setCostServiceCharge(strategyDetail.getCostServiceCharge());
                    if (i == 0) {
                        String time = vo.getStart_time().split(" ")[1];
                        chargingOrderAccountingStrategy.setStartTime(time.substring(0, time.lastIndexOf(":")));
                    } else {
                        chargingOrderAccountingStrategy.setStartTime(strategyDetail.getStartTime());
                    }
                    if (i == lists.size() - 1) {
                        String time = vo.getEnd_time().split(" ")[1];
                        chargingOrderAccountingStrategy.setEndTime(time.substring(0, time.lastIndexOf(":")));
                    } else {
                        chargingOrderAccountingStrategy.setEndTime(strategyDetail.getEndTime());
                    }
                    //已充电总度数
                    BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(sharp_peak_charge);
                    BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(sharp_peak_charge);
                    BigDecimal serviceCharge = originalServicePrice;
                    BigDecimal vipDiscountAmount = BigDecimal.ZERO;
                    //计算优惠金额
                    if (null != chargingOrder.getVipDiscount()) {
                        //0.58折
                        vipDiscountAmount = serviceCharge.multiply(new BigDecimal(1).subtract(chargingOrder.getVipDiscount()));
                        serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount());
                    }
                    chargingOrderAccountingStrategy.setChargingCapacity(sharp_peak_charge);
                    chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc.setScale(4, RoundingMode.HALF_EVEN));
                    chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge.setScale(4, RoundingMode.HALF_EVEN));
                    chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice.setScale(4, RoundingMode.HALF_EVEN));
                    chargingOrderAccountingStrategy.setVipDiscountAmount(vipDiscountAmount.setScale(4, RoundingMode.HALF_EVEN));
                    chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now());
                    chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy);
                    //电费
                    periodElectricPrice_total = periodElectricPrice_total.add(electrovalenc);
                    //服务费(含折扣)
                    serviceCharge_total = serviceCharge_total.add(serviceCharge);
                    //服务费(不含折扣)
                    periodServicePrice_total = periodServicePrice_total.add(originalServicePrice);
                    //会员折扣优惠金额
                    vipDiscountAmount_total = vipDiscountAmount_total.add(vipDiscountAmount);
                    //原始总金额(不含折扣)
                    total = total.add(electrovalenc.add(originalServicePrice));
                }
                BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue());
                //原金额
                BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
                //支付金额
                BigDecimal payAmount = periodElectricPrice_total.add(serviceCharge_total);
                //退款金额=充值金额-实际支付金额
                BigDecimal refundAmount = rechargeAmount.subtract(payAmount);
                UploadRealTimeMonitoringData uploadRealTimeMonitoringData = uploadRealTimeMonitoringDataService.getLastDataById(chargingOrder.getCode());
                if (null != uploadRealTimeMonitoringData && null == chargingOrder.getEndMode()) {
                    Integer soc = uploadRealTimeMonitoringData.getSoc();
                    if (soc >= 98) {
                        chargingOrder.setEndMode(2);
                    } else if (null != chargingOrder.getResidualAmount() && chargingOrder.getResidualAmount().compareTo(new BigDecimal(1)) <= 0) {
                        chargingOrder.setEndMode(3);
                    } else {
                        chargingOrder.setEndMode(1);
                    }
                }
                chargingOrder.setResidualAmount(rechargeAmount.subtract(total).setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setStartTime(LocalDateTime.parse(vo.getStart_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS")));
                chargingOrder.setEndTime(LocalDateTime.parse(vo.getEnd_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS")));
                chargingOrder.setStatus(5);
                chargingOrder.setOrderAmount(orderAmount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setElectrovalence(periodElectricPrice_total.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setChargingCapacity(vo.getTotal_electricity());
                chargingOrder.setElectricity(vo.getTotal_electricity());
                chargingOrder.setVipDiscountAmount(vipDiscountAmount_total);
                if (vipDiscountAmount_total.compareTo(BigDecimal.ZERO) == 0) {
                    chargingOrder.setVipDiscount(BigDecimal.valueOf(1));
                }
                //计算优惠券
                BigDecimal couponDiscount = BigDecimal.ZERO;
                if (null != chargingOrder.getAppCouponId()) {
                    //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。
                    TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData();
                    String couponJson = appCoupon.getCouponJson();
                    TCoupon tCoupon = JSON.parseObject(couponJson, TCoupon.class);
                    Integer preferentialMode = tCoupon.getPreferentialMode();
                    if (1 == preferentialMode) {
                        //满减
                        if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
                            BigDecimal couponDiscountAmount = tCoupon.getDiscountAmount();
                            //如果优惠金额大于服务费金额,以服务费作为最大限制
                            if (serviceCharge_total.compareTo(couponDiscountAmount) < 0) {
                                couponDiscount = serviceCharge_total;
                                serviceCharge_total = BigDecimal.ZERO;
                            } else {
                                couponDiscount = couponDiscountAmount;
                            }
                            appCoupon.setStatus(2);
                            appCouponClient.updateAppCoupon(appCoupon);
                        } else {
                            appCouponClient.refund(chargingOrder.getAppCouponId().toString());
                            chargingOrder.setAppCouponId(null);
                            chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
                        }
                    }
                    if (2 == preferentialMode) {
                        //抵扣
                        if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
                            //折扣金额
                            BigDecimal divide = payAmount.multiply(new BigDecimal(10).subtract(tCoupon.getDiscount())).divide(new BigDecimal(10));
                            divide = divide.compareTo(tCoupon.getMaximumDiscountAmount()) > 0 ? tCoupon.getMaximumDiscountAmount() : divide;
                            //如果优惠金额大于服务费金额,以服务费作为最大限制
                            if (serviceCharge_total.compareTo(divide) < 0) {
                                couponDiscount = serviceCharge_total;
                                serviceCharge_total = BigDecimal.ZERO;
                            } else {
                                couponDiscount = divide;
                            }
                            appCoupon.setStatus(2);
                            appCouponClient.updateAppCoupon(appCoupon);
                        } else {
                            chargingOrder.setAppCouponId(null);
                            chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
                            appCouponClient.refund(chargingOrder.getAppCouponId().toString());
                        }
                    }
                }
                //优惠券优惠金额
                couponDiscount = couponDiscount.setScale(4, RoundingMode.HALF_EVEN);
                //退款金额+优惠券
                refundAmount = refundAmount.add(couponDiscount);
                //实际支付金额-优惠券
                payAmount = payAmount.subtract(couponDiscount);
                if (serviceCharge_total.compareTo(BigDecimal.ZERO) > 0) {
                    serviceCharge_total = serviceCharge_total.subtract(couponDiscount);
                }
                chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setPaymentAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setRefundAmount(refundAmount.setScale(2, RoundingMode.HALF_EVEN));
                chargingOrder.setRefundStatus(1);
                UploadRealTimeMonitoringData asc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "asc");
                UploadRealTimeMonitoringData desc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "desc");
                if(null != asc){
                    chargingOrder.setStartSoc(new BigDecimal(asc.getSoc()));
                }
                if(null != desc){
                    chargingOrder.setEndSoc(new BigDecimal(desc.getSoc()));
                }
                this.updateById(chargingOrder);
            }else{
                List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
                if(!dataList.isEmpty()) {
                    //获取当前订单的计费规则,然后分段计算总的度数和充电金额
                    List<AccountingStrategyDetailOrder> detailOrders = accountingStrategyDetailOrderService.list(new LambdaQueryWrapper<AccountingStrategyDetailOrder>()
                            .eq(AccountingStrategyDetailOrder::getChargingOrderId, chargingOrder.getId()).last(" order by start_time"));
                    detailOrders.get(detailOrders.size() - 1).setEndTime("23:59");
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
                    //开始解析每个时段的充电度数
                    BigDecimal decimal = BigDecimal.ZERO;
                    //如果使用优惠券需要判断优惠券是否满足使用条件
                    //退款金额=优惠券金额+剩余充电金额
                    BigDecimal periodElectricPrice_total = BigDecimal.ZERO;
                    BigDecimal periodServicePrice_total = BigDecimal.ZERO;
                    BigDecimal vipDiscountAmount_total = BigDecimal.ZERO;
                    BigDecimal serviceCharge_total = BigDecimal.ZERO;
                    BigDecimal total = BigDecimal.ZERO;
                    //判断实时数据是否跨天
                    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
                    Date end_time = dataList.get(0).getCreate_time();
                    String end = sdf2.format(end_time);
                    Date start_time = dataList.get(dataList.size() - 1).getCreate_time();
                    String start = sdf2.format(start_time);
                    if (!end.equals(start)) {
                        List<AccountingStrategyDetailOrder> list = detailOrders.stream().map(s -> {
                            AccountingStrategyDetailOrder accountingStrategyDetailOrder = new AccountingStrategyDetailOrder();
                            BeanUtils.copyProperties(s, accountingStrategyDetailOrder);
                            return accountingStrategyDetailOrder;
                        }).collect(Collectors.toList());
                        for (AccountingStrategyDetailOrder detailOrder : detailOrders) {
                            detailOrder.setStartTime(start + " " + detailOrder.getStartTime());
                            detailOrder.setEndTime(start + " " + detailOrder.getEndTime());
                        }
                        for (AccountingStrategyDetailOrder detailOrder : list) {
                            detailOrder.setStartTime(end + " " + detailOrder.getStartTime());
                            detailOrder.setEndTime(end + " " + detailOrder.getEndTime());
                        }
                        detailOrders.addAll(list);
                    } else {
                        for (AccountingStrategyDetailOrder detailOrder : detailOrders) {
                            detailOrder.setStartTime(start + " " + detailOrder.getStartTime());
                            detailOrder.setEndTime(start + " " + detailOrder.getEndTime());
                        }
                    }
                    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmm");
                    List<TChargingOrderAccountingStrategy> list = new ArrayList<>();
                    for (AccountingStrategyDetailOrder detailOrder : detailOrders) {
                        long startTime = Long.parseLong(detailOrder.getStartTime().replaceAll("-", "").replaceAll(" ", "").replaceAll(":", ""));
                        long endTime = Long.parseLong(detailOrder.getEndTime().replaceAll("-", "").replaceAll(" ", "").replaceAll(":", ""));
                        List<UploadRealTimeMonitoringData> collect = dataList.stream().filter(s -> Long.parseLong(sdf1.format(s.getCreate_time())) > startTime && Long.parseLong(sdf1.format(s.getCreate_time())) <= endTime).collect(Collectors.toList());
                        if (!collect.isEmpty()) {
                            //升序排序
                            collect.sort(new Comparator<UploadRealTimeMonitoringData>() {
                                @Override
                                public int compare(UploadRealTimeMonitoringData o1, UploadRealTimeMonitoringData o2) {
                                    return o1.getCharging_degree().compareTo(o2.getCharging_degree());
                                }
                            });
                            UploadRealTimeMonitoringData uploadRealTimeMonitoringData = collect.get(collect.size() - 1);
                            BigDecimal chargingDegree = uploadRealTimeMonitoringData.getCharging_degree();
                            BigDecimal subtract = chargingDegree.subtract(decimal);
                            decimal = chargingDegree;
                            if (subtract.compareTo(BigDecimal.ZERO) > 0) {
                                //组装充电明细数据
                                TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy();
                                chargingOrderAccountingStrategy.setChargingOrderId(chargingOrder.getId());
                                chargingOrderAccountingStrategy.setAccountingStrategyDetailId(detailOrder.getId());
                                chargingOrderAccountingStrategy.setType(detailOrder.getType());
                                chargingOrderAccountingStrategy.setElectrovalence(detailOrder.getElectrovalence());
                                chargingOrderAccountingStrategy.setServiceCharge(detailOrder.getServiceCharge());
                                chargingOrderAccountingStrategy.setCostServiceCharge(detailOrder.getCostServiceCharge());
                                chargingOrderAccountingStrategy.setChargingCapacity(subtract);
                                chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now());
                                if (list.size() == 0) {
                                    String time = sdf.format(collect.get(0).getCreate_time());
                                    chargingOrderAccountingStrategy.setStartTime(time);
                                } else {
                                    chargingOrderAccountingStrategy.setStartTime(detailOrder.getStartTime().split(" ")[1]);
                                }
                                chargingOrderAccountingStrategy.setEndTime(detailOrder.getEndTime().split(" ")[1]);
                                //已充电总度数
                                BigDecimal electrovalenc = detailOrder.getElectrovalence().multiply(subtract);
                                BigDecimal originalServicePrice = detailOrder.getServiceCharge().multiply(subtract);
                                BigDecimal serviceCharge = originalServicePrice;
                                BigDecimal vipDiscountAmount = BigDecimal.ZERO;
                                //计算优惠金额
                                if (null != chargingOrder.getVipDiscount()) {
                                    //0.58折
                                    vipDiscountAmount = serviceCharge.multiply(new BigDecimal(1).subtract(chargingOrder.getVipDiscount()));
                                    serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount());
                                }
                                chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc.setScale(4, RoundingMode.HALF_EVEN));
                                chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge.setScale(4, RoundingMode.HALF_EVEN));
                                chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice.setScale(4, RoundingMode.HALF_EVEN));
                                chargingOrderAccountingStrategy.setVipDiscountAmount(vipDiscountAmount.setScale(4, RoundingMode.HALF_EVEN));
                                chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now());
                                list.add(chargingOrderAccountingStrategy);
                                //电费
                                periodElectricPrice_total = periodElectricPrice_total.add(electrovalenc);
                                //服务费(含折扣)
                                serviceCharge_total = serviceCharge_total.add(serviceCharge);
                                //服务费(不含折扣)
                                periodServicePrice_total = periodServicePrice_total.add(originalServicePrice);
                                //会员折扣优惠金额
                                vipDiscountAmount_total = vipDiscountAmount_total.add(vipDiscountAmount);
                                //原始总金额(不含折扣)
                                total = total.add(electrovalenc.add(originalServicePrice));
                            }
                        }
                    }
                    list.get(list.size() - 1).setEndTime(sdf.format(dataList.get(0).getCreate_time()));
                    chargingOrderAccountingStrategyService.saveBatch(list);
                    BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue());
                    //原金额
                    BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
                    //支付金额
                    BigDecimal payAmount = periodElectricPrice_total.add(serviceCharge_total);
                    //退款金额=充值金额-实际支付金额
                    BigDecimal refundAmount = rechargeAmount.subtract(payAmount);
                    UploadRealTimeMonitoringData uploadRealTimeMonitoringData = uploadRealTimeMonitoringDataService.getLastDataById(chargingOrder.getCode());
                    if (null != uploadRealTimeMonitoringData && null == chargingOrder.getEndMode()) {
                        Integer soc = uploadRealTimeMonitoringData.getSoc();
                        if (soc >= 98) {
                            chargingOrder.setEndMode(2);
                        } else if (null != chargingOrder.getResidualAmount() && chargingOrder.getResidualAmount().compareTo(new BigDecimal(1)) <= 0) {
                            chargingOrder.setEndMode(3);
                        } else {
                            chargingOrder.setEndMode(1);
                        }
                    }
                    chargingOrder.setResidualAmount(rechargeAmount.subtract(total).setScale(2, RoundingMode.HALF_EVEN));
                    chargingOrder.setStartTime(list.get(0).getCreateTime());
                    chargingOrder.setEndTime(list.get(list.size() - 1).getCreateTime());
                    chargingOrder.setStatus(5);
                    chargingOrder.setOrderAmount(orderAmount.setScale(2, RoundingMode.HALF_EVEN));
                    chargingOrder.setElectrovalence(periodElectricPrice_total.setScale(2, RoundingMode.HALF_EVEN));
                    chargingOrder.setChargingCapacity(list.get(list.size() - 1).getChargingCapacity());
                    chargingOrder.setElectricity(list.get(list.size() - 1).getChargingCapacity());
                    chargingOrder.setVipDiscountAmount(vipDiscountAmount_total);
                    if (vipDiscountAmount_total.compareTo(BigDecimal.ZERO) == 0) {
                        chargingOrder.setVipDiscount(BigDecimal.valueOf(1));
                    }
                    //计算优惠券
                    BigDecimal couponDiscount = BigDecimal.ZERO;
                    if (null != chargingOrder.getAppCouponId()) {
                        //判断实际充电金额是否满足优惠券使用条件,如果不满足则不适用优惠券。
                        TAppCoupon appCoupon = appCouponClient.getAppCouponById(chargingOrder.getAppCouponId()).getData();
                        String couponJson = appCoupon.getCouponJson();
                        TCoupon tCoupon = com.alibaba.fastjson2.JSON.parseObject(couponJson, TCoupon.class);
                        Integer preferentialMode = tCoupon.getPreferentialMode();
                        if (1 == preferentialMode) {
                            //满减
                            if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
                                BigDecimal couponDiscountAmount = tCoupon.getDiscountAmount();
                                //如果优惠金额大于服务费金额,以服务费作为最大限制
                                if (serviceCharge_total.compareTo(couponDiscountAmount) < 0) {
                                    couponDiscount = serviceCharge_total;
                                    serviceCharge_total = BigDecimal.ZERO;
                                } else {
                                    couponDiscount = couponDiscountAmount;
                                }
                                appCoupon.setStatus(2);
                                appCouponClient.updateAppCoupon(appCoupon);
                            } else {
                                appCouponClient.refund(chargingOrder.getAppCouponId().toString());
                                chargingOrder.setAppCouponId(null);
                                chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
                            }
                        }
                        if (2 == preferentialMode) {
                            //抵扣
                            if (payAmount.compareTo(tCoupon.getMeetTheConditions()) >= 0) {
                                //折扣金额
                                BigDecimal divide = payAmount.multiply(new BigDecimal(10).subtract(tCoupon.getDiscount())).divide(new BigDecimal(10));
                                divide = divide.compareTo(tCoupon.getMaximumDiscountAmount()) > 0 ? tCoupon.getMaximumDiscountAmount() : divide;
                                //如果优惠金额大于服务费金额,以服务费作为最大限制
                                if (serviceCharge_total.compareTo(divide) < 0) {
                                    couponDiscount = serviceCharge_total;
                                    serviceCharge_total = BigDecimal.ZERO;
                                } else {
                                    couponDiscount = divide;
                                }
                                appCoupon.setStatus(2);
                                appCouponClient.updateAppCoupon(appCoupon);
                            } else {
                                chargingOrder.setAppCouponId(null);
                                chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
                                appCouponClient.refund(chargingOrder.getAppCouponId().toString());
                            }
                        }
                    }
                    //优惠券优惠金额
                    couponDiscount = couponDiscount.setScale(4, RoundingMode.HALF_EVEN);
                    //退款金额+优惠券
                    refundAmount = refundAmount.add(couponDiscount);
                    //实际支付金额-优惠券
                    payAmount = payAmount.subtract(couponDiscount);
                    if (serviceCharge_total.compareTo(BigDecimal.ZERO) > 0) {
                        serviceCharge_total = serviceCharge_total.subtract(couponDiscount);
                    }
                    chargingOrder.setCouponDiscountAmount(couponDiscount.setScale(2, RoundingMode.HALF_EVEN));
                    chargingOrder.setServiceCharge(serviceCharge_total.setScale(2, RoundingMode.HALF_EVEN));
                    chargingOrder.setPaymentAmount(payAmount.setScale(2, RoundingMode.HALF_EVEN));
                    chargingOrder.setRefundAmount(refundAmount.setScale(2, RoundingMode.HALF_EVEN));
                    chargingOrder.setRefundStatus(1);
                    UploadRealTimeMonitoringData asc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "asc");
                    UploadRealTimeMonitoringData desc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode(), "desc");
                    if (null != asc) {
                        chargingOrder.setStartSoc(new BigDecimal(asc.getSoc()));
                    }
                    if (null != desc) {
                        chargingOrder.setEndSoc(new BigDecimal(desc.getSoc()));
                    }
                    chargingOrderService.updateById(chargingOrder);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}