“mitao”
2026-05-07 2182fb521701539d4327d18105c7e5b6e9fd42f6
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -63,7 +63,9 @@
import com.ruoyi.other.api.domain.*;
import com.ruoyi.order.vo.ChargingOrderListInfoVO;
import com.ruoyi.other.api.domain.TVip;
import com.ruoyi.other.api.dto.ExchangeCodeConsumeDTO;
import com.ruoyi.other.api.feignClient.*;
import com.ruoyi.other.api.vo.ExchangeCodeConsumeResultVO;
import com.ruoyi.payment.api.feignClient.AliPaymentClient;
import com.ruoyi.payment.api.feignClient.H5AliPaymentClient;
import com.ruoyi.payment.api.feignClient.WxPaymentClient;
@@ -73,8 +75,6 @@
import com.ruoyi.payment.api.vo.*;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
@@ -83,6 +83,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
@@ -202,6 +203,8 @@
   
   @Resource
   private VipClient vipClient;
   @Resource
   private OtherClient otherClient;
   
   @Resource
   private UserTagClient userTagClient;
@@ -331,7 +334,7 @@
      List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
      if (null != dataList) {
         //在MongoDB中获取数据
         SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
      SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
         List<UploadRealTimeMonitoringData> dataLists = new ArrayList<>();
         String t = "";
         for (UploadRealTimeMonitoringData uploadRealTimeMonitoringData : dataList) {
@@ -418,10 +421,95 @@
    * @param addChargingOrder
    * @return
    */
    private boolean isBalancePayMode(Integer payMethod) {
        return payMethod != null && (payMethod == 1 || payMethod == 2);
    }
    private BigDecimal money(BigDecimal amount) {
        return amount == null ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : amount.setScale(2, RoundingMode.HALF_UP);
    }
    private void changeUserBalance(Long userId, BigDecimal delta) {
        if (userId == null || delta == null || delta.compareTo(BigDecimal.ZERO) == 0) {
            return;
        }
        TAppUser appUser = appUserClient.getUserById(userId).getData();
        if (appUser == null) {
            throw new RuntimeException("用户不存在");
        }
        appUser.setBalance(money(appUser.getBalance()).add(delta).setScale(2, RoundingMode.HALF_UP));
        appUserClient.updateAppUser(appUser);
    }
    private void recordBalanceConsume(TChargingOrder chargingOrder, BigDecimal consumeAmount) {
        if (chargingOrder == null || chargingOrder.getAppUserId() == null || chargingOrder.getId() == null
                || consumeAmount == null || consumeAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        ExchangeCodeConsumeDTO consumeDTO = new ExchangeCodeConsumeDTO();
        consumeDTO.setUserId(chargingOrder.getAppUserId());
        consumeDTO.setOrderId(chargingOrder.getId());
        consumeDTO.setAmount(consumeAmount);
        R<ExchangeCodeConsumeResultVO> result = otherClient.consumeExchangeCodeBalance(consumeDTO);
        if (result == null || result.getCode() != 200) {
            throw new RuntimeException("扣减兑换码余额失败");
        }
    }
    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) {
            return;
        }
        ExchangeCodeConsumeDTO refundDTO = new ExchangeCodeConsumeDTO();
        refundDTO.setUserId(chargingOrder.getAppUserId());
        refundDTO.setOrderId(chargingOrder.getId());
        refundDTO.setAmount(refundAmount);
        refundDTO.setRefundNo(refundNo);
        R<ExchangeCodeConsumeResultVO> result = otherClient.refundExchangeCodeBalance(refundDTO);
        if (result == null || result.getCode() != 200) {
            throw new RuntimeException("退还兑换码余额失败");
        }
    }
    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));
        chargingOrder.setThirdRefundAmount(money(chargingOrder.getThirdRefundAmount()).add(thirdRefundAmount));
        this.baseMapper.updateById(chargingOrder);
        refund.setRefundStatus(2);
        chargingOrderRefundService.save(refund);
        if (balanceRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
            changeUserBalance(chargingOrder.getAppUserId(), balanceRefundAmount);
            recordBalanceRefund(chargingOrder, balanceRefundAmount, refund.getRefundCode());
        }
    }
   @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());
      BigDecimal userBalance = money(appUser.getBalance());
      BigDecimal balancePayAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
      BigDecimal thirdPayAmount = rechargeAmount;
      if (payMethod == 2 && userBalance.compareTo(rechargeAmount) >= 0) {
         payMethod = 1;
         addChargingOrder.setPayMethod(1);
      }
      if (isBalancePayMode(payMethod)) {
         addChargingOrder.setAppUserCouponId(null);
         if (payMethod == 1 && userBalance.compareTo(rechargeAmount) < 0) {
            return AjaxResult.error("余额不足,请选择组合支付或第三方支付");
         }
         balancePayAmount = payMethod == 1 ? rechargeAmount : userBalance.min(rechargeAmount).setScale(2, RoundingMode.HALF_UP);
         thirdPayAmount = rechargeAmount.subtract(balancePayAmount).setScale(2, RoundingMode.HALF_UP);
      }
      //查询待支付状态的订单,没有支付则删除订单
      List<TChargingOrder> list = this.list(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, userId)
            .eq(TChargingOrder::getRechargePaymentStatus, 1).eq(TChargingOrder::getDelFlag, 0));
@@ -539,7 +627,12 @@
      chargingOrder.setChargingGunId(addChargingOrder.getId());
      chargingOrder.setRechargePaymentType(addChargingOrder.getPaymentType());
      chargingOrder.setRechargePaymentStatus(1);
      chargingOrder.setRechargeAmount(addChargingOrder.getPaymentAmount());
      chargingOrder.setPayMethod(payMethod);
      chargingOrder.setBalancePayAmount(balancePayAmount);
      chargingOrder.setThirdPayAmount(thirdPayAmount);
      chargingOrder.setBalanceRefundAmount(BigDecimal.ZERO);
      chargingOrder.setThirdRefundAmount(BigDecimal.ZERO);
      chargingOrder.setRechargeAmount(rechargeAmount);
      chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId());
      chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
      chargingOrder.setOrderSource(1);
@@ -554,7 +647,7 @@
      TAccountingStrategy accountingStrategy = accountingStrategyClient.getAccountingStrategyById(accountingStrategyId).getData();
      
      //直营站点才可以享受会员折扣
      if (null != appUser.getVipId() && 1 == site.getBusinessCategory()) {
      if (!isBalancePayMode(payMethod) && null != appUser.getVipId() && 1 == site.getBusinessCategory()) {
         TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
         BigDecimal discount = null;
         if (1 == vip.getType()) {
@@ -594,12 +687,19 @@
      }
      accountingStrategyDetailOrderService.saveBatch(list1);
      
      if (thirdPayAmount.compareTo(BigDecimal.ZERO) == 0 && balancePayAmount.compareTo(BigDecimal.ZERO) > 0) {
         changeUserBalance(userId, balancePayAmount.negate());
         recordBalanceConsume(chargingOrder, balancePayAmount);
      }
      if (thirdPayAmount.compareTo(BigDecimal.ZERO) == 0) {
         return chargingOrderCallback(addChargingOrder.getPaymentType(), chargingOrder.getCode(), "BALANCE", null);
      }
      //会员优惠折扣将其计入增加充电时长(增加总充电金额)
      //如果充电总金额未使用完,则需要退回费用=(原金额/总金额)*(总金额-实际充电金额)
      if (1 == addChargingOrder.getPaymentType()) {
         PaymentOrder paymentOrder = new PaymentOrder();
         paymentOrder.setCode(chargingOrder.getCode());
         paymentOrder.setAmount(addChargingOrder.getPaymentAmount());
         paymentOrder.setAmount(thirdPayAmount);
         paymentOrder.setOpenId(appUser.getWxOpenid());
         paymentOrder.setDescription("充电充值");
         paymentOrder.setNotifyUrl("/payment/wx/pay/notify");
@@ -609,7 +709,7 @@
      if (2 == addChargingOrder.getPaymentType()) {
         AliPaymentReq req = new AliPaymentReq();
         req.setOutTradeNo(chargingOrder.getCode());
         req.setTotalAmount(addChargingOrder.getPaymentAmount().toString());
         req.setTotalAmount(thirdPayAmount.toString());
         req.setSubject("充电充值");
         req.setBuyerOpenId(appUser.getAliOpenid());
         req.setBody("充电充值");
@@ -622,7 +722,7 @@
      if (3 == addChargingOrder.getPaymentType()) {
         AliPaymentReq req = new AliPaymentReq();
         req.setOutTradeNo(chargingOrder.getCode());
         req.setTotalAmount(addChargingOrder.getPaymentAmount().toString());
         req.setTotalAmount(thirdPayAmount.toString());
         req.setSubject("充电充值");
         req.setBuyerOpenId(appUser.getAliOpenid());
         req.setBody("充电充值");
@@ -646,11 +746,22 @@
    * @param attach         附加数据
    * @return
    */
    @Transactional
   @Override
   public AjaxResult chargingOrderCallback(Integer paymentType, String out_trade_no, String transaction_id, String attach) {
      TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, out_trade_no));
      if (chargingOrder.getRechargePaymentStatus() == 2) {
         return AjaxResult.success();
      }
      if (isBalancePayMode(chargingOrder.getPayMethod())
            && money(chargingOrder.getThirdPayAmount()).compareTo(BigDecimal.ZERO) > 0
            && money(chargingOrder.getBalancePayAmount()).compareTo(BigDecimal.ZERO) > 0) {
         TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
         if (money(appUser.getBalance()).compareTo(money(chargingOrder.getBalancePayAmount())) < 0) {
            throw new RuntimeException("余额不足,支付回调处理失败");
         }
         changeUserBalance(chargingOrder.getAppUserId(), money(chargingOrder.getBalancePayAmount()).negate());
         recordBalanceConsume(chargingOrder, money(chargingOrder.getBalancePayAmount()));
      }
      chargingOrder.setRechargePaymentStatus(2);
      chargingOrder.setRechargeSerialNumber(transaction_id);
@@ -785,15 +896,15 @@
      });
//      //异步线程检测远程启动的应答结果。如果失败,则需要全额退款
//      Long id = chargingOrder.getId();
//      //执行5分钟的定时任务检测
//      ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
//      scheduler.scheduleAtFixedRate(()->{
//         if(timingDetection(id)){
//            scheduler.shutdown();
//         }
//      }, 5, 1, TimeUnit.SECONDS);
      //异步线程检测远程启动的应答结果。如果失败,则需要全额退款
      Long id = chargingOrder.getId();
      //执行10分钟的定时任务检测
      ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
      scheduler.scheduleAtFixedRate(()->{
         if(timingDetection(id)){
            scheduler.shutdown();
         }
      }, 10, 1, TimeUnit.SECONDS);
      return AjaxResult.success();
   }
   
@@ -814,14 +925,14 @@
      List<PlatformStartChargingReply> data = platformStartChargingReplyService.getPlatformStartChargingReply(code);
      log.info(code + ":-------------------开始检查调起充电结果-------------------" + data.toString());
      Site site = siteClient.getSiteByIds(Arrays.asList(chargingOrder.getSiteId())).getData().get(0);
      if (data.size() != 0) {
      if (!data.isEmpty()) {
         PlatformStartChargingReply platformStartChargingReply = data.get(1);
         Integer startup_result = platformStartChargingReply.getStartup_result();
         Integer failure_cause = platformStartChargingReply.getFailure_cause();
         Integer counter = counter_map.get(code);
         PreChargeCheck preChargeCheck1 = redisService.getCacheObject(key);
         //5分钟内还未插枪则取消充电,退回金额。
         if (failure_cause == 5 && (null == counter || counter < 1800)) {
         //15分钟内还未插枪则取消充电,退回金额。
         if (failure_cause == 5 && (null == counter || counter < 60 * 15)) {
            counter = (null == counter ? 0 : counter) + 1;
            counter_map.put(code, counter);
            //启动失败
@@ -837,27 +948,19 @@
            //启动失败
            preChargeCheck1.setStartupSuccess(3);
            preChargeCheck1.setFailureCause(failure_cause);
            chargingOrder.setStatus(2);
            chargingOrder.setEndMode(0);
            this.updateById(chargingOrder);
            //启动失败后取消订单,退款操作
            refund(code);
            chargingOrder.setStatus(-1);
            chargingOrder.setEndMode(0);
         } else {
            //启动成功
            preChargeCheck1.setStartupSuccess(2);
            chargingOrder.setStatus(3);
            chargingOrder.setStartTime(LocalDateTime.now());
            this.updateById(chargingOrder);
         }
         this.updateById(chargingOrder);
         if (chargingOrder.getStatus() == 3) {
            //推送监管平台订单状态
            new Thread(() -> {
               ChargingOrderVo chargingOrderVo = new ChargingOrderVo();
               BeanUtils.copyProperties(chargingOrder, chargingOrderVo);
               chargingMessageClient.pushOrderStatus(chargingOrderVo);
            }).start();
         }
         redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
         //推送三方平台订单状态
         if (2 == chargingOrder.getOrderSource() && 1 == site.getIsOpenSynchronization()) {
@@ -865,6 +968,12 @@
         }
         ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
         threadPoolExecutor.execute(()->{
            if (chargingOrder.getStatus() == 3) {
               //推送监管平台订单状态
               ChargingOrderVo chargingOrderVo = new ChargingOrderVo();
               BeanUtils.copyProperties(chargingOrder, chargingOrderVo);
               chargingMessageClient.pushOrderStatus(chargingOrderVo);
            }
            //推送成都监管
            NotificationConnectorChargeStatusVo vo = new NotificationConnectorChargeStatusVo();
            vo.setOrderCode(chargingOrder.getCode());
@@ -873,47 +982,77 @@
         });
         return true;
      } else {
         Integer counter = boot_failed_map.get(code);
         log.info(code + ":-------------------未上传开启充电结果-------------------" + counter);
         PreChargeCheck preChargeCheck1 = redisService.getCacheObject(key);
         //5分钟内未启动成功,退回金额。
         if (null == counter || counter < 1800) {
            counter = (null == counter ? 0 : counter) + 1;
            boot_failed_map.put(code, counter);
            //启动失败
            preChargeCheck1.setStartupSuccess(1);
            preChargeCheck1.setFailureCause(0);
         UploadRealTimeMonitoringData uploadRealTimeMonitoringData = uploadRealTimeMonitoringDataService.getDataByOrderCode(code, "desc");
         if(null != uploadRealTimeMonitoringData){
            //启动成功
            preChargeCheck1.setStartupSuccess(2);
            chargingOrder.setStatus(3);
            chargingOrder.setStartTime(LocalDateTime.now());
            this.updateById(chargingOrder);
            redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
            return false;
            //推送三方平台订单状态
            if (2 == chargingOrder.getOrderSource() && 1 == site.getIsOpenSynchronization()) {
               tcecClient.notificationEquipChargeStatus(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
            }
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
            threadPoolExecutor.execute(()->{
               if (chargingOrder.getStatus() == 3) {
                  //推送监管平台订单状态
                  ChargingOrderVo chargingOrderVo = new ChargingOrderVo();
                  BeanUtils.copyProperties(chargingOrder, chargingOrderVo);
                  chargingMessageClient.pushOrderStatus(chargingOrderVo);
               }
               //推送成都监管
               NotificationConnectorChargeStatusVo vo = new NotificationConnectorChargeStatusVo();
               vo.setOrderCode(chargingOrder.getCode());
               vo.setChargingGunId(chargingOrder.getChargingGunId());
               chengDuJianGuanClient.notificationConnectorChargeStatus(vo);
            });
            return true;
         }else{
            Integer counter = boot_failed_map.get(code);
            log.info(code + ":-------------------未上传开启充电结果-------------------" + counter);
            //15分钟内未启动成功,退回金额。
            if (null == counter || counter < 60 * 15) {
               counter = (null == counter ? 0 : counter) + 1;
               boot_failed_map.put(code, counter);
               //启动失败
               preChargeCheck1.setStartupSuccess(1);
               preChargeCheck1.setFailureCause(0);
               redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
               return false;
            }
            //清除计时器中的无效数据
            boot_failed_map.remove(code);
            TChargingOrder order = new TChargingOrder();
            order.setId(id);
            order.setAppUserId(chargingOrder.getAppUserId());
            //启动失败
            preChargeCheck1.setStartupSuccess(3);
            preChargeCheck1.setFailureCause(0);
            order.setStatus(2);
            order.setEndMode(0);
            this.updateById(order);
            //启动失败后取消订单,退款操作
            refund(code);
            redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
            //推送三方平台订单状态
            if (2 == chargingOrder.getOrderSource() && 1 == site.getIsOpenSynchronization()) {
               tcecClient.notificationEquipChargeStatus(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
            }
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
            threadPoolExecutor.execute(()->{
               //推送成都监管
               NotificationConnectorChargeStatusVo vo = new NotificationConnectorChargeStatusVo();
               vo.setOrderCode(chargingOrder.getCode());
               vo.setChargingGunId(chargingOrder.getChargingGunId());
               chengDuJianGuanClient.notificationConnectorChargeStatus(vo);
            });
            return true;
         }
         //清除计时器中的无效数据
         boot_failed_map.remove(code);
         TChargingOrder order = new TChargingOrder();
         order.setId(id);
         order.setAppUserId(chargingOrder.getAppUserId());
         //启动失败
         preChargeCheck1.setStartupSuccess(3);
         preChargeCheck1.setFailureCause(0);
         //启动失败后取消订单,退款操作
         refund(code);
         order.setStatus(-1);
         order.setEndMode(0);
         this.updateById(order);
         redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
         //推送三方平台订单状态
         if (2 == chargingOrder.getOrderSource() && 1 == site.getIsOpenSynchronization()) {
            tcecClient.notificationEquipChargeStatus(chargingOrder.getStartChargeSeq(), chargingOrder.getOperatorId());
         }
         ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
         threadPoolExecutor.execute(()->{
            //推送成都监管
            NotificationConnectorChargeStatusVo vo = new NotificationConnectorChargeStatusVo();
            vo.setOrderCode(chargingOrder.getCode());
            vo.setChargingGunId(chargingOrder.getChargingGunId());
            chengDuJianGuanClient.notificationConnectorChargeStatus(vo);
         });
         return true;
      }
   }
   
@@ -963,15 +1102,17 @@
         //启动失败
         preChargeCheck1.setStartupSuccess(3);
         preChargeCheck1.setFailureCause(failure_cause);
         order.setStatus(2);
         order.setEndMode(0);
         this.updateById(order);
         //启动失败后取消订单,退款操作
         refund(code);
         order.setStatus(-1);
         order.setEndMode(0);
      } else {
         //启动成功
         preChargeCheck1.setStartupSuccess(2);
         order.setStatus(3);
         order.setStartTime(LocalDateTime.now());
         this.updateById(order);
         TChargingGun chargingGun = chargingGunClient.getChargingGunById(order.getChargingGunId()).getData();
         chargingGun.setStatus(4);
         chargingGunClient.updateChargingGunById(chargingGun);
@@ -981,7 +1122,6 @@
         }
      }
      redisService.setCacheObject("AQJC_" + order.getChargingGunId(), preChargeCheck1, 24L, TimeUnit.HOURS);
      this.updateById(order);
      
      if (3 == order.getStatus()) {
         //推送监管平台订单状态
@@ -1004,8 +1144,6 @@
            tcecClient.notificationStartChargeResult(result);
            tcecClient.notificationEquipChargeStatus(order.getStartChargeSeq(), order.getOperatorId());
         }
      }
   }
   
@@ -1014,127 +1152,168 @@
    *
    * @param code
    */
    @Transactional
   public void refund(String code) {
      log.info(code + ":-------------------充电启动失败,执行退款-------------------");
      TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code));
      if (chargingOrder.getOrderSource() == 1 && chargingOrder.getStatus() == 2) {
         Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
         BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
         //构建退款明细
         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(rechargeAmount);
         chargingOrderRefund.setRefundStatus(1);
         chargingOrderRefund.setPayType(rechargePaymentType);
         chargingOrderRefund.setRefundStatus(1);
         chargingOrderRefund.setCode(code);
         chargingOrderRefund.setRefundTitle("充电失败");
         chargingOrderRefund.setRefundContent("充电失败");
         chargingOrderRefund.setRefundReason("充电失败");
         chargingOrderRefund.setRefundRemark("全额退款");
         chargingOrderRefund.setRefundTotalAmount(rechargeAmount);
         chargingOrderRefund.setPayAmount(rechargeAmount);
         if (1 == rechargePaymentType) {
            WxPaymentRefundModel model = new WxPaymentRefundModel();
            model.setOut_trade_no(chargingOrder.getCode());
            model.setOut_refund_no(chargingOrderRefund.getRefundCode());
            model.setReason("充电失败,取消充电订单");
            model.setNotify_url("/payment/wx/refund/notify");
            WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
            amount.setRefund(rechargeAmount.multiply(new BigDecimal(100)).intValue());
            amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue());
            amount.setCurrency("CNY");
            model.setAmount(amount);
            R<Map<String, Object>> orderR = wxPaymentClient.refundOrderR(model);
            if (200 == orderR.getCode()) {
               chargingOrderRefundService.save(chargingOrderRefund);
               //手续费
               Map<String, Object> amount1 = (Map<String, Object>) orderR.getData().get("amount");
               Object refund_fee1 = amount1.get("refund_fee");
               BigDecimal refund_fee = new BigDecimal(null == refund_fee1 ? "0" : refund_fee1.toString()).divide(new BigDecimal(100));
               chargingOrderRefund.setRefundFee(refund_fee);
               chargingOrderRefundService.updateById(chargingOrderRefund);
               //回退会员折扣次数
               if (chargingOrder.getVipDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
                  TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                  GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
                  getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
                  getAppUserVipDetail.setVipId(appUser.getVipId());
                  TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
                  if (null != data) {
                     data.setChargeNum(data.getChargeNum() + 1);
                     appUserVipDetailClient.updateAppUserVipDetail(data);
                  }
               }
            }
         }
         if (2 == rechargePaymentType) {
            RefundReq dto = new RefundReq();
            dto.setOutTradeNo(chargingOrder.getCode());
            dto.setOutRequestNo(chargingOrderRefund.getCode());
            dto.setRefundAmount(rechargeAmount.toString());
            dto.setRefundReason("充电失败,取消充电订单");
            RefundResp resp = aliPaymentClient.refund(dto).getData();
            if (null != resp) {
               chargingOrderRefundService.save(chargingOrderRefund);
               //回退会员折扣次数
               if (chargingOrder.getVipDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
                  TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                  GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
                  getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
                  getAppUserVipDetail.setVipId(appUser.getVipId());
                  TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
                  if (null != data) {
                     data.setChargeNum(data.getChargeNum() + 1);
                     appUserVipDetailClient.updateAppUserVipDetail(data);
                  }
               }
               try {
                  Thread.sleep(1000);
               } catch (InterruptedException e) {
                  throw new RuntimeException(e);
               }
               chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
            }
         }
         if (3 == rechargePaymentType) {
            RefundReq dto = new RefundReq();
            dto.setOutTradeNo(chargingOrder.getRechargeSerialNumber());
            dto.setOutRequestNo(chargingOrderRefund.getCode());
            dto.setRefundAmount(rechargeAmount.toString());
            dto.setRefundReason("充电失败,取消充电订单");
            RefundResp resp = h5AliPaymentClient.refund(dto).getData();
            if (null != resp && "10000".equals(resp.getCode())) {
               chargingOrderRefundService.save(chargingOrderRefund);
               //回退会员折扣次数
               if (chargingOrder.getVipDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
                  TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                  GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
                  getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
                  getAppUserVipDetail.setVipId(appUser.getVipId());
                  TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
                  if (null != data) {
                     data.setChargeNum(data.getChargeNum() + 1);
                     appUserVipDetailClient.updateAppUserVipDetail(data);
                  }
               }
               try {
                  Thread.sleep(1000);
               } catch (InterruptedException e) {
                  throw new RuntimeException(e);
               }
               chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
            }
         }
      }
        RLock lock = redissonClient.getLock("REFUND_ORDER_LOCK:" + code);
        try {
            boolean tryLock = lock.tryLock(30, 30, TimeUnit.SECONDS);
            if(tryLock){
                log.info(code + ":-------------------充电启动失败,执行退款-------------------");
                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);
                    //构建退款明细
                    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.setBalanceRefundAmount(balanceRefundAmount);
                    chargingOrderRefund.setThirdRefundAmount(thirdRefundAmount);
                    chargingOrderRefund.setRefundStatus(1);
                    chargingOrderRefund.setPayType(rechargePaymentType);
                    chargingOrderRefund.setRefundStatus(1);
                    chargingOrderRefund.setCode(code);
                    chargingOrderRefund.setRefundTitle("充电失败");
                    chargingOrderRefund.setRefundContent("充电失败");
                    chargingOrderRefund.setRefundReason("充电失败");
                    chargingOrderRefund.setRefundRemark("全额退款");
                    chargingOrderRefund.setRefundTotalAmount(totalRefundAmount);
                    chargingOrderRefund.setPayAmount(rechargeAmount);
                    chargingOrder.setBalanceRefundAmount(balanceRefundAmount);
                    chargingOrder.setThirdRefundAmount(thirdRefundAmount);
                    chargingOrder.setRefundAmount(totalRefundAmount);
                    chargingOrder.setRefundStatus(thirdRefundAmount.compareTo(BigDecimal.ZERO) > 0 ? 1 : 2);
                    if (thirdRefundAmount.compareTo(BigDecimal.ZERO) == 0) {
                        if (balanceRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
                            changeUserBalance(chargingOrder.getAppUserId(), balanceRefundAmount);
                            recordBalanceRefund(chargingOrder, balanceRefundAmount, chargingOrderRefund.getRefundCode());
                        }
                        chargingOrderRefund.setRefundStatus(2);
                        chargingOrderRefund.setRefundSerialNumber("BALANCE");
                        chargingOrderRefund.setRefundTime(LocalDateTime.now());
                        chargingOrderRefundService.save(chargingOrderRefund);
                        this.updateById(chargingOrder);
                        return;
                    }
                    this.updateById(chargingOrder);
                    if (thirdRefundAmount.compareTo(BigDecimal.ZERO) > 0 && 1 == rechargePaymentType) {
                        WxPaymentRefundModel model = new WxPaymentRefundModel();
                        model.setOut_trade_no(chargingOrder.getCode());
                        model.setOut_refund_no(chargingOrderRefund.getRefundCode());
                        model.setReason("充电失败,取消充电订单");
                        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.setCurrency("CNY");
                        model.setAmount(amount);
                        R<Map<String, Object>> orderR = wxPaymentClient.refundOrderR(model);
                        if (200 == orderR.getCode()) {
                            chargingOrderRefundService.save(chargingOrderRefund);
                            //手续费
                            Map<String, Object> amount1 = (Map<String, Object>) orderR.getData().get("amount");
                            Object refund_fee1 = amount1.get("refund_fee");
                            BigDecimal refund_fee = new BigDecimal(null == refund_fee1 ? "0" : refund_fee1.toString()).divide(new BigDecimal(100));
                            chargingOrderRefund.setRefundFee(refund_fee);
                            chargingOrderRefundService.updateById(chargingOrderRefund);
                            //回退会员折扣次数
                            if (chargingOrder.getVipDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
                                TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                                GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
                                getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
                                getAppUserVipDetail.setVipId(appUser.getVipId());
                                TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
                                if (null != data) {
                                    data.setChargeNum(data.getChargeNum() + 1);
                                    appUserVipDetailClient.updateAppUserVipDetail(data);
                                }
                            }
                        }
                    }
                    if (2 == rechargePaymentType) {
                        RefundReq dto = new RefundReq();
                        dto.setOutTradeNo(chargingOrder.getCode());
                        dto.setOutRequestNo(chargingOrderRefund.getCode());
                        dto.setRefundAmount(thirdRefundAmount.toString());
                        dto.setRefundReason("充电失败,取消充电订单");
                        RefundResp resp = aliPaymentClient.refund(dto).getData();
                        if (null != resp) {
                            chargingOrderRefundService.save(chargingOrderRefund);
                            //回退会员折扣次数
                            if (chargingOrder.getVipDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
                                TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                                GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
                                getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
                                getAppUserVipDetail.setVipId(appUser.getVipId());
                                TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
                                if (null != data) {
                                    data.setChargeNum(data.getChargeNum() + 1);
                                    appUserVipDetailClient.updateAppUserVipDetail(data);
                                }
                            }
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                            chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                        }
                    }
                    if (3 == rechargePaymentType) {
                        RefundReq dto = new RefundReq();
                        dto.setOutTradeNo(chargingOrder.getRechargeSerialNumber());
                        dto.setOutRequestNo(chargingOrderRefund.getCode());
                        dto.setRefundAmount(thirdRefundAmount.toString());
                        dto.setRefundReason("充电失败,取消充电订单");
                        RefundResp resp = h5AliPaymentClient.refund(dto).getData();
                        if (null != resp && "10000".equals(resp.getCode())) {
                            chargingOrderRefundService.save(chargingOrderRefund);
                            //回退会员折扣次数
                            if (chargingOrder.getVipDiscountAmount().compareTo(BigDecimal.ZERO) > 0) {
                                TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                                GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
                                getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
                                getAppUserVipDetail.setVipId(appUser.getVipId());
                                TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
                                if (null != data) {
                                    data.setChargeNum(data.getChargeNum() + 1);
                                    appUserVipDetailClient.updateAppUserVipDetail(data);
                                }
                            }
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                            chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                        }
                    }
                }
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            lock.unlock();
        }
   }
   
    @Transactional
   public void refund1(String code, BigDecimal money) {
      log.info(code + ":-------------------充电成功,执行手动退款-------------------");
      TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code));
@@ -1147,6 +1326,8 @@
         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
         chargingOrderRefund.setRefundCode("CDF" + sdf.format(new Date()) + Double.valueOf(Math.random() * 1000).intValue());
         chargingOrderRefund.setRefundAmount(money);
         chargingOrderRefund.setBalanceRefundAmount(BigDecimal.ZERO);
         chargingOrderRefund.setThirdRefundAmount(money);
         chargingOrderRefund.setRefundStatus(1);
         chargingOrderRefund.setPayType(rechargePaymentType);
         chargingOrderRefund.setRefundStatus(1);
@@ -1165,7 +1346,7 @@
            model.setNotify_url("/payment/wx/refund/notify");
            WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
            amount.setRefund(money.multiply(new BigDecimal(100)).intValue());
            amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue());
            amount.setTotal((isBalancePayMode(chargingOrder.getPayMethod()) ? money(chargingOrder.getThirdPayAmount()) : rechargeAmount).multiply(new BigDecimal(100)).intValue());
            amount.setCurrency("CNY");
            model.setAmount(amount);
            R<Map<String, Object>> orderR = wxPaymentClient.refundOrderR(model);
@@ -1227,22 +1408,47 @@
    * @param success_time
    * @return
    */
    @Transactional
   public AjaxResult chargingOrderStartupFailureWxRefund(String out_refund_no, String refund_id, String tradeState, String success_time) {
      TChargingOrderRefund one = chargingOrderRefundService.getOne(new LambdaQueryWrapper<TChargingOrderRefund>().eq(TChargingOrderRefund::getRefundCode, out_refund_no));
      one.setRefundSerialNumber(refund_id);
      one.setRefundStatus(2);
      one.setRefundTime(LocalDateTime.now());
      chargingOrderRefundService.updateById(one);
      TChargingOrder order = this.getById(one.getChargingOrderId());
      TChargingOrder chargingOrder = new TChargingOrder();
      chargingOrder.setId(one.getChargingOrderId());
      chargingOrder.setAppUserId(order.getAppUserId());
      chargingOrder.setRefundStatus(2);
      chargingOrder.setRefundSerialNumber(refund_id);
      chargingOrder.setRefundTime(LocalDateTime.now());
      this.updateById(chargingOrder);
      return AjaxResult.success();
        RLock lock = redissonClient.getLock("chargingOrderStartupFailureWxRefund:" + out_refund_no);
        try {
            boolean tryLock = lock.tryLock(10, 10, TimeUnit.SECONDS);
            if(tryLock){
                TChargingOrderRefund one = chargingOrderRefundService.getOne(new LambdaQueryWrapper<TChargingOrderRefund>().eq(TChargingOrderRefund::getRefundCode, out_refund_no));
                if (null == one || one.getRefundStatus() == null || one.getRefundStatus() != 1) {
                    return AjaxResult.success();
                }
                if (!"SUCCESS".equals(tradeState)) {
                    return AjaxResult.success();
                }
                TChargingOrder order = this.getById(one.getChargingOrderId());
                if (order == null || (order.getRefundStatus() != null && order.getRefundStatus() == 2)) {
                    return AjaxResult.success();
                }
                one.setRefundSerialNumber(refund_id);
                one.setRefundStatus(2);
                one.setRefundTime(LocalDateTime.now());
                chargingOrderRefundService.updateById(one);
                if (money(one.getBalanceRefundAmount()).compareTo(BigDecimal.ZERO) > 0) {
                    changeUserBalance(order.getAppUserId(), money(one.getBalanceRefundAmount()));
                    recordBalanceRefund(order, money(one.getBalanceRefundAmount()), one.getRefundCode());
                }
                TChargingOrder chargingOrder = new TChargingOrder();
                chargingOrder.setId(one.getChargingOrderId());
                chargingOrder.setAppUserId(order.getAppUserId());
                chargingOrder.setRefundStatus(2);
                chargingOrder.setRefundSerialNumber(refund_id);
                chargingOrder.setRefundTime(LocalDateTime.now());
                this.updateById(chargingOrder);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            lock.unlock();
        }
        return AjaxResult.success();
   }
   
   
@@ -1553,48 +1759,11 @@
      // 查询当前登陆人按钮权限
      SysUser sysUser = sysUserClient.getSysUser(tokenService.getLoginUser().getUserid()).getData();
      Integer roleType = sysUser.getRoleType();
      //如果没传siteId,获取当前登陆人所有的siteIds
      List<Integer> siteIds = new ArrayList<>();
      if (dto.getSiteId() == null) {
         if (userId != null) {
            List<GetSiteListDTO> data = siteClient.getSiteListByUserId(userId).getData();
            for (GetSiteListDTO datum : data) {
               siteIds.add(datum.getId());
            }
         }
      } else {
         siteIds.add(dto.getSiteId());
      }
      if (siteIds.isEmpty()) {
         siteIds.add(-1);
      } else {
         if (roleType == 2) {
            List<Integer> integers = new ArrayList<>();
            for (Integer siteId : siteIds) {
               // 校验有没有这个站点的权限
               List<Boolean> t1 = partnerClient.getChargingOrderMenu(sysUser.getObjectId(), siteId).getData();
               Boolean b = t1.get(1);
               if (b) {
                  integers.add(siteId);
               }
            }
            siteIds = integers;
         }
      }
      if (siteIds.isEmpty()) siteIds.add(-1);
      dto.setSiteIds(siteIds);
      List<ChargingOrderVO> list = this.baseMapper.chargingOrder(pageInfo, dto, startTime1, startTime2, endTime1, endTime2);
      BigDecimal total = new BigDecimal("0");
      long time = 0L;
      BigDecimal electronicMoney = new BigDecimal("0");
      BigDecimal serviceMoney = new BigDecimal("0");
      BigDecimal commissionMoney = new BigDecimal("0");
//       BigDecimal refundMoney = new BigDecimal("0");
      BigDecimal paymentMoney = new BigDecimal("0");
      List<TChargingOrderAccountingStrategy> list3 = chargingOrderAccountingStrategyService.list();
         setChargingOrderAuthSiteIds(dto, sysUser, userId, roleType);
         List<Integer> siteIds = dto.getSiteIds();
         List<ChargingOrderVO> list = this.baseMapper.chargingOrder(pageInfo, dto, startTime1, startTime2, endTime1, endTime2);
         fillChargingOrderBalanceIncome(list);
         List<TChargingOrderAccountingStrategy> list3 = chargingOrderAccountingStrategyService.list();
      for (ChargingOrderVO chargingOrderVO : list) {
         if (roleType == 2) {
            for (Integer siteId : siteIds) {
@@ -1658,25 +1827,226 @@
            
         }
      }
      fillEmptyChargingOrderSummary(tCharingOrderVO);
      Map<String, Object> map = this.baseMapper.chargingOrderNolimit(dto, startTime1, startTime2, endTime1, endTime2);
      if (null != map) {
         tCharingOrderVO.setTotal(map.get("total") == null ? BigDecimal.ZERO : (BigDecimal) map.get("total"));
         tCharingOrderVO.setTime(map.get("time") == null ? 0L : (Long) map.get("time"));
         tCharingOrderVO.setIncome((map.get("paymentMoney") == null ? BigDecimal.ZERO : (BigDecimal) map.get("paymentMoney")).setScale(2, BigDecimal.ROUND_HALF_EVEN));
         tCharingOrderVO.setElectronicMoney((map.get("electronicMoney") == null ? BigDecimal.ZERO : (BigDecimal) map.get("electronicMoney")).setScale(2, BigDecimal.ROUND_HALF_EVEN));
         tCharingOrderVO.setServiceMoney((map.get("serviceMoney") == null ? BigDecimal.ZERO : (BigDecimal) map.get("serviceMoney")).setScale(2, BigDecimal.ROUND_HALF_EVEN));
      } else {
         tCharingOrderVO.setTotal(BigDecimal.ZERO);
         tCharingOrderVO.setTime(0L);
         tCharingOrderVO.setIncome(BigDecimal.ZERO);
         tCharingOrderVO.setElectronicMoney(BigDecimal.ZERO);
         tCharingOrderVO.setServiceMoney(BigDecimal.ZERO);
         tCharingOrderVO.setTotal(getSummaryDecimal(map, "total"));
         tCharingOrderVO.setTime(getSummaryLong(map, "time"));
         tCharingOrderVO.setIncome(getSummaryDecimal(map, "income"));
         tCharingOrderVO.setElectronicMoney(getSummaryDecimal(map, "electronicMoney"));
         tCharingOrderVO.setServiceMoney(getSummaryDecimal(map, "serviceMoney"));
      }
      Map<String, Object> fundMap = this.baseMapper.chargingOrderFundSummary(dto, startTime1, startTime2, endTime1, endTime2);
      if (null != fundMap) {
         tCharingOrderVO.setPlatformIncomeTotal(getSummaryDecimal(fundMap, "platformIncomeTotal"));
         tCharingOrderVO.setPartnerIncomeTotal(getSummaryDecimal(fundMap, "partnerIncomeTotal"));
         tCharingOrderVO.setWechatIncome(getSummaryDecimal(fundMap, "wechatIncome"));
         tCharingOrderVO.setAlipayIncome(getSummaryDecimal(fundMap, "alipayIncome"));
         tCharingOrderVO.setWhitelistChargingIncome(getSummaryDecimal(fundMap, "whitelistChargingIncome"));
         tCharingOrderVO.setWhitelistRefund(getSummaryDecimal(fundMap, "whitelistRefund"));
      }
      Map<String, Object> balanceMap = getExchangeCodeBalanceSummary(dto, startTime1, startTime2, endTime1, endTime2);
      tCharingOrderVO.setBalanceIncome(getSummaryDecimal(balanceMap, "balanceIncome"));
      tCharingOrderVO.setBalanceGiftIncome(getSummaryDecimal(balanceMap, "balanceGiftIncome"));
      pageInfo.setRecords(list);
      tCharingOrderVO.setList(pageInfo);
      return tCharingOrderVO;
         return tCharingOrderVO;
      }
      private void fillChargingOrderBalanceIncome(List<ChargingOrderVO> list) {
         if (list == null || list.isEmpty()) {
            return;
         }
         List<Long> orderIds = list.stream().map(ChargingOrderVO::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 (ChargingOrderVO item : list) {
            Map<String, Object> row = incomeMap.get(item.getId());
            item.setBalanceIncome(getSummaryDecimal(row, "balanceIncome"));
            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) {
         if (userId != null) {
            List<GetSiteListDTO> data = siteClient.getSiteListByUserId(userId).getData();
            for (GetSiteListDTO datum : data) {
               siteIds.add(datum.getId());
            }
         }
      } else {
         siteIds.add(dto.getSiteId());
      }
      if (siteIds.isEmpty()) {
         siteIds.add(-1);
      } else if (roleType == 2) {
         List<Integer> integers = new ArrayList<>();
         for (Integer siteId : siteIds) {
            List<Boolean> t1 = partnerClient.getChargingOrderMenu(sysUser.getObjectId(), siteId).getData();
            Boolean b = t1.get(1);
            if (b) {
               integers.add(siteId);
            }
         }
         siteIds = integers;
      }
      if (siteIds.isEmpty()) {
         siteIds.add(-1);
      }
      dto.setSiteIds(siteIds);
   }
   @Override
   public List<ChargingOrderBalanceIncomeDetailVO> balanceIncomeDetail(ChargingOrderQuery dto) {
      String startTime1 = null;
      String startTime2 = null;
      String endTime1 = null;
      String endTime2 = null;
      if (StringUtils.hasLength(dto.getStartTime())) {
         String[] split = dto.getStartTime().split(" - ");
         startTime1 = split[0];
         startTime2 = split[1];
      }
      if (StringUtils.hasLength(dto.getEndTime())) {
         String[] split = dto.getEndTime().split(" - ");
         endTime1 = split[0];
         endTime2 = split[1];
      }
      if (StringUtils.hasLength(dto.getPhone())) {
         List<Long> data = appUserClient.getUserIdsByPhone(dto.getPhone()).getData();
         if (data == null || data.isEmpty()) {
            return new ArrayList<>();
         }
         dto.setUserIds(data);
      }
      Long userId = tokenService.getLoginUser().getUserid();
      SysUser sysUser = sysUserClient.getSysUser(userId).getData();
      setChargingOrderAuthSiteIds(dto, sysUser, userId, sysUser.getRoleType());
      List<Long> orderIds = this.baseMapper.chargingOrderSummaryOrderIds(dto, startTime1, startTime2, endTime1, endTime2);
      if (orderIds == null || orderIds.isEmpty()) {
         return new ArrayList<>();
      }
      Map<Long, ChargingOrderBalanceIncomeDetailVO> detailMap = new LinkedHashMap<>();
      int batchSize = 500;
      for (int i = 0; i < orderIds.size(); i += batchSize) {
         List<Long> batchIds = orderIds.subList(i, Math.min(i + batchSize, orderIds.size()));
         List<ChargingOrderBalanceIncomeDetailVO> batchList = this.baseMapper.exchangeCodeBalanceIncomeDetail(batchIds);
         if (batchList == null || batchList.isEmpty()) {
            continue;
         }
         for (ChargingOrderBalanceIncomeDetailVO item : batchList) {
            Long packageId = item.getPackageId() == null ? 0L : item.getPackageId();
            ChargingOrderBalanceIncomeDetailVO detail = detailMap.get(packageId);
            if (detail == null) {
               detail = new ChargingOrderBalanceIncomeDetailVO();
               detail.setPackageId(item.getPackageId());
               detail.setPackageName(item.getPackageName());
               detail.setBalanceIncome(BigDecimal.ZERO);
               detail.setGiftIncome(BigDecimal.ZERO);
               detailMap.put(packageId, detail);
            }
            detail.setBalanceIncome(detail.getBalanceIncome().add(item.getBalanceIncome() == null ? BigDecimal.ZERO : item.getBalanceIncome()));
            detail.setGiftIncome(detail.getGiftIncome().add(item.getGiftIncome() == null ? BigDecimal.ZERO : item.getGiftIncome()));
         }
      }
      List<ChargingOrderBalanceIncomeDetailVO> result = new ArrayList<>();
      for (ChargingOrderBalanceIncomeDetailVO detail : detailMap.values()) {
         BigDecimal balanceIncome = (detail.getBalanceIncome() == null ? BigDecimal.ZERO : detail.getBalanceIncome()).setScale(2, RoundingMode.HALF_EVEN);
         BigDecimal giftIncome = (detail.getGiftIncome() == null ? BigDecimal.ZERO : detail.getGiftIncome()).setScale(2, RoundingMode.HALF_EVEN);
         if (balanceIncome.compareTo(BigDecimal.ZERO) == 0 && giftIncome.compareTo(BigDecimal.ZERO) == 0) {
            continue;
         }
         detail.setBalanceIncome(balanceIncome);
         detail.setGiftIncome(giftIncome);
         result.add(detail);
      }
      return result;
   }
   private void fillEmptyChargingOrderSummary(TCharingOrderVO tCharingOrderVO) {
      tCharingOrderVO.setTotal(BigDecimal.ZERO);
      tCharingOrderVO.setTime(0L);
      tCharingOrderVO.setIncome(BigDecimal.ZERO);
      tCharingOrderVO.setElectronicMoney(BigDecimal.ZERO);
      tCharingOrderVO.setServiceMoney(BigDecimal.ZERO);
      tCharingOrderVO.setPlatformIncomeTotal(BigDecimal.ZERO);
      tCharingOrderVO.setPartnerIncomeTotal(BigDecimal.ZERO);
      tCharingOrderVO.setWechatIncome(BigDecimal.ZERO);
      tCharingOrderVO.setAlipayIncome(BigDecimal.ZERO);
      tCharingOrderVO.setBalanceIncome(BigDecimal.ZERO);
      tCharingOrderVO.setBalanceGiftIncome(BigDecimal.ZERO);
      tCharingOrderVO.setWhitelistChargingIncome(BigDecimal.ZERO);
      tCharingOrderVO.setWhitelistRefund(BigDecimal.ZERO);
   }
   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);
      totalMap.put("balanceGiftIncome", BigDecimal.ZERO);
      List<Long> orderIds = this.baseMapper.chargingOrderSummaryOrderIds(dto, startTime1, startTime2, endTime1, endTime2);
      if (orderIds == null || orderIds.isEmpty()) {
         return totalMap;
      }
      BigDecimal balanceIncome = BigDecimal.ZERO;
      BigDecimal balanceGiftIncome = BigDecimal.ZERO;
      int batchSize = 500;
      for (int i = 0; i < orderIds.size(); i += batchSize) {
         List<Long> batchIds = orderIds.subList(i, Math.min(i + batchSize, orderIds.size()));
         Map<String, Object> batchMap = this.baseMapper.exchangeCodeBalanceSummary(batchIds);
         if (batchMap != null) {
            balanceIncome = balanceIncome.add(getSummaryDecimal(batchMap, "balanceIncome"));
            balanceGiftIncome = balanceGiftIncome.add(getSummaryDecimal(batchMap, "balanceGiftIncome"));
         }
      }
      totalMap.put("balanceIncome", balanceIncome);
      totalMap.put("balanceGiftIncome", balanceGiftIncome);
      return totalMap;
   }
      private BigDecimal getSummaryDecimal(Map<String, Object> map, String key) {
         if (map == null) {
            return BigDecimal.ZERO;
         }
         Object value = map.get(key);
      if (value == null) {
         return BigDecimal.ZERO;
      }
      if (value instanceof BigDecimal) {
         return ((BigDecimal) value).setScale(2, RoundingMode.HALF_EVEN);
      }
      if (value instanceof Number) {
         return BigDecimal.valueOf(((Number) value).doubleValue()).setScale(2, RoundingMode.HALF_EVEN);
      }
      return new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_EVEN);
   }
      private Long getSummaryLong(Map<String, Object> map, String key) {
         if (map == null) {
            return 0L;
         }
         Object value = map.get(key);
      if (value == null) {
         return 0L;
      }
      if (value instanceof Number) {
         return ((Number) value).longValue();
      }
      return Long.parseLong(value.toString());
   }
   @Override
   public R<PageInfo<PayOrderDto>> payOrderQuery(PayOrderQueryDto payOrderQueryDto) {
      PageInfo<PayOrderDto> pageInfo = new PageInfo<>(payOrderQueryDto.getPageCurr(), payOrderQueryDto.getPageSize());
@@ -1770,14 +2140,19 @@
      String startTime2 = null;
      String endTime1 = null;
      String endTime2 = null;
      List<TChargingGun> allGun = chargingGunClient.getAllGun().getData();
      List<TChargingPile> allPile = chargingGunClient.getAllPile().getData();
      if (StringUtils.hasLength(dto.getStartTime())) {
         String[] split = dto.getStartTime().split(" - ");
         startTime1 = split[0];
         startTime2 = split[1];
            String[] split1 = split[1].split(":");
            startTime2 = split1[0] + ":" + split1[1] + ":59";
      }
      if (StringUtils.hasLength(dto.getEndTime())) {
         String[] split = dto.getEndTime().split(" - ");
         endTime1 = split[0];
            String[] split1 = split[1].split(":");
            endTime2 = split1[0] + ":" + split1[1] + ":59";
      }
      ChargingOrderTimeVO chargingOrderTimeVO = new ChargingOrderTimeVO();
      if (StringUtils.hasLength(dto.getPhone())) {
@@ -1845,103 +2220,86 @@
      }
      dto.setSiteIds(siteIds);
      PageInfo<ChargingOrderListVO> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
      List<ChargingOrderListVO> list = this.baseMapper.chargingList(pageInfo, dto, startTime1, startTime2, endTime1, endTime2);
      List<Site> sites = siteClient.getSiteAll().getData();
      List<Long> collect1 = list.stream().map(ChargingOrderListVO::getId).collect(Collectors.toList());
      if(collect1.isEmpty()){
         collect1.add(-1L);
      }
      List<TChargingOrderAccountingStrategy> chargingOrderAccountingStrategies = chargingOrderAccountingStrategyService.list();
      for (ChargingOrderListVO chargingOrderListVO : list) {
      List<ChargingOrderListVO> list = new ArrayList<>();
      List<Map<String, Object>> maps = this.baseMapper.chargingList1(pageInfo, dto, startTime1, startTime2, endTime1, endTime2);
      for (Map<String, Object> map : maps) {
         if(null == map){
            continue;
         }
         ChargingOrderListVO chargingOrderListVO = new ChargingOrderListVO();
         if (roleType == 2) {
            List<Boolean> data = partnerClient.getChargingListMenu(sysUser.getObjectId(), chargingOrderListVO.getSiteId()).getData();
            List<Boolean> data = partnerClient.getChargingListMenu(sysUser.getObjectId(), Integer.valueOf(map.get("siteId").toString())).getData();
            chargingOrderListVO.setAuthInfo(data.get(0));
            chargingOrderListVO.setAuthCurve(data.get(1));
         }
         chargingOrderListVO.setUid(map.get("id").toString());
         chargingOrderListVO.setCode(map.get("code").toString());
         chargingOrderListVO.setSiteName(map.get("siteName").toString());
         chargingOrderListVO.setOrderType(map.get("orderType").toString());
         chargingOrderListVO.setTerminalName(map.get("terminalName").toString());
         chargingOrderListVO.setElectricity(null == map.get("electricity") ? BigDecimal.ZERO : new BigDecimal(map.get("electricity").toString()));
         chargingOrderListVO.setChargingCapacity(chargingOrderListVO.getElectricity());
         Object periodElectricPrice = map.get("periodElectricPrice");
         Object periodServicePrice = map.get("periodServicePrice");
         if(null != periodServicePrice){
            Integer orderSource = Integer.valueOf(map.get("orderSource").toString());
            if(2 == orderSource){
               BigDecimal bigDecimal = new BigDecimal(periodServicePrice.toString()).multiply(new BigDecimal(0.8)).setScale(2, RoundingMode.HALF_EVEN);
               chargingOrderListVO.setPaymentAmount(new BigDecimal(periodElectricPrice.toString()).add(bigDecimal));
               BigDecimal sharingAmount = new BigDecimal(periodServicePrice.toString()).multiply(new BigDecimal(0.2)).setScale(2, RoundingMode.HALF_EVEN);
               chargingOrderListVO.setSharingAmount(sharingAmount);
            }else{
               chargingOrderListVO.setPaymentAmount(new BigDecimal(periodElectricPrice.toString()).add(new BigDecimal(periodServicePrice.toString())).setScale(2, RoundingMode.HALF_EVEN));
               chargingOrderListVO.setSharingAmount(BigDecimal.ZERO);
            }
         }else{
            chargingOrderListVO.setPaymentAmount(BigDecimal.ZERO);
            chargingOrderListVO.setSharingAmount(BigDecimal.ZERO);
         }
         chargingOrderListVO.setElectrovalence(null == map.get("electrovalence") ? BigDecimal.ZERO : new BigDecimal(map.get("electrovalence").toString()));
         chargingOrderListVO.setServiceCharge(null == map.get("serviceCharge") ? BigDecimal.ZERO : new BigDecimal(map.get("serviceCharge").toString()));
         BigDecimal bigDecimal = new BigDecimal("0.006");
         if (chargingOrderListVO.getOrderAmount() != null) {
            chargingOrderListVO.setCommissionAmount(chargingOrderListVO.getRechargeAmount().multiply(bigDecimal));
         if (!"0".equals(map.get("rechargePaymentType").toString())) {
            chargingOrderListVO.setCommissionAmount(new BigDecimal(map.get("rechargeAmount").toString()).multiply(bigDecimal));
         }
         chargingOrderListVO.setPaymentAmount(chargingOrderListVO.getPaymentAmount());
         chargingOrderListVO.setUid(chargingOrderListVO.getId() + "");
         List<Integer> integers = new ArrayList<>();
         integers.add(chargingOrderListVO.getSiteId());
         Site site = sites.stream().filter(e -> e.getId().equals(chargingOrderListVO.getSiteId())).findFirst().orElse(null);
         if (site != null) {
            chargingOrderListVO.setSiteName(site.getName());
         if(null != map.get("tripartitePlatformName")){
            chargingOrderListVO.setTripartitePlatformName(map.get("tripartitePlatformName").toString());
         }
         if (chargingOrderListVO.getChargingGunId() != null && chargingOrderListVO.getChargingPileId() != null) {
            TChargingGun data1 = allGun.stream().filter(e -> e.getId().equals(chargingOrderListVO.getChargingGunId())).findFirst().orElse(null);
            TChargingPile data2 = allPile.stream().filter(e -> e.getId().equals(chargingOrderListVO.getChargingPileId())).findFirst().orElse(null);
            if (data2 != null && data1 != null) {
               chargingOrderListVO.setTerminalName(data2.getName() + "-" + data1.getName());
            }
         if(null != map.get("startTime")){
            chargingOrderListVO.setStartTime(LocalDateTime.parse(map.get("startTime").toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
         }
         if (chargingOrderListVO.getStartTime() != null && chargingOrderListVO.getEndTime() != null) {
            LocalDateTime startTime = chargingOrderListVO.getStartTime();
            LocalDateTime endTime = chargingOrderListVO.getEndTime();
            // 计算时间差 单位秒
            long between = ChronoUnit.SECONDS.between(startTime, endTime);
            chargingOrderListVO.setChargingSecond(between);
         if(null != map.get("endTime")){
            chargingOrderListVO.setEndTime(LocalDateTime.parse(map.get("endTime").toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
         }
         // 获取开始SOC 结束soc
         if (chargingOrderListVO.getCode() != null) {
            UploadRealTimeMonitoringData asc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrderListVO.getCode(), "asc");
            UploadRealTimeMonitoringData desc = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrderListVO.getCode(), "desc");
            if(null != asc){
               chargingOrderListVO.setStartSoc(asc.getSoc().toString());
            }
            if(null != desc){
               chargingOrderListVO.setEndSoc(desc.getSoc().toString());
            }
         if(null != map.get("chargingSecond")){
            chargingOrderListVO.setChargingSecond(Long.valueOf(map.get("chargingSecond").toString()));
         }else{
            chargingOrderListVO.setChargingSecond(0L);
         }
         if (chargingOrderListVO.getAppUserId() != null) {
            TAppUser data3 = appUserClient.getUserById(chargingOrderListVO.getAppUserId()).getData();
            List<Long> carId = new ArrayList<>();
            if (data3 != null) {
               if (chargingOrderListVO.getAppUserCarId() != null) {
                  carId.add(chargingOrderListVO.getAppUserCarId());
                  if (!carId.isEmpty()) {
                     List<TAppUserCar> data4 = appUserCarClient.getCarByIds(carId).getData();
                     if (data4 != null && !data4.isEmpty()) {
                        chargingOrderListVO.setLicensePlate(data4.get(0).getLicensePlate());
                     }
                  }
               } else {
                  chargingOrderListVO.setLicensePlate(chargingOrderListVO.getPlateNum());
               }
               chargingOrderListVO.setPhone(data3.getPhone());
            }
         if(null != map.get("startSoc")){
            chargingOrderListVO.setEndSoc(map.get("startSoc").toString());
         }
         List<TChargingOrderAccountingStrategy> list2 = chargingOrderAccountingStrategies.stream().filter(s->s.getChargingOrderId().equals(chargingOrderListVO.getId())).collect(Collectors.toList());
         // 尖峰平谷充电量 度数
         BigDecimal jian = new BigDecimal("0");
         BigDecimal feng = new BigDecimal("0");
         BigDecimal ping = new BigDecimal("0");
         BigDecimal gu = new BigDecimal("0");
         BigDecimal total = new BigDecimal("0");
         for (TChargingOrderAccountingStrategy temp : list2) {
            if (temp.getChargingCapacity() == null) {
               temp.setChargingCapacity(BigDecimal.ZERO);
            }
            switch (temp.getType()) {
               case 1:
                  jian = jian.add(temp.getChargingCapacity());
                  break;
               case 2:
                  feng = feng.add(temp.getChargingCapacity());
                  break;
               case 3:
                  ping = ping.add(temp.getChargingCapacity());
                  break;
               case 4:
                  gu = gu.add(temp.getChargingCapacity());
                  break;
            }
         if(null != map.get("endSoc")){
            chargingOrderListVO.setEndSoc(map.get("endSoc").toString());
         }
         total = total.add(jian).add(feng).add(ping).add(gu);
         if(null != map.get("status")){
            chargingOrderListVO.setStatus(Integer.valueOf(map.get("status").toString()));
         }
         if(null != map.get("endMode")){
            chargingOrderListVO.setEndMode(Integer.valueOf(map.get("endMode").toString()));
         }
         if(null != map.get("phone")){
            chargingOrderListVO.setPhone(map.get("phone").toString());
         }
         if(null != map.get("licensePlate")){
            chargingOrderListVO.setLicensePlate(map.get("licensePlate").toString());
         }
         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());
         BigDecimal gu = null == map.get("gu") ? BigDecimal.ZERO : new BigDecimal(map.get("gu").toString());
         BigDecimal total = jian.add(feng).add(ping).add(gu);
         if (total.compareTo(new BigDecimal("0")) != 0) {
            chargingOrderListVO.setElectronicProportion(
                  jian.divide(total, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")) + "%(尖)/"
@@ -1955,52 +2313,11 @@
                        "0" + "%(平)/" +
                        "0" + "%(谷)");
         }
         if (chargingOrderListVO.getOrderSource().equals(2)) {
            chargingOrderListVO.setSharingAmount(chargingOrderListVO.getServiceCharge() != null ?
                  chargingOrderListVO.getServiceCharge().multiply(new BigDecimal("0.2")).setScale(2, BigDecimal.ROUND_HALF_UP)
                  : new BigDecimal("0"));
         } else {
            chargingOrderListVO.setSharingAmount(new BigDecimal("0"));
         }
         list.add(chargingOrderListVO);
      }
      // 不分页
      PageInfo<ChargingOrderListVO> pageInfo1 = new PageInfo<>(1, 999999999);
      List<ChargingOrderListVO> list1 = this.baseMapper.chargingList(pageInfo1, dto, startTime1, startTime2, endTime1, endTime2);
      for (ChargingOrderListVO chargingOrderListVO : list1) {
         List<Integer> integers = new ArrayList<>();
         integers.add(chargingOrderListVO.getSiteId());
         Site site = sites.stream().filter(e -> e.getId().equals(chargingOrderListVO.getSiteId())).findFirst().orElse(null);
         if (site != null) {
            chargingOrderListVO.setSiteName(site.getName());
         }
         if (chargingOrderListVO.getStartTime() != null && chargingOrderListVO.getEndTime() != null) {
            LocalDateTime startTime = chargingOrderListVO.getStartTime();
            LocalDateTime endTime = chargingOrderListVO.getEndTime();
            // 计算时间差 单位秒
            long between = ChronoUnit.SECONDS.between(startTime, endTime);
            chargingOrderListVO.setChargingSecond(between);
         }
         if (chargingOrderListVO.getChargingGunId() != null && chargingOrderListVO.getChargingPileId() != null) {
            TChargingGun data1 = allGun.stream().filter(e -> e.getId().equals(chargingOrderListVO.getChargingGunId())).findFirst().orElse(null);
            TChargingPile data2 = allPile.stream().filter(e -> e.getId().equals(chargingOrderListVO.getChargingPileId())).findFirst().orElse(null);
            if (data2 != null && data1 != null) {
               chargingOrderListVO.setTerminalName(data2.getName() + "-" + data1.getName());
            }
         }
      }
      chargingOrderTimeVO.setExportList(list1);
      chargingOrderTimeVO.setOrderCount(list1.size());
      // 计算充电总度数
      BigDecimal electronic = new BigDecimal("0");
      // 支付金额
      BigDecimal paymentAmount = new BigDecimal("0");
      // 电费
      BigDecimal electrovalence = new BigDecimal("0");
      // 服务费
      BigDecimal serviceCharge = new BigDecimal("0");
      // 尖峰平谷充电到账
      BigDecimal jianElectronic = new BigDecimal("0");
      BigDecimal fengElectronic = new BigDecimal("0");
@@ -2016,74 +2333,38 @@
      BigDecimal feng = new BigDecimal("0");
      BigDecimal ping = new BigDecimal("0");
      BigDecimal gu = new BigDecimal("0");
      for (ChargingOrderListVO chargingOrderListVO : list1) {
         List<TChargingOrderAccountingStrategy> collect = chargingOrderAccountingStrategies.stream().filter(s -> s.getChargingOrderId().equals(chargingOrderListVO.getId())).collect(Collectors.toList());
         BigDecimal periodServicePrice = collect.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
         BigDecimal periodElectricPrice = collect.stream().map(TChargingOrderAccountingStrategy::getPeriodElectricPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
         BigDecimal chargingCapacity = collect.stream().map(TChargingOrderAccountingStrategy::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
         electronic = electronic.add(chargingCapacity);
         electrovalence = electrovalence.add(periodElectricPrice);
         if (chargingOrderListVO.getOrderSource().equals(2)) {
            serviceCharge = serviceCharge.add(periodServicePrice.multiply(new BigDecimal("0.8")));
            paymentAmount = paymentAmount.add(periodElectricPrice).add(periodServicePrice.multiply(new BigDecimal("0.8")));
         } else {
            serviceCharge = serviceCharge.add(periodServicePrice);
            paymentAmount = paymentAmount.add(periodElectricPrice).add(periodServicePrice);
      List<Map<String, Object>> list1 = this.baseMapper.chargingListSum(dto, startTime1, startTime2, endTime1, endTime2);
      for (Map<String, Object> map : list1) {
         if(null == map){
            continue;
         }
         if (!chargingOrderListVO.getOrderSource().equals(2)) {
            for (TChargingOrderAccountingStrategy temp : collect) {
               switch (temp.getType()) {
                  case 1:
                     jian = jian.add(temp.getChargingCapacity());
                     jianElectronic = jianElectronic.add(temp.getPeriodElectricPrice()).add(temp.getPeriodServicePrice());
                     jianService = jianService.add(temp.getPeriodServicePrice());
                     break;
                  case 2:
                     feng = feng.add(temp.getChargingCapacity());
                     fengElectronic = fengElectronic.add(temp.getPeriodElectricPrice()).add(temp.getPeriodServicePrice());
                     fengService = fengService.add(temp.getPeriodServicePrice());
                     break;
                  case 3:
                     ping = ping.add(temp.getChargingCapacity());
                     pingElectronic = pingElectronic.add(temp.getPeriodElectricPrice()).add(temp.getPeriodServicePrice());
                     pingService = pingService.add(temp.getPeriodServicePrice());
                     break;
                  case 4:
                     gu = gu.add(temp.getChargingCapacity());
                     guElectronic = guElectronic.add(temp.getPeriodElectricPrice()).add(temp.getPeriodServicePrice());
                     guService = guService.add(temp.getPeriodServicePrice());
                     break;
               }
            }
         } else {
            for (TChargingOrderAccountingStrategy temp : collect) {
               BigDecimal multiply = temp.getPeriodServicePrice().multiply(new BigDecimal("0.8"));
               switch (temp.getType()) {
                  case 1:
                     jian = jian.add(temp.getChargingCapacity());
                     jianElectronic = jianElectronic.add(temp.getPeriodElectricPrice()).add(multiply);
                     jianService = jianService.add(multiply);
                     break;
                  case 2:
                     feng = feng.add(temp.getChargingCapacity());
                     fengElectronic = fengElectronic.add(temp.getPeriodElectricPrice()).add(multiply);
                     fengService = fengService.add(multiply);
                     break;
                  case 3:
                     ping = ping.add(temp.getChargingCapacity());
                     pingElectronic = pingElectronic.add(temp.getPeriodElectricPrice()).add(multiply);
                     pingService = pingService.add(multiply);
                     break;
                  case 4:
                     gu = gu.add(temp.getChargingCapacity());
                     guElectronic = guElectronic.add(temp.getPeriodElectricPrice()).add(multiply);
                     guService = guService.add(multiply);
                     break;
               }
            }
         }
         jianElectronic = jianElectronic.add(new BigDecimal(null == map.get("jianElectronic") ? "0" : map.get("jianElectronic").toString()));
         fengElectronic = fengElectronic.add(new BigDecimal(null == map.get("fengElectronic") ? "0" : map.get("fengElectronic").toString()));
         pingElectronic = pingElectronic.add(new BigDecimal(null == map.get("pingElectronic") ? "0" : map.get("pingElectronic").toString()));
         guElectronic = guElectronic.add(new BigDecimal(null == map.get("guElectronic") ? "0" : map.get("guElectronic").toString()));
         jianService = jianService.add(new BigDecimal(null == map.get("jianService") ? "0" : map.get("jianService").toString()));
         fengService = fengService.add(new BigDecimal(null == map.get("fengService") ? "0" : map.get("fengService").toString()));
         pingService = pingService.add(new BigDecimal(null == map.get("pingService") ? "0" : map.get("pingService").toString()));
         guService = guService.add(new BigDecimal(null == map.get("guService") ? "0" : map.get("guService").toString()));
         jian = jian.add(new BigDecimal(null == map.get("jian") ? "0" : map.get("jian").toString()));
         feng = feng.add(new BigDecimal(null == map.get("feng") ? "0" : map.get("feng").toString()));
         ping = ping.add(new BigDecimal(null == map.get("ping") ? "0" : map.get("ping").toString()));
         gu = gu.add(new BigDecimal(null == map.get("gu") ? "0" : map.get("gu").toString()));
      }
        Map<String, Object> map = this.baseMapper.chargingListSum1(dto, startTime1, startTime2, endTime1, endTime2);
        System.err.println("充电时段统计-查询参数:" + JSON.toJSONString(dto));
        System.err.println("充电时段统计-汇总数据:" + JSON.toJSONString(map));
        //订单数量
        int orderCount = Integer.parseInt(map.get("orderCount").toString());
        // 计算充电总度数
        BigDecimal electronic = new BigDecimal(map.get("electronic").toString());
        // 支付金额
        BigDecimal paymentAmount = new BigDecimal(map.get("paymentAmount").toString());
        // 电费
        BigDecimal electrovalence = new BigDecimal(map.get("electrovalence").toString());
        // 服务费
        BigDecimal serviceCharge = new BigDecimal(map.get("serviceCharge").toString());
        chargingOrderTimeVO.setOrderCount(orderCount);
      chargingOrderTimeVO.setChargingCapacity(electronic.setScale(2, BigDecimal.ROUND_HALF_EVEN));
      chargingOrderTimeVO.setPaymentAmount(paymentAmount.setScale(2, BigDecimal.ROUND_HALF_EVEN));
      chargingOrderTimeVO.setElectrovalence(electrovalence.setScale(2, BigDecimal.ROUND_HALF_EVEN));
@@ -2130,6 +2411,93 @@
      pageInfo.setRecords(list);
      chargingOrderTimeVO.setList(pageInfo);
      return chargingOrderTimeVO;
   }
   @Override
   public List<ChargingOrderListVO> export(ChargingListQuery dto) {
      String startTime1 = null;
      String startTime2 = null;
      String endTime1 = null;
      String endTime2 = null;
      if (StringUtils.hasLength(dto.getStartTime())) {
         String[] split = dto.getStartTime().split(" - ");
         startTime1 = split[0];
         startTime2 = split[1];
      }
      if (StringUtils.hasLength(dto.getEndTime())) {
         String[] split = dto.getEndTime().split(" - ");
         endTime1 = split[0];
         endTime2 = split[1];
      }
      if (StringUtils.hasLength(dto.getPhone())) {
         List<Long> data = appUserClient.getUserIdsByPhone(dto.getPhone()).getData();
         if (data != null) {
            if (!data.isEmpty()) {
               dto.setUserIds(data);
            }
         } else {
            dto.setUserIds(new ArrayList<Long>());
         }
         if (dto.getUserIds().isEmpty()) {
            List<Long> carIds = dto.getUserIds();
            carIds.add(-1L);
            dto.setUserIds(carIds);
         }
      }
      if (StringUtils.hasLength(dto.getLicensePlate())) {
         List<Long> data = appUserCarClient.getAppUserCarByLicensePlates(dto.getLicensePlate()).getData();
         if (data != null) {
            if (!data.isEmpty()) {
               dto.setCarIds(data);
            }
         } else {
            dto.setCarIds(new ArrayList<Long>());
         }
         if (dto.getCarIds().isEmpty()) {
            List<Long> carIds = dto.getCarIds();
            carIds.add(-1L);
            dto.setCarIds(carIds);
         }
      }
      Long userId = tokenService.getLoginUser().getUserid();
      // 查询当前登陆人按钮权限
      SysUser sysUser = sysUserClient.getSysUser(tokenService.getLoginUser().getUserid()).getData();
      Integer roleType = sysUser.getRoleType();
      //如果没传siteId,获取当前登陆人所有的siteIds
      List<Integer> siteIds = new ArrayList<>();
      if (dto.getSiteId() == null) {
         if (userId != null) {
            List<GetSiteListDTO> data = siteClient.getSiteListByUserId(userId).getData();
            for (GetSiteListDTO datum : data) {
               siteIds.add(datum.getId());
            }
         }
      } else {
         siteIds.add(dto.getSiteId());
      }
      if (siteIds.isEmpty()) {
         siteIds.add(-1);
      } else {
         if (roleType == 2) {
            List<Integer> integers = new ArrayList<>();
            for (Integer siteId : siteIds) {
               // 校验有没有这个站点的权限
               List<Boolean> t1 = partnerClient.getChargingOrderMenu(sysUser.getObjectId(), siteId).getData();
               Boolean b = t1.get(1);
               if (b) {
                  integers.add(siteId);
               }
            }
            siteIds = integers;
         }
      }
      dto.setSiteIds(siteIds);
      List<ChargingOrderListVO> list1 = this.baseMapper.chargingList(dto, startTime1, startTime2, endTime1, endTime2);
      return list1;
   }
   
   
@@ -2183,7 +2551,7 @@
      
      // 获取开始SOC 结束soc
      if (chargingOrder.getCode() != null) {
         List<UploadRealTimeMonitoringData> data6 = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
         List<UploadRealTimeMonitoringData> data6 = uploadRealTimeMonitoringDataService.getDataByOrderCodeAsc(chargingOrder.getCode());
         if (data6 != null) {
            for (UploadRealTimeMonitoringData uploadRealTimeMonitoringData : data6) {
               if (uploadRealTimeMonitoringData.getOutput_current() != null &&
@@ -2320,542 +2688,563 @@
    * @param vo
    */
   @Override
    @Transactional
   public R endChargeBillingCharge(TransactionRecordMessageVO vo) {
      RLock lock = redissonClient.getLock("endOrder:" + vo.getTransaction_serial_number());
      boolean tryLock = false;
      try {
         tryLock = lock.tryLock(100, TimeUnit.SECONDS);
      } catch (InterruptedException e) {
         e.printStackTrace();
         lock.unlock();
         return R.ok();
      }
      if (!tryLock) {
         return R.ok();
      }
      try {
         Object cacheObject = redisService.getCacheObject("chargingOrderStatus:" + vo.getTransaction_serial_number());
         if(null != cacheObject && 5 == (int)cacheObject){
            return R.ok();
         }
         TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, vo.getTransaction_serial_number()));
         if (null == chargingOrder) {
            return R.ok();
         }
         Integer status = chargingOrder.getStatus();
         if (status == 5) {
            return R.ok();
         }
         //如果使用优惠券需要判断优惠券是否满足使用条件
         //退款金额=优惠券金额+剩余充电金额
         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()) {
            return R.fail("计费策略为空,无法计算费用");
         }
         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<>();
         //跨天
         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));
            boolean tryLock = lock.tryLock(60, 60, TimeUnit.SECONDS);
            if(tryLock){
                TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, vo.getTransaction_serial_number()));
                if (null == chargingOrder) {
                    log.error("订单不存在,订单号:{}", vo.getTransaction_serial_number());
                    return R.fail("订单不存在,订单号:" + vo.getTransaction_serial_number());
                }
                Integer status = chargingOrder.getStatus();
                if (status == 5) {
                    log.info("订单已结算,订单号:{}", vo.getTransaction_serial_number());
                    return R.fail("订单已结算,订单号:" + vo.getTransaction_serial_number());
                }
         List<UploadRealTimeMonitoringData> dataList = uploadRealTimeMonitoringDataService.getDataByOrderCode(chargingOrder.getCode());
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         chargingOrder.setStartTime(LocalDateTime.parse(sdf.format(dataList.get(dataList.size() - 1).getCreate_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);
         this.updateById(chargingOrder);
         redisService.setCacheObject("chargingOrderStatus:" + vo.getTransaction_serial_number(), 5, 100L, TimeUnit.SECONDS);
         chargingOrder = this.getById(chargingOrder.getId());
         Site site = siteClient.getSiteByIds(Arrays.asList(chargingOrder.getSiteId())).getData().get(0);
         //推送三方平台
         if (2 == chargingOrder.getOrderSource() && 1 == site.getIsOpenSynchronization()) {
            TChargingOrder finalChargingOrder = chargingOrder;
            new Thread(new Runnable() {
               @Override
               public void run() {
                  tcecClient.notificationEquipChargeStatus(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getOperatorId());
                  tcecClient.notificationStopChargeResult(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getChargingGunId().toString(),
                        finalChargingOrder.getOperatorId());
                  tcecClient.notificationChargeOrderInfo(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getOperatorId());
               }
            }).start();
         }
         ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
         TChargingOrder finalChargingOrder1 = chargingOrder;
         threadPoolExecutor.execute(()->{
            //推送成都监管
            NotificationConnectorChargeStatusVo statusVo = new NotificationConnectorChargeStatusVo();
            statusVo.setOrderCode(finalChargingOrder1.getCode());
            statusVo.setChargingGunId(finalChargingOrder1.getChargingGunId());
            chengDuJianGuanClient.notificationConnectorChargeStatus(statusVo);
            chengDuJianGuanClient.notificationOrderInfo(statusVo);
         });
         //开始将优惠券优惠的金额添加到明细中
         BigDecimal couponDiscountAmount = chargingOrder.getCouponDiscountAmount();
         if (null != couponDiscountAmount && couponDiscountAmount.compareTo(BigDecimal.ZERO) > 0) {
            List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()));
            BigDecimal reduce = list.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            for (TChargingOrderAccountingStrategy chargingOrderAccountingStrategy : list) {
               BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodServicePrice();
               BigDecimal multiply = couponDiscountAmount.multiply(periodServicePrice.divide(reduce, new MathContext(4, RoundingMode.HALF_EVEN)));
               periodServicePrice = periodServicePrice.subtract(multiply);
               chargingOrderAccountingStrategy.setPeriodServicePrice(periodServicePrice.setScale(2, RoundingMode.HALF_EVEN));
               chargingOrderAccountingStrategy.setCouponDiscountAmount(multiply.setScale(2, RoundingMode.HALF_EVEN));
            }
            chargingOrderAccountingStrategyService.updateBatchById(list);
         }
         // 将枪状态重置为空闲
         TChargingGun chargingGun = new TChargingGun();
         chargingGun.setId(chargingOrder.getChargingGunId());
         chargingGun.setStatus(2);
         chargingGun.setChargingPower(BigDecimal.ZERO);
         chargingGunClient.updateChargingGunById(chargingGun);
         chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
         //推送状态给三方平台
         if (2 == chargingOrder.getOrderSource() && 1 == site.getIsOpenSynchronization()) {
            tcecClient.pushChargingGunStatus(chargingGun.getFullNumber(), 2);
         }
         //添加积分
         if (1 == chargingOrder.getOrderSource()) {
            TIntegralRule integralRule = integralRuleClient.getSet().getData();
            if (null != integralRule) {
               TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
               Integer num1 = JSON.parseObject(integralRule.getChargeCredit()).getInteger("num1");
               Integer integral = chargingOrder.getServiceCharge().intValue() * num1;
               if (null != appUser.getVipId()) {
                  TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
                  Integer doubleIntegration = vip.getDoubleIntegration();
                  //双倍积分
                  if (1 == doubleIntegration) {
                     integral *= 2;
                  }
               }
               if (integral > 0) {
                  TAppUserIntegralChange appUserIntegralChange = new TAppUserIntegralChange();
                  appUserIntegralChange.setAppUserId(appUser.getId());
                  appUserIntegralChange.setChangeType(2);
                  appUserIntegralChange.setHistoricalIntegral(appUser.getPoints());
                  appUser.setPoints(appUser.getPoints() + integral);
                  appUserIntegralChange.setCurrentIntegral(appUser.getPoints());
                  appUserIntegralChange.setCreateTime(LocalDateTime.now());
                  appUserIntegralChange.setOrderCode(chargingOrder.getCode());
                  appUserIntegralChange.setExtension(chargingOrder.getId().toString());
                  appUserClient.updateAppUser(appUser);
                  appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange);
               }
            }
            //计算用户标签
            editUserTag(chargingOrder);
            //用户推荐奖励
            referralReward(chargingOrder);
            //开始构建退款费用
            refundAmount = refundAmount.setScale(2, RoundingMode.HALF_EVEN);
            Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
            if (refundAmount.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(refundAmount);
               chargingOrderRefund.setPayType(rechargePaymentType);
               chargingOrderRefund.setRefundStatus(1);
               chargingOrderRefund.setCode(chargingOrder.getCode());
               chargingOrderRefund.setRefundTitle("充电完成退款");
               chargingOrderRefund.setRefundContent("充电完成退款");
               chargingOrderRefund.setRefundReason("充电完成退款");
               chargingOrderRefund.setRefundRemark("实际充电消费金额:" + chargingOrder.getPaymentAmount());
               chargingOrderRefund.setRefundTotalAmount(refundAmount);
               chargingOrderRefund.setPayAmount(rechargeAmount);
               if (1 == rechargePaymentType) {
                  WxPaymentRefundModel model = new WxPaymentRefundModel();
                  model.setOut_trade_no(chargingOrder.getCode());
                  model.setOut_refund_no(chargingOrderRefund.getRefundCode());
                  model.setReason("充电完成退款");
                  model.setNotify_url("/payment/wx/refund/notify");
                  WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
                  amount.setRefund(refundAmount.multiply(new BigDecimal(100)).intValue());
                  amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue());
                  amount.setCurrency("CNY");
                  model.setAmount(amount);
                  R<Map<String, Object>> result = wxPaymentClient.refundOrderR(model);
                  if (200 == result.getCode()) {
                     chargingOrderRefundService.save(chargingOrderRefund);
                     //手续费
                     Map<String, Object> amount1 = (Map<String, Object>) result.getData().get("amount");
                     Object refund_fee1 = amount1.get("refund_fee");
                     BigDecimal refund_fee = new BigDecimal(null == refund_fee1 ? "0" : refund_fee1.toString()).divide(new BigDecimal(100));
                     chargingOrderRefund.setRefundFee(refund_fee);
                     chargingOrderRefundService.updateById(chargingOrderRefund);
                  }
               }
               if (2 == rechargePaymentType) {
                  RefundReq dto = new RefundReq();
                  dto.setOutTradeNo(chargingOrder.getCode());
                  dto.setOutRequestNo(chargingOrderRefund.getRefundCode());
                  dto.setRefundAmount(refundAmount.toString());
                  dto.setRefundReason("充电完成退款");
                  RefundResp resp = aliPaymentClient.refund(dto).getData();
                  if (null != resp) {
                     chargingOrderRefundService.save(chargingOrderRefund);
                     this.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                  }
               }
               if (3 == rechargePaymentType) {
                  RefundReq dto = new RefundReq();
                  dto.setOutTradeNo(chargingOrder.getRechargeSerialNumber());
                  dto.setOutRequestNo(chargingOrderRefund.getRefundCode());
                  dto.setRefundAmount(refundAmount.toString());
                  dto.setRefundReason("充电完成退款");
                  RefundResp resp = h5AliPaymentClient.refund(dto).getData();
                  if (null != resp && "10000".equals(resp.getCode())) {
                     chargingOrderRefundService.save(chargingOrderRefund);
                     this.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                  }
               }
            }else{
               //构建退款明细
               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(refundAmount);
               chargingOrderRefund.setRefundStatus(2);
               chargingOrderRefund.setPayType(rechargePaymentType);
               chargingOrderRefund.setCode(chargingOrder.getCode());
               chargingOrderRefund.setRefundTitle("充电完成退款");
               chargingOrderRefund.setRefundContent("充电完成退款");
               chargingOrderRefund.setRefundReason("充电完成退款");
               chargingOrderRefund.setRefundRemark("实际充电消费金额:" + chargingOrder.getPaymentAmount());
               chargingOrderRefund.setRefundTotalAmount(refundAmount);
               chargingOrderRefund.setPayAmount(rechargeAmount);
               chargingOrderRefund.setRefundTime(LocalDateTime.now());
               chargingOrderRefundService.save(chargingOrderRefund);
                //如果使用优惠券需要判断优惠券是否满足使用条件
                //退款金额=优惠券金额+剩余充电金额
                BigDecimal periodElectricPrice_total = BigDecimal.ZERO;
                BigDecimal periodServicePrice_total = BigDecimal.ZERO;
                BigDecimal vipDiscountAmount_total = BigDecimal.ZERO;
                BigDecimal serviceCharge_total = BigDecimal.ZERO;
                BigDecimal total = BigDecimal.ZERO;
               chargingOrder.setRefundStatus(2);
               chargingOrder.setRefundTime(LocalDateTime.now());
               this.updateById(chargingOrder);
            }
         }
         //添加汇总统计数据
         List<TChargingOrderAccountingStrategy> list4 = chargingOrderAccountingStrategyService.list(new QueryWrapper<TChargingOrderAccountingStrategy>().eq("charging_order_id", chargingOrder.getId()));
         BigDecimal electronic_reduce = list4.stream().map(TChargingOrderAccountingStrategy::getPeriodElectricPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
         BigDecimal service_reduce = list4.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
         BigDecimal chargingCapacity = list4.stream().map(TChargingOrderAccountingStrategy::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
         BigDecimal serviceMoney = BigDecimal.ZERO;
         BigDecimal paymentMoney = BigDecimal.ZERO;
         long time = 0;
         if (!chargingOrder.getOrderSource().equals(2)) {
            serviceMoney = serviceMoney.add(service_reduce);
            paymentMoney = paymentMoney.add(electronic_reduce).add(service_reduce);
         } else {
            serviceMoney = serviceMoney.add(service_reduce.multiply(new BigDecimal("0.8")));
            paymentMoney = paymentMoney.add(electronic_reduce).add(service_reduce.multiply(new BigDecimal("0.8")));
         }
         if (chargingOrder.getStartTime() != null && chargingOrder.getEndTime() != null) {
            LocalDateTime startTime = chargingOrder.getStartTime();
            LocalDateTime endTime = chargingOrder.getEndTime();
            // 计算时间差 单位秒
            time = ChronoUnit.SECONDS.between(startTime, endTime);
         }
         TChargingOrderSummaryData summaryData = new TChargingOrderSummaryData();
         summaryData.setChargingOrderId(chargingOrder.getId());
         summaryData.setChargingCapacity(chargingCapacity);
         summaryData.setChargingDuration(time);
         summaryData.setIncome(paymentMoney.setScale(2, BigDecimal.ROUND_HALF_EVEN));
         summaryData.setElectricPrice(electronic_reduce.setScale(2, BigDecimal.ROUND_HALF_EVEN));
         summaryData.setServicePrice(serviceMoney.setScale(2, BigDecimal.ROUND_HALF_EVEN));
         chargingOrderSummaryDataService.save(summaryData);
         //推送监管平台订单状态和订单详情
         ChargingOrderVo chargingOrderVo = new ChargingOrderVo();
         BeanUtils.copyProperties(chargingOrder, chargingOrderVo);
         chargingMessageClient.pushOrderInfo(chargingOrderVo);
         chargingMessageClient.pushOrderStatus(chargingOrderVo);
                //获取订单的计费策略
                List<AccountingStrategyDetailOrder> accountingStrategyDetailOrderList = accountingStrategyDetailOrderClient.getAllAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
                if (accountingStrategyDetailOrderList.isEmpty()) {
                    return R.fail("计费策略为空,无法计算费用");
                }
                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 (!isBalancePayMode(chargingOrder.getPayMethod()) && 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));
                refundAmount = refundAmount.max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP);
                BigDecimal thirdRefundAmount = refundAmount.min(money(chargingOrder.getThirdPayAmount())).setScale(2, RoundingMode.HALF_UP);
                BigDecimal balanceRefundAmount = refundAmount.subtract(thirdRefundAmount).min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                BigDecimal actualThirdPayAmount = money(chargingOrder.getThirdPayAmount()).subtract(thirdRefundAmount);
                if (actualThirdPayAmount.compareTo(BigDecimal.ZERO) < 0) {
                    actualThirdPayAmount = BigDecimal.ZERO;
                }
                BigDecimal actualBalancePayAmount = money(chargingOrder.getBalancePayAmount()).subtract(balanceRefundAmount);
                if (actualBalancePayAmount.compareTo(BigDecimal.ZERO) < 0) {
                    actualBalancePayAmount = BigDecimal.ZERO;
                }
                refundAmount = thirdRefundAmount.add(balanceRefundAmount);
                chargingOrder.setBalanceRefundAmount(balanceRefundAmount.setScale(2, RoundingMode.HALF_UP));
                chargingOrder.setThirdRefundAmount(thirdRefundAmount.setScale(2, RoundingMode.HALF_UP));
                chargingOrder.setPaymentAmount(actualThirdPayAmount.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);
                chargingOrder = this.getById(chargingOrder.getId());
                Site site = siteClient.getSiteByIds(Arrays.asList(chargingOrder.getSiteId())).getData().get(0);
                //推送三方平台
                if (2 == chargingOrder.getOrderSource() && 1 == site.getIsOpenSynchronization()) {
                    TChargingOrder finalChargingOrder = chargingOrder;
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            tcecClient.notificationEquipChargeStatus(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getOperatorId());
                            tcecClient.notificationStopChargeResult(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getChargingGunId().toString(),
                                    finalChargingOrder.getOperatorId());
                            tcecClient.notificationChargeOrderInfo(finalChargingOrder.getStartChargeSeq(), finalChargingOrder.getOperatorId());
                        }
                    }).start();
                }
                ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
                TChargingOrder finalChargingOrder1 = chargingOrder;
                threadPoolExecutor.execute(()->{
                    //推送成都监管
                    NotificationConnectorChargeStatusVo statusVo = new NotificationConnectorChargeStatusVo();
                    statusVo.setOrderCode(finalChargingOrder1.getCode());
                    statusVo.setChargingGunId(finalChargingOrder1.getChargingGunId());
                    chengDuJianGuanClient.notificationConnectorChargeStatus(statusVo);
                    chengDuJianGuanClient.notificationOrderInfo(statusVo);
                });
                //开始将优惠券优惠的金额添加到明细中
                BigDecimal couponDiscountAmount = chargingOrder.getCouponDiscountAmount();
                if (null != couponDiscountAmount && couponDiscountAmount.compareTo(BigDecimal.ZERO) > 0) {
                    List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()));
                    BigDecimal reduce = list.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                    for (TChargingOrderAccountingStrategy chargingOrderAccountingStrategy : list) {
                        BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodServicePrice();
                        BigDecimal multiply = couponDiscountAmount.multiply(periodServicePrice.divide(reduce, new MathContext(4, RoundingMode.HALF_EVEN)));
                        periodServicePrice = periodServicePrice.subtract(multiply);
                        chargingOrderAccountingStrategy.setPeriodServicePrice(periodServicePrice.setScale(2, RoundingMode.HALF_EVEN));
                        chargingOrderAccountingStrategy.setCouponDiscountAmount(multiply.setScale(2, RoundingMode.HALF_EVEN));
                    }
                    chargingOrderAccountingStrategyService.updateBatchById(list);
                }
                // 将枪状态重置为空闲
                TChargingGun chargingGun = new TChargingGun();
                chargingGun.setId(chargingOrder.getChargingGunId());
                chargingGun.setStatus(2);
                chargingGun.setChargingPower(BigDecimal.ZERO);
                chargingGunClient.updateChargingGunById(chargingGun);
                chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
                //推送状态给三方平台
                if (2 == chargingOrder.getOrderSource() && 1 == site.getIsOpenSynchronization()) {
                    tcecClient.pushChargingGunStatus(chargingGun.getFullNumber(), 2);
                }
                //添加积分
                if (1 == chargingOrder.getOrderSource()) {
                    TIntegralRule integralRule = integralRuleClient.getSet().getData();
                    if (null != integralRule) {
                        TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
                        Integer num1 = JSON.parseObject(integralRule.getChargeCredit()).getInteger("num1");
                        Integer integral = chargingOrder.getServiceCharge().intValue() * num1;
                        if (null != appUser.getVipId()) {
                            TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
                            Integer doubleIntegration = vip.getDoubleIntegration();
                            //双倍积分
                            if (1 == doubleIntegration) {
                                integral *= 2;
                            }
                        }
                        if (integral > 0) {
                            TAppUserIntegralChange appUserIntegralChange = new TAppUserIntegralChange();
                            appUserIntegralChange.setAppUserId(appUser.getId());
                            appUserIntegralChange.setChangeType(2);
                            appUserIntegralChange.setHistoricalIntegral(appUser.getPoints());
                            appUser.setPoints(appUser.getPoints() + integral);
                            appUserIntegralChange.setCurrentIntegral(appUser.getPoints());
                            appUserIntegralChange.setCreateTime(LocalDateTime.now());
                            appUserIntegralChange.setOrderCode(chargingOrder.getCode());
                            appUserIntegralChange.setExtension(chargingOrder.getId().toString());
                            appUserClient.updateAppUser(appUser);
                            appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange);
                        }
                    }
                    //计算用户标签
                    editUserTag(chargingOrder);
                    //用户推荐奖励
                    referralReward(chargingOrder);
                    //开始构建退款费用
                    refundAmount = refundAmount.setScale(2, RoundingMode.HALF_EVEN);
                    Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
                    if (refundAmount.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(refundAmount);
                        chargingOrderRefund.setPayType(rechargePaymentType);
                        chargingOrderRefund.setRefundStatus(1);
                        chargingOrderRefund.setCode(chargingOrder.getCode());
                        chargingOrderRefund.setRefundTitle("充电完成退款");
                        chargingOrderRefund.setRefundContent("充电完成退款");
                        chargingOrderRefund.setRefundReason("充电完成退款");
                        chargingOrderRefund.setRefundRemark("实际充电消费金额:" + chargingOrder.getPaymentAmount());
                        chargingOrderRefund.setRefundTotalAmount(refundAmount);
                        chargingOrderRefund.setPayAmount(rechargeAmount);
                        if (1 == rechargePaymentType) {
                            WxPaymentRefundModel model = new WxPaymentRefundModel();
                            model.setOut_trade_no(chargingOrder.getCode());
                            model.setOut_refund_no(chargingOrderRefund.getRefundCode());
                            model.setReason("充电完成退款");
                            model.setNotify_url("/payment/wx/refund/notify");
                            WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
                            amount.setRefund(thirdRefundAmount.multiply(new BigDecimal(100)).intValue());
                            amount.setTotal(rechargeAmount.multiply(new BigDecimal(100)).intValue());
                            amount.setCurrency("CNY");
                            model.setAmount(amount);
                            R<Map<String, Object>> result = wxPaymentClient.refundOrderR(model);
                            if (200 == result.getCode()) {
                                //手续费
                                Map<String, Object> amount1 = (Map<String, Object>) result.getData().get("amount");
                                Object refund_fee1 = amount1.get("refund_fee");
                                BigDecimal refund_fee = new BigDecimal(null == refund_fee1 ? "0" : refund_fee1.toString()).divide(new BigDecimal(100));
                                chargingOrderRefund.setRefundFee(refund_fee);
                                chargingOrderRefundService.save(chargingOrderRefund);
                            }
                        }
                        if (thirdRefundAmount.compareTo(BigDecimal.ZERO) > 0 && 2 == rechargePaymentType) {
                            RefundReq dto = new RefundReq();
                            dto.setOutTradeNo(chargingOrder.getCode());
                            dto.setOutRequestNo(chargingOrderRefund.getRefundCode());
                            dto.setRefundAmount(thirdRefundAmount.toString());
                            dto.setRefundReason("充电完成退款");
                            RefundResp resp = aliPaymentClient.refund(dto).getData();
                            if (null != resp) {
                                chargingOrderRefundService.save(chargingOrderRefund);
                                this.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                            }
                        }
                        if (thirdRefundAmount.compareTo(BigDecimal.ZERO) > 0 && 3 == rechargePaymentType) {
                            RefundReq dto = new RefundReq();
                            dto.setOutTradeNo(chargingOrder.getRechargeSerialNumber());
                            dto.setOutRequestNo(chargingOrderRefund.getRefundCode());
                            dto.setRefundAmount(thirdRefundAmount.toString());
                            dto.setRefundReason("充电完成退款");
                            RefundResp resp = h5AliPaymentClient.refund(dto).getData();
                            if (null != resp && "10000".equals(resp.getCode())) {
                                chargingOrderRefundService.save(chargingOrderRefund);
                                this.chargingOrderStartupFailureWxRefund(chargingOrderRefund.getRefundCode(), resp.getTradeNo(), "SUCCESS", null);
                            }
                        }
                    }else{
                        //构建退款明细
                        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(refundAmount);
                        chargingOrderRefund.setBalanceRefundAmount(balanceRefundAmount);
                        chargingOrderRefund.setThirdRefundAmount(thirdRefundAmount);
                        chargingOrderRefund.setRefundStatus(2);
                        chargingOrderRefund.setPayType(rechargePaymentType);
                        chargingOrderRefund.setCode(chargingOrder.getCode());
                        chargingOrderRefund.setRefundTitle("充电完成退款");
                        chargingOrderRefund.setRefundContent("充电完成退款");
                        chargingOrderRefund.setRefundReason("充电完成退款");
                        chargingOrderRefund.setRefundRemark("实际充电消费金额:" + chargingOrder.getPaymentAmount());
                        chargingOrderRefund.setRefundTotalAmount(refundAmount);
                        chargingOrderRefund.setPayAmount(rechargeAmount);
                        chargingOrderRefund.setRefundTime(LocalDateTime.now());
                        chargingOrderRefundService.save(chargingOrderRefund);
                        if (balanceRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
                            changeUserBalance(chargingOrder.getAppUserId(), balanceRefundAmount);
                            recordBalanceRefund(chargingOrder, balanceRefundAmount, chargingOrderRefund.getRefundCode());
                        }
                        chargingOrder.setRefundStatus(2);
                        chargingOrder.setRefundTime(LocalDateTime.now());
                        this.updateById(chargingOrder);
                    }
                }
                //添加汇总统计数据
                List<TChargingOrderAccountingStrategy> list4 = chargingOrderAccountingStrategyService.list(new QueryWrapper<TChargingOrderAccountingStrategy>().eq("charging_order_id", chargingOrder.getId()));
                BigDecimal electronic_reduce = list4.stream().map(TChargingOrderAccountingStrategy::getPeriodElectricPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal service_reduce = list4.stream().map(TChargingOrderAccountingStrategy::getPeriodServicePrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal chargingCapacity = list4.stream().map(TChargingOrderAccountingStrategy::getChargingCapacity).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal serviceMoney = BigDecimal.ZERO;
                BigDecimal paymentMoney = BigDecimal.ZERO;
                long time = 0;
                if (!chargingOrder.getOrderSource().equals(2)) {
                    serviceMoney = serviceMoney.add(service_reduce);
                    paymentMoney = paymentMoney.add(electronic_reduce).add(service_reduce);
                } else {
                    serviceMoney = serviceMoney.add(service_reduce.multiply(new BigDecimal("0.8")));
                    paymentMoney = paymentMoney.add(electronic_reduce).add(service_reduce.multiply(new BigDecimal("0.8")));
                }
                if (chargingOrder.getStartTime() != null && chargingOrder.getEndTime() != null) {
                    LocalDateTime startTime = chargingOrder.getStartTime();
                    LocalDateTime endTime = chargingOrder.getEndTime();
                    // 计算时间差 单位秒
                    time = ChronoUnit.SECONDS.between(startTime, endTime);
                }
                TChargingOrderSummaryData summaryData = new TChargingOrderSummaryData();
                summaryData.setChargingOrderId(chargingOrder.getId());
                summaryData.setChargingCapacity(chargingCapacity.setScale(6, RoundingMode.HALF_EVEN));
                summaryData.setChargingDuration(time);
                summaryData.setIncome(paymentMoney.setScale(2, BigDecimal.ROUND_HALF_EVEN));
                summaryData.setElectricPrice(electronic_reduce.setScale(2, BigDecimal.ROUND_HALF_EVEN));
                summaryData.setServicePrice(serviceMoney.setScale(2, BigDecimal.ROUND_HALF_EVEN));
                chargingOrderSummaryDataService.save(summaryData);
                //推送监管平台订单状态和订单详情
                ChargingOrderVo chargingOrderVo = new ChargingOrderVo();
                BeanUtils.copyProperties(chargingOrder, chargingOrderVo);
                chargingMessageClient.pushOrderInfo(chargingOrderVo);
                chargingMessageClient.pushOrderStatus(chargingOrderVo);
            }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
@@ -2981,8 +3370,27 @@
         chargingOrderRefund.setRefundRemark(payOrderQueryDto.getRemark());
         chargingOrderRefund.setRefundTotalAmount(tChargingOrder.getRefundAmount().add(payOrderQueryDto.getRefundAmount()));
         chargingOrderRefund.setPayAmount(tChargingOrder.getPaymentAmount());
         BigDecimal manualRefundAmount = money(payOrderQueryDto.getRefundAmount());
         BigDecimal refundedThirdAmount = money(tChargingOrder.getThirdRefundAmount());
         BigDecimal refundableThirdAmount = money(tChargingOrder.getThirdPayAmount()).subtract(refundedThirdAmount);
         if (refundableThirdAmount.compareTo(BigDecimal.ZERO) < 0) {
            refundableThirdAmount = BigDecimal.ZERO;
         }
         BigDecimal thirdRefundAmount = isBalancePayMode(tChargingOrder.getPayMethod())
               ? manualRefundAmount.min(refundableThirdAmount).setScale(2, RoundingMode.HALF_UP)
               : manualRefundAmount;
         BigDecimal balanceRefundAmount = manualRefundAmount.subtract(thirdRefundAmount).setScale(2, RoundingMode.HALF_UP);
         if (balanceRefundAmount.compareTo(BigDecimal.ZERO) < 0) {
            balanceRefundAmount = BigDecimal.ZERO;
         }
         chargingOrderRefund.setBalanceRefundAmount(balanceRefundAmount);
         chargingOrderRefund.setThirdRefundAmount(thirdRefundAmount);
         
         if (1 == tChargingOrder.getRechargePaymentType()) {
         if (thirdRefundAmount.compareTo(BigDecimal.ZERO) == 0) {
            chargingOrderRefund.setRefundSerialNumber("BALANCE");
            finishManualChargingRefund(tChargingOrder, chargingOrderRefund, manualRefundAmount, balanceRefundAmount, thirdRefundAmount);
         }
         else if (1 == tChargingOrder.getRechargePaymentType()) {
            WxPaymentRefundModel model = new WxPaymentRefundModel();
            model.setOut_trade_no(tChargingOrder.getCode());
            model.setOut_refund_no(chargingOrderRefund.getRefundCode());
@@ -2990,16 +3398,13 @@
            model.setReason("取消订单");
            model.setNotify_url("/payment/wx/refund/notify");
            WxPaymentRefundModel.RefundAmount amount = new WxPaymentRefundModel.RefundAmount();
            amount.setRefund(payOrderQueryDto.getRefundAmount().multiply(new BigDecimal(100)).intValue());
            amount.setTotal(tChargingOrder.getRechargeAmount().multiply(new BigDecimal(100)).intValue());
            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.setCurrency("CNY");
            model.setAmount(amount);
            R<Map<String, Object>> orderR = wxPaymentClient.refundOrderR(model);
            if (200 == orderR.getCode()) {
               tChargingOrder.setRefundStatus(2);
               tChargingOrder.setRefundAmount((tChargingOrder.getRefundAmount() == null ? BigDecimal.valueOf(0) : tChargingOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
               this.baseMapper.updateById(tChargingOrder);
               chargingOrderRefundService.save(chargingOrderRefund);
               finishManualChargingRefund(tChargingOrder, chargingOrderRefund, manualRefundAmount, balanceRefundAmount, thirdRefundAmount);
               //手续费
               Map<String, Object> amount1 = (Map<String, Object>) orderR.getData().get("amount");
               Object refund_fee1 = amount1.get("refund_fee");
@@ -3009,33 +3414,27 @@
            }
         }
         
         if (2 == tChargingOrder.getRechargePaymentType()) {
         else if (2 == tChargingOrder.getRechargePaymentType()) {
            RefundReq dto = new RefundReq();
            dto.setOutTradeNo(tChargingOrder.getCode());
            dto.setOutRequestNo(tChargingOrder.getCode());
            dto.setRefundAmount(payOrderQueryDto.getRefundAmount().toString());
            dto.setRefundAmount(thirdRefundAmount.toString());
            dto.setRefundReason("取消订单");
            RefundResp resp = aliPaymentClient.refund(dto).getData();
            if (null != resp) {
               chargingOrderRefund.setRefundStatus(2);
               chargingOrderRefund.setRefundAmount((tChargingOrder.getRefundAmount() == null ? BigDecimal.valueOf(0) : tChargingOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
               this.baseMapper.updateById(tChargingOrder);
               chargingOrderRefundService.save(chargingOrderRefund);
               finishManualChargingRefund(tChargingOrder, chargingOrderRefund, manualRefundAmount, balanceRefundAmount, thirdRefundAmount);
               
            }
         }
         if (3 == tChargingOrder.getRechargePaymentType()) {
         else if (3 == tChargingOrder.getRechargePaymentType()) {
            RefundReq dto = new RefundReq();
            dto.setOutTradeNo(tChargingOrder.getRechargeSerialNumber());
            dto.setOutRequestNo(tChargingOrder.getCode());
            dto.setRefundAmount(payOrderQueryDto.getRefundAmount().toString());
            dto.setRefundAmount(thirdRefundAmount.toString());
            dto.setRefundReason("取消订单");
            RefundResp resp = h5AliPaymentClient.refund(dto).getData();
            if (null != resp && "10000".equals(resp.getCode())) {
               chargingOrderRefund.setRefundStatus(2);
               chargingOrderRefund.setRefundAmount((tChargingOrder.getRefundAmount() == null ? BigDecimal.valueOf(0) : tChargingOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
               this.baseMapper.updateById(tChargingOrder);
               chargingOrderRefundService.save(chargingOrderRefund);
               finishManualChargingRefund(tChargingOrder, chargingOrderRefund, manualRefundAmount, balanceRefundAmount, thirdRefundAmount);
               
            }
         }
@@ -3144,6 +3543,8 @@
         vipOrderRefund.setVipOrderId(vipOrder.getId());
         vipOrderRefund.setRefundAmount(payOrderQueryDto.getRefundAmount());
         vipOrderRefund.setRefundStatus(1);
         vipOrderRefund.setPayTime(vipOrder.getPayTime());
         vipOrderRefund.setPayCode(vipOrder.getCode());
         vipOrderRefund.setPayType(vipOrder.getPaymentType());
         vipOrderRefund.setRefundTime(LocalDateTime.now());
         vipOrderRefund.setCode(vipOrder.getCode());
@@ -3226,7 +3627,8 @@
   public TChargingOrder getChargingOrderByLicensePlate(GetChargingOrderByLicensePlate query) {
      TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getPlateNum, query.getLicensePlate())
            .eq(TChargingOrder::getDelFlag, 0).between(TChargingOrder::getStartTime, query.getStartTime(), LocalDateTime.now())
            .eq(TChargingOrder::getRechargePaymentStatus, 2).in(TChargingOrder::getStatus, Arrays.asList(4, 5)));
            .eq(TChargingOrder::getRechargePaymentStatus, 2).in(TChargingOrder::getStatus, Arrays.asList(3, 4, 5))
                .last(" order by start_time desc limit 0, 1"));
      return one;
   }
   
@@ -3991,8 +4393,14 @@
   public List<Map<String, Object>> needElec(List<Integer> siteIds, ChargingStatisticsQueryDto statisticsQueryDto) {
      return this.baseMapper.needElec(siteIds, statisticsQueryDto);
   }
   @Override
    @Override
    public Map<String, Object> getChargingOrderCount(List<Integer> siteIds, String time) {
        time = time.split(" ")[0];
        return this.baseMapper.getChargingOrderCount(siteIds, time);
    }
    @Override
   public List<Map<String, Object>> getHourType(List<Integer> siteIds, ChargingDetailQueryDto statisticsQueryDto) {
      return this.baseMapper.getHourType(siteIds, statisticsQueryDto);
   }
@@ -4339,10 +4747,10 @@
            long between = ChronoUnit.SECONDS.between(startTime, endTime);
            time += between;
         }
         TChargingOrderSummaryData summaryData = new TChargingOrderSummaryData();
         summaryData.setChargingOrderId(chargingOrderVO.getId());
         summaryData.setChargingCapacity(chargingCapacity);
         summaryData.setChargingCapacity(chargingCapacity.setScale(6, RoundingMode.HALF_EVEN));
         summaryData.setChargingDuration(time);
         summaryData.setIncome(paymentMoney.setScale(2, BigDecimal.ROUND_HALF_EVEN));
         summaryData.setElectricPrice(electronic_reduce.setScale(2, BigDecimal.ROUND_HALF_EVEN));
@@ -4457,4 +4865,35 @@
   public List<TChargingOrder> findEndChargingOrder() {
      return this.baseMapper.findEndChargingOrder();
   }
   /**
    * 获取需要手动修改订单状态的数据
    * @return
    */
   @Override
   public List<TChargingOrder> findUpStatusChargingOrder() {
      return this.baseMapper.findUpStatusChargingOrder();
   }
   /**
    * 查询充电算账单数据
    * @param startTime
    * @param endTime
    */
   @Override
    public List<Map<String, Object>> getChargingSettlementBill(String startTime, String endTime, Integer dateType) {
      return this.baseMapper.getChargingSettlementBill(startTime, endTime, dateType);
    }
   /**
    * 查询账户结算账单数据
    * @param startTime
    * @param endTime
    * @return
    */
   @Override
   public List<Map<String, Object>> getAccountSettlementStatement(String startTime, String endTime, Integer rechargePaymentType) {
      return this.baseMapper.getAccountSettlementStatement(startTime, endTime, rechargePaymentType);
   }
}