Pu Zhibing
2024-10-22 b4b44f2021dbf083b7057fb7e192b72d08b4bf17
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -38,7 +38,7 @@
import com.ruoyi.order.api.query.SettlementListQuery;
import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery;
import com.ruoyi.order.api.vo.*;
import com.ruoyi.order.api.vo.SecurityDetection;
import com.ruoyi.order.api.vo.PlatformStopChargingReplyVO;
import com.ruoyi.order.dto.*;
import com.ruoyi.order.mapper.TChargingOrderMapper;
import com.ruoyi.order.mapper.TSettlementConfirmMapper;
@@ -47,6 +47,7 @@
import com.ruoyi.order.service.TChargingOrderService;
import com.ruoyi.order.service.TOrderEvaluateService;
import com.ruoyi.order.service.*;
import com.ruoyi.order.vo.EndOfChargePageInfo;
import com.ruoyi.other.api.domain.*;
import com.ruoyi.order.vo.ChargingOrderListInfoVO;
import com.ruoyi.other.api.feignClient.*;
@@ -56,7 +57,6 @@
import com.ruoyi.payment.api.model.RefundResp;
import com.ruoyi.payment.api.model.WxPaymentRefundModel;
import com.ruoyi.payment.api.vo.*;
import com.ruoyi.system.api.feignClient.SysUserClient;
import io.seata.spring.annotation.GlobalTransactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -65,14 +65,15 @@
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.time.temporal.WeekFields;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
@@ -97,8 +98,7 @@
   @Resource
   private SiteClient siteClient;
   @Resource
   private AppUserCarClient appUserCarClient;
   @Resource
@@ -139,16 +139,12 @@
   @Resource
   private TOrderEvaluateService orderEvaluateService;
   @Resource
   private AccountingStrategyDetailClient accountingStrategyDetailClient;
   @Resource
   private AccountingStrategyDetailOrderClient accountingStrategyDetailOrderClient;
   @Resource
   private AccountingStrategyOrderClient accountingStrategyOrderClient;
   @Resource
   private AccountingStrategyClient accountingStrategyClient;
@@ -209,6 +205,7 @@
      Map<String, Object> map = new HashMap<>();
      int size = this.baseMapper.getMyChargingOrderList(appUserId, 1, null, null).size();
      map.put("number", size);
      query.setPageCurr((query.getPageCurr() - 1) * query.getPageSize());
      List<TChargingOrder> list = this.baseMapper.getMyChargingOrderList(appUserId, query.getType(), query.getPageCurr(), query.getPageSize());
      List<MyChargingOrderList> orderLists = new ArrayList<>();
      for (TChargingOrder tChargingOrder : list) {
@@ -262,8 +259,8 @@
      }else{
         myChargingOrderInfo.setLicensePlate("无");
      }
      myChargingOrderInfo.setStartTime(chargingOrder.getStartTime().toInstant(ZoneOffset.of("+8")).toEpochMilli());
      myChargingOrderInfo.setEndTime(chargingOrder.getEndTime().toInstant(ZoneOffset.of("+8")).toEpochMilli());
      myChargingOrderInfo.setStartTime(chargingOrder.getStartTime().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() * 1000);
      myChargingOrderInfo.setEndTime(chargingOrder.getEndTime().atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() * 1000);
      myChargingOrderInfo.setOrderAmount(chargingOrder.getOrderAmount());
      myChargingOrderInfo.setPaymentAmount(chargingOrder.getPaymentAmount());
      myChargingOrderInfo.setRechargeAmount(chargingOrder.getRechargeAmount());
@@ -295,7 +292,7 @@
         myChargingOrderInfo.setCurrentAndVoltage(currentAndVoltage);
         //在MongoDB中获取数据
         List<Integer> soc = dataList.stream().map(UploadRealTimeMonitoringData::getSoc).collect(Collectors.toList());
         List<BigDecimal> po = dataList.stream().map(s -> s.getOutput_current().multiply(s.getOutput_voltage()).divide(new BigDecimal(1000))).collect(Collectors.toList());
         List<BigDecimal> po = dataList.stream().map(s -> s.getOutput_current().multiply(s.getOutput_voltage()).divide(new BigDecimal(1000),2, RoundingMode.HALF_DOWN)).collect(Collectors.toList());
         List<Map<String, Object>> power = new ArrayList<>();
         for (int i = 0; i < time.size(); i++) {
            Map<String, Object> map = new HashMap<>();
@@ -308,7 +305,7 @@
         }
         myChargingOrderInfo.setPower(power);
      }
      myChargingOrderInfo.setActionable(myChargingOrderInfo.getEndTime() + 604800000L > System.currentTimeMillis() ? 0 : 1);
      myChargingOrderInfo.setActionable(myChargingOrderInfo.getEndTime() + 604800000L < System.currentTimeMillis() ? 0 : 1);
      return myChargingOrderInfo;
   }
   
@@ -321,6 +318,8 @@
   @Override
   public List<MyChargingOrderList> getNoInvoicedOrder(GetNoInvoicedOrder query) {
      Long appUserId = tokenService.getLoginUserApplet().getUserId();
      query.setPageCurr((query.getPageCurr() - 1) * query.getPageSize());
      List<TChargingOrder> orderList = this.baseMapper.getNoInvoicedOrder(appUserId, query.getMonth(), query.getPageCurr(), query.getPageSize());
      List<MyChargingOrderList> list = new ArrayList<>();
      for (TChargingOrder tChargingOrder : orderList) {
@@ -434,6 +433,7 @@
      chargingOrder.setAppUserId(userId);
      chargingOrder.setAppUserCarId(addChargingOrder.getAppUserCarId());
      TChargingGun tChargingGun = chargingGunClient.getChargingGunById(addChargingOrder.getId()).getData();
      TChargingPile chargingPile = chargingPileClient.getChargingPileById(tChargingGun.getChargingPileId()).getData();
      chargingOrder.setSiteId(tChargingGun.getSiteId());
      chargingOrder.setChargingPileId(tChargingGun.getChargingPileId());
      chargingOrder.setChargingGunId(addChargingOrder.getId());
@@ -441,8 +441,9 @@
      chargingOrder.setRechargePaymentStatus(1);
      chargingOrder.setRechargeAmount(addChargingOrder.getPaymentAmount());
      chargingOrder.setAppCouponId(addChargingOrder.getAppUserCouponId());
      chargingOrder.setVipDiscount(new BigDecimal(10));
      chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
      chargingOrder.setOrderSource(0);
      chargingOrder.setTitle("【充电桩充电】" + chargingPile.getNumber() + "号桩/" + tChargingGun.getCode() + "号枪");
      
      Site site = siteClient.getSiteByIds(Arrays.asList(tChargingGun.getSiteId())).getData().get(0);
      Integer accountingStrategyId = tChargingGun.getAccountingStrategyId();
@@ -469,7 +470,7 @@
         TAppUserVipDetail vipDetail = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
         if(null != vipDetail){
            Integer chargeNum = vipDetail.getChargeNum();
            if(0 > chargeNum){
            if(0 < chargeNum){
               chargingOrder.setVipDiscount(discount);
            }
         }
@@ -557,77 +558,83 @@
      //根据支付金额,获取出使用的计费策略明细
      //计算电费金额和服务费
      BigDecimal serviceCharge = BigDecimal.ZERO;
      BigDecimal electrovalence = BigDecimal.ZERO;
      BigDecimal discountAmount = BigDecimal.ZERO;
      BigDecimal discount = chargingOrder.getVipDiscount();
      //先根据额定功率计算出每秒充电度数,然后计算出支付金额能充多少度电
      TChargingGun tChargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
      //1秒充电度数
      BigDecimal s_degrees = tChargingGun.getRatedPower().divide(new BigDecimal(3600), 6, RoundingMode.HALF_EVEN);
      TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
      List<AccountingStrategyDetailOrder> list = accountingStrategyDetailOrderClient.getAllAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
      for (AccountingStrategyDetailOrder accountingStrategyDetailOrder : list) {
         Integer start = Integer.valueOf(accountingStrategyDetailOrder.getStartTime().replaceAll(":", ""));
         Integer end = Integer.valueOf(accountingStrategyDetailOrder.getEndTime().replaceAll(":", ""));
         String[] split = accountingStrategyDetailOrder.getEndTime().split(":");
         if(now >= start && now < end){
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
            calendar.set(Calendar.MINUTE, Integer.valueOf(split[1]));
            //到此策略结束的秒数
            if(null == nowTimeMillis){
               String[] split1 = accountingStrategyDetailOrder.getStartTime().split(":");
               Calendar calendar1 = Calendar.getInstance();
               calendar1.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split1[0]));
               calendar1.set(Calendar.MINUTE, Integer.valueOf(split1[1]));
               nowTimeMillis = calendar.getTimeInMillis();
      //判断会员是否还有充电优惠次数,计算会员优惠的折扣金额
      if(null != appUser.getVipId()){
         GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
         getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
         getAppUserVipDetail.setVipId(appUser.getVipId());
         TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
         if(null != data && data.getChargeNum() > 0){
            //计算折扣
            List<AccountingStrategyDetailOrder> list = accountingStrategyDetailOrderClient.getAllAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
            //将数据叠加两份,处理跨天的情况
            list.addAll(list);
            boolean sta = false;
            for (AccountingStrategyDetailOrder accountingStrategyDetailOrder : list) {
               Integer start = Integer.valueOf(accountingStrategyDetailOrder.getStartTime().replaceAll(":", ""));
               Integer end = Integer.valueOf(accountingStrategyDetailOrder.getEndTime().replaceAll(":", ""));
               String[] split = accountingStrategyDetailOrder.getEndTime().split(":");
               if(sta || (now >= start && now < end)){
                  sta = true;
                  Calendar end_calendar = Calendar.getInstance();
                  end_calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
                  end_calendar.set(Calendar.MINUTE, Integer.valueOf(split[1]));
                  //到此策略结束的秒数
                  if(null == nowTimeMillis){
                     String[] split1 = accountingStrategyDetailOrder.getStartTime().split(":");
                     Calendar start_calendar = Calendar.getInstance();
                     start_calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split1[0]));
                     start_calendar.set(Calendar.MINUTE, Integer.valueOf(split1[1]));
                     nowTimeMillis = start_calendar.getTimeInMillis();
                  }
                  //间隔秒数
                  long m = (end_calendar.getTimeInMillis() - nowTimeMillis) / 1000;
                  //每秒需要支付的服务费金额
                  BigDecimal total_until = accountingStrategyDetailOrder.getElectrovalence().add(accountingStrategyDetailOrder.getServiceCharge());
                  BigDecimal s_total_amount = s_degrees.multiply(total_until);
                  //每秒需要支付的服务费金额
                  BigDecimal s_server_amount = s_degrees.multiply(accountingStrategyDetailOrder.getServiceCharge());
                  //计算剩余金额能充多长时间的电
                  long times = rechargeAmount1.divide(s_total_amount, 0, RoundingMode.DOWN).longValue();
                  if(times > m){
                     //充电时间跨度两个计费策略,需要继续对下一个策略进行计算
                     serviceCharge = s_server_amount.multiply(new BigDecimal(m));
                     discountAmount = discountAmount.add(serviceCharge.multiply((new BigDecimal(1).subtract(discount))));
                     rechargeAmount1 = rechargeAmount1.subtract(s_total_amount.multiply(new BigDecimal(m)));
                     nowTimeMillis = null;
                  }else{
                     serviceCharge = s_server_amount.multiply(new BigDecimal(times));
                     discountAmount = discountAmount.add(serviceCharge.multiply((new BigDecimal(1).subtract(discount))));
                     break;
                  }
               }
            }
            long m = (calendar.getTimeInMillis() - nowTimeMillis) / 1000;
            //每度电的单价
            BigDecimal total_unit = accountingStrategyDetailOrder.getElectrovalence().add(accountingStrategyDetailOrder.getServiceCharge());
            //每秒需要支付的金额
            BigDecimal multiply = s_degrees.multiply(total_unit);
            //计算充值金额能充多长时间的电
            long times = rechargeAmount1.divide(multiply, 0, RoundingMode.DOWN).longValue();
            if(times > m){
               //充电时间跨度两个计费策略,需要继续对下一个策略进行计算
               electrovalence = accountingStrategyDetailOrder.getElectrovalence().multiply(s_degrees).multiply(new BigDecimal(m));
               serviceCharge = accountingStrategyDetailOrder.getServiceCharge().multiply(s_degrees).multiply(new BigDecimal(m));
               discountAmount = discountAmount.add(serviceCharge.multiply((new BigDecimal(10).subtract(discount)).divide(new BigDecimal(10))));
               rechargeAmount1 = rechargeAmount1.subtract(multiply.multiply(new BigDecimal(m)));
               nowTimeMillis = null;
            }else{
               electrovalence = accountingStrategyDetailOrder.getElectrovalence().multiply(s_degrees).multiply(new BigDecimal(times));
               serviceCharge = accountingStrategyDetailOrder.getServiceCharge().multiply(s_degrees).multiply(new BigDecimal(times));
               discountAmount = discountAmount.add(serviceCharge.multiply((new BigDecimal(10).subtract(discount)).divide(new BigDecimal(10))));
               break;
            if(discountAmount.compareTo(BigDecimal.ZERO) >= 0){
               //计算会员最大优惠金额
               TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
               BigDecimal maximumDeduction = vip.getMaximumDeduction();
               //普通会员有最高优惠限制
               if(vip.getType() == 1 && discountAmount.compareTo(maximumDeduction) > 0){
                  discountAmount = maximumDeduction;
               }
            }
            discountAmount = discountAmount.setScale(4, RoundingMode.HALF_EVEN);
         }
      }
      if(discountAmount.compareTo(BigDecimal.ZERO) >= 0){
         //计算会员最大优惠金额
         if(null != appUser.getVipId()){
            TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
            BigDecimal maximumDeduction = vip.getMaximumDeduction();
            //普通会员有最高优惠限制
            if(vip.getType() == 1 && discountAmount.compareTo(maximumDeduction) > 0){
               discountAmount = maximumDeduction;
            }
            //判断会员是否还有充电优惠次数
            GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
            getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
            getAppUserVipDetail.setVipId(appUser.getVipId());
            TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
            if(null != data && data.getChargeNum() > 0){
               data.setChargeNum(data.getChargeNum() - 1);
               appUserVipDetailClient.updateAppUserVipDetail(data);
               //会员有充电优惠次数,直接将优惠金额加入到充电费用中增加充电时长
               electrovalence = electrovalence.add(discountAmount);
            }
         }
      }
      chargingOrder.setChargeAmount(electrovalence);
      //机子上显示的金额为用户充值的金额+会员折扣金额
      BigDecimal account_balance = chargingOrder.getRechargeAmount().add(discountAmount).setScale(4, RoundingMode.HALF_EVEN);
      chargingOrder.setChargeAmount(account_balance);
      chargingOrder.setVipDiscountAmount(discountAmount);
      this.updateById(chargingOrder);
@@ -640,11 +647,9 @@
      platformStartCharging.setCharging_gun_code(tChargingGun.getCode());
      //使用订单id作为逻辑卡号
      platformStartCharging.setCard_number(chargingOrder.getId().toString());
      platformStartCharging.setAccount_balance(electrovalence);
      System.err.println("-------------------远程调起开始充电请求-------------------");
      System.err.println(platformStartCharging.toString());
      platformStartCharging.setAccount_balance(account_balance);
      log.error(chargingOrder.getCode() + ":-------------------远程调起开始充电请求-------------------" + platformStartCharging.toString());
      sendMessageClient.platformStartCharging(platformStartCharging);
      //异步线程检测远程启动的应答结果。如果失败,则需要全额退款
      Long id = chargingOrder.getId();
@@ -676,17 +681,19 @@
      if(null != securityDetection){
         PreChargeCheck preChargeCheck1 =  redisService.getCacheObject("AQJC_" + chargingOrder.getChargingGunId());
         if(null != preChargeCheck1){
            preChargeCheck1.setElectronicLockLock(preChargeCheck1.getElectronicLockLock());
            preChargeCheck1.setElectronicLockLock(true);
            preChargeCheck1.setInsulationTesting(true);
            preChargeCheck1.setSecureConnectionDetection(preChargeCheck1.getSecureConnectionDetection());
            preChargeCheck1.setSecureConnectionDetection(securityDetection.getSecure_connection() == 1);
            preChargeCheck1.setStartupSuccess(1);
            redisService.setCacheObject("AQJC_" + chargingOrder.getChargingGunId(), preChargeCheck1, 24L, TimeUnit.HOURS);
         }
      }
      
      List<PlatformStartChargingReply> data = platformStartChargingReplyClient.getPlatformStartChargingReply(code).getData();
      System.err.println(code + ":-------------------开始检查调起充电结果-------------------");
      System.err.println(data.toString());
      if(null == data){
         return false;
      }
      log.error(code + ":-------------------开始检查调起充电结果-------------------" + data.toString());
      if(data.size() != 0){
         PlatformStartChargingReply platformStartChargingReply = data.get(1);
         Integer startup_result = platformStartChargingReply.getStartup_result();
@@ -725,9 +732,8 @@
         redisService.setCacheObject(key, preChargeCheck1, 24L, TimeUnit.HOURS);
         return true;
      }else{
         log.error(code + ":未上传开启充电结果........");
         Integer counter = boot_failed_map.get(code);
         log.error(code + ":-------------------未上传开启充电结果-------------------" + counter);
         PreChargeCheck preChargeCheck1 = redisService.getCacheObject(key);
         //5分钟内未启动成功,退回金额。
         if(null == counter || counter < 300){
@@ -762,27 +768,26 @@
    * @param securityDetection
    */
   @Override
   public void securityDetection(SecurityDetection securityDetection){
   public void securityDetection(SecurityDetectionVO securityDetection){
      GetChargingGunByCode code = new GetChargingGunByCode();
      code.setCharging_pile_code(securityDetection.getCharging_pile_code());
      code.setCharging_gun_code(securityDetection.getCharging_gun_code());
      TChargingGun chargingGun = chargingGunClient.getChargingGunByCode(code).getData();
      PreChargeCheck preChargeCheck1 =  redisService.getCacheObject("AQJC_" + chargingGun.getId());
      PreChargeCheck preChargeCheck1 = redisService.getCacheObject("AQJC_" + chargingGun.getId());
      if(null != preChargeCheck1){
         preChargeCheck1.setElectronicLockLock(preChargeCheck1.getElectronicLockLock());
         preChargeCheck1.setElectronicLockLock(true);
         preChargeCheck1.setInsulationTesting(true);
         preChargeCheck1.setSecureConnectionDetection(preChargeCheck1.getSecureConnectionDetection());
         preChargeCheck1.setStartupSuccess(1);
         preChargeCheck1.setSecureConnectionDetection(securityDetection.getSecure_connection() == 1);
         redisService.setCacheObject("AQJC_" + chargingGun.getId(), preChargeCheck1, 24L, TimeUnit.HOURS);
      }
   }
   
   /**
    * 启动充电应发
    * 启动充电应答
    * @param message
    */
   @Override
   public void startChargeSuccessfully(PlatformStartChargingReplyMessage message) {
   public void startChargeSuccessfully(PlatformStartChargingReplyMessageVO message) {
      Integer startup_result = message.getStartup_result();
      Integer failure_cause = message.getFailure_cause();
      TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, message.getTransaction_serial_number()));
@@ -792,11 +797,9 @@
      String code = order.getCode();
      PreChargeCheck preChargeCheck1 =  redisService.getCacheObject("AQJC_" + order.getChargingGunId());
      if(null != preChargeCheck1){
         preChargeCheck1.setElectronicLockLock(preChargeCheck1.getElectronicLockLock());
         preChargeCheck1.setElectronicLockLock(true);
         preChargeCheck1.setInsulationTesting(true);
         preChargeCheck1.setSecureConnectionDetection(preChargeCheck1.getSecureConnectionDetection());
         preChargeCheck1.setStartupSuccess(1);
         redisService.setCacheObject("AQJC_" + order.getChargingGunId(), preChargeCheck1, 24L, TimeUnit.HOURS);
      }
      if(0 == startup_result){
         //启动失败
@@ -812,6 +815,7 @@
         order.setStatus(3);
         order.setStartTime(LocalDateTime.now());
      }
      redisService.setCacheObject("AQJC_" + order.getChargingGunId(), preChargeCheck1, 24L, TimeUnit.HOURS);
      this.updateById(order);
   }
   
@@ -820,6 +824,7 @@
    * @param code
    */
   public void refund(String code){
      log.error(code + ":-------------------充电启动失败,执行退款-------------------");
      TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, code));
      if(chargingOrder.getStatus() == 2){
         Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
@@ -885,13 +890,11 @@
    * @return
    */
   public AjaxResult chargingOrderStartupFailureWxRefund(String out_refund_no, String refund_id, String tradeState, String success_time){
      if("SUCCESS".equals(tradeState)){
         TChargingOrderRefund one = chargingOrderRefundService.getOne(new LambdaQueryWrapper<TChargingOrderRefund>().eq(TChargingOrderRefund::getRefundCode, out_refund_no));
         one.setRefundSerialNumber(refund_id);
         one.setRefundStatus(2);
         one.setRefundTime(LocalDateTime.parse(success_time, DateTimeFormatter.ofPattern("yyyy-MM-DDTHH:mm:ss+TIMEZONE")));
         chargingOrderRefundService.updateById(one);
      }
      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);
      return AjaxResult.success();
   }
@@ -907,7 +910,7 @@
   public ChargingDetails getChargingDetails(Integer id) {
      Long userId = tokenService.getLoginUserApplet().getUserId();
      TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, userId).eq(TChargingOrder::getChargingGunId, id)
            .in(TChargingOrder::getStatus, Arrays.asList(1, 2, 3)).eq(TChargingOrder::getRechargePaymentStatus, 2).eq(TChargingOrder::getDelFlag, 0));
            .eq(TChargingOrder::getRechargePaymentStatus, 2).eq(TChargingOrder::getDelFlag, 0).orderByDesc(TChargingOrder::getStartTime).last(" limit 0, 1"));
      if(null == one){
         return null;
      }
@@ -929,7 +932,9 @@
         chargingDetails.setCompletionRatio(data.getSoc());
         chargingDetails.setRemainingChargeTime(data.getTime_remaining());
         chargingDetails.setChargedDegrees(data.getCharging_degree());
         chargingDetails.setChargedTime(data.getCumulative_charging_time());
         Integer h = Integer.valueOf(data.getCumulative_charging_time() / 60);
         Integer m = Integer.valueOf(data.getCumulative_charging_time() % 60);
         chargingDetails.setChargedTime(String.format("%02d", h) + ":" + String.format("%02d", m));
      }
      ChargingHandshake chargingHandshake = chargingHandshakeClient.getDataByOrderCode(one.getCode()).getData();
      if(null != chargingHandshake && null != data && null != one.getAppUserCarId()){
@@ -954,13 +959,103 @@
   public AjaxResult stopCharging(String id) {
      TChargingOrder chargingOrder = this.getById(id);
      Integer status = chargingOrder.getStatus();
      if(status != 3){
         return AjaxResult.error("还未开始充电");
      }
      if(status == 4 || status == 5){
         return AjaxResult.error("不能重复操作");
      }
      chargingOrder.setStatus(4);
      chargingOrder.setEndTime(LocalDateTime.now());
      chargingOrder.setEndMode(1);
      this.updateById(chargingOrder);
      
      String code1 = chargingOrder.getCode();
      TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
      //异步线程处理停机
      ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1);
      cachedThreadPool.execute(()->{
         //调用硬件停止充电,停止成功后开始计算费用退款
         TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingOrder.getChargingPileId()).getData();
         PlatformStopCharging platformStopCharging = new PlatformStopCharging();
         platformStopCharging.setCharging_pile_code(chargingPile.getCode());
         platformStopCharging.setCharging_gun_code(chargingGun.getCode());
         sendMessageClient.platformStopCharging(platformStopCharging);
         log.error(code1 + ":-------------------远程停止充电请求-------------------");
         log.error(platformStopCharging.toString());
         //开始查询停机应答,成功后开始计费费用
         boolean stop_status = false;
         for (int i = 0; i < 60; i++) {
            TChargingOrder chargingOrder1 = this.getById(id);
            if(chargingOrder1.getStatus() != 3){
               stop_status = true;
               break;
            }
            GetPlatformStopChargingReply query = new GetPlatformStopChargingReply();
            query.setCharging_gun_code(chargingGun.getCode());
            query.setCharging_pile_code(chargingPile.getCode());
            //将时间转换成UTC时间后查询数据(mongodb存储时间以UTC格式存储)
            ZoneId zoneId = ZoneId.systemDefault();
            ZonedDateTime zonedDateTime = ZonedDateTime.of(chargingOrder.getEndTime(), zoneId);
            ZonedDateTime endTime = zonedDateTime.withZoneSameInstant(ZoneId.of("UTC"));
            query.setEnd_time(endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            PlatformStopChargingReply reply = platformStopChargingReplyClient.getPlatformStopChargingReply(query).getData();
            log.error(code1 + ":-------------------查询远程停止充电应答-------------------");
            if(null == reply){
               log.error(code1 + ":-------------------远程停止充电应答无数据-------------------");
               try {
                  Thread.sleep(1000);
               } catch (InterruptedException e) {
                  throw new RuntimeException(e);
               }
               continue;
            }
            log.error(reply.toString());
            if(0 == reply.getStop_result()){
               String failure_cause = "";
               switch (reply.getFailure_cause()){
                  case 0:
                     failure_cause = "无";
                     break;
                  case 1:
                     failure_cause = "设备编号不匹配";
                     break;
                  case 2:
                     failure_cause = "枪未处于充电状态";
                     break;
                  case 3:
                     failure_cause = "其他";
                     break;
               }
               log.error(code1 + ":停机失败:订单号:{},失败原因:{}", chargingOrder.getCode(), failure_cause);
               try {
                  Thread.sleep(1000);
               } catch (InterruptedException e) {
                  throw new RuntimeException(e);
               }
            }else{
               log.error(code1 + ":-------------------远程停止充电请求成功-------------------");
               stop_status = true;
               break;
            }
         }
         if(stop_status){
            chargingOrder.setEndMode(1);
            this.updateById(chargingOrder);
         }else{
            log.error(code1 + ":-------------------远程停止充电应答最终失败-------------------");
         }
      });
      return AjaxResult.success();
   }
   /**
    * 结束充电后处理用户标签数据
    * @param chargingOrder
    */
   public void editUserTag(TChargingOrder chargingOrder){
      //处理用户标签数据
      List<TUserTag> data = userTagClient.getAllUserTag().getData();
      //累计充电次数
@@ -1017,63 +1112,14 @@
            }
         }
      }
      //异步线程处理停机
      ExecutorService cachedThreadPool = Executors.newFixedThreadPool(1);
      cachedThreadPool.execute(()->{
         //调用硬件停止充电,停止成功后开始计算费用退款
         TChargingPile chargingPile = chargingPileClient.getChargingPileById(chargingOrder.getChargingPileId()).getData();
         TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
         PlatformStopCharging platformStopCharging = new PlatformStopCharging();
         platformStopCharging.setCharging_pile_code(chargingPile.getCode());
         platformStopCharging.setCharging_gun_code(chargingGun.getCode());
         sendMessageClient.platformStopCharging(platformStopCharging);
         //开始查询停机应答,成功后开始计费费用
         for (int i = 0; i < 60; i++) {
            GetPlatformStopChargingReply query = new GetPlatformStopChargingReply();
            query.setCharging_gun_code(chargingGun.getCode());
            query.setCharging_pile_code(chargingPile.getCode());
            PlatformStopChargingReply reply = platformStopChargingReplyClient.getPlatformStopChargingReply(query).getData();
            if(null == reply){
               try {
                  Thread.sleep(1000);
               } catch (InterruptedException e) {
                  throw new RuntimeException(e);
               }
               continue;
            }
            if(0 == reply.getStop_result()){
               String failure_cause = "";
               switch (reply.getFailure_cause()){
                  case 0:
                     failure_cause = "无";
                     break;
                  case 1:
                     failure_cause = "设备编号不匹配";
                     break;
                  case 2:
                     failure_cause = "枪未处于充电状态";
                     break;
                  case 3:
                     failure_cause = "其他";
                     break;
               }
               log.error("停机失败:订单号:{},失败原因:{}", chargingOrder.getCode(), failure_cause);
               throw new RuntimeException(failure_cause);
            }
            // 将枪状态重置为空闲
            chargingGun.setStatus(2);
            chargingGunClient.updateChargingGunById(chargingGun);
            //计算费用,处理退款
            endCharge(chargingOrder);
            break;
         }
      });
   }
   /**
    * 推荐奖励(被推荐首单奖励)
    * @param chargingOrder
    */
   public void referralReward(TChargingOrder chargingOrder){
      //处理推荐奖励(被推荐首单奖励)
      TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
      long count = this.count(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, chargingOrder.getAppUserId())
@@ -1117,172 +1163,60 @@
         appUserIntegralChange.setHistoricalIntegral(appUser1.getPoints());
         appUserIntegralChange.setCurrentIntegral(appUser1.getPoints() + num1);
         appUserIntegralChange.setCreateTime(LocalDateTime.now());
         appUserIntegralChange.setOrderCode(chargingOrder.getCode());
         appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange);
         appUser1.setPoints(appUser1.getPoints() + num1);
         appUserClient.updateAppUser(appUser1);
      }
      return AjaxResult.success();
   }
   /**
    * 手动结束后的费用计算和退款逻辑
    * 停止充电应答结果处理
    * @param platformStopChargingReply
    */
   @GlobalTransactional(rollbackFor = Exception.class)
   public void endCharge(TChargingOrder chargingOrder){
      //如果使用优惠券需要判断优惠券是否满足使用条件
      //根据实际的充电金额计算退款金额   退回费用=(原金额/总金额)*(总金额-实际充电金额)
      //退款金额=优惠券金额+剩余充电金额
      List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()));
      BigDecimal total = BigDecimal.ZERO;
      for (TChargingOrderAccountingStrategy chargingOrderAccountingStrategy : list) {
         BigDecimal periodElectricPrice = chargingOrderAccountingStrategy.getPeriodElectricPrice();
         BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodOriginalServicePrice();
         total = total.add(periodElectricPrice).add(periodServicePrice);
      }
      BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
      BigDecimal vipDiscountAmount = chargingOrder.getVipDiscountAmount();
      BigDecimal decimal = rechargeAmount.add(vipDiscountAmount);
      //退款金额(已经计算了折扣优惠部分)
      BigDecimal refundAmount = rechargeAmount.divide(decimal, new MathContext(4, RoundingMode.HALF_EVEN)).multiply(decimal.subtract(total));
      BigDecimal payAmount = BigDecimal.valueOf(total.doubleValue());
      BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue());
      if(null != chargingOrder.getVipDiscount()){
         orderAmount = orderAmount.divide(chargingOrder.getVipDiscount().divide(new BigDecimal(10)));
         chargingOrder.setOrderAmount(total);
      }
      if(chargingOrder.getEndMode() == 2){
         chargingOrder.setEndMode(refundAmount.compareTo(BigDecimal.ZERO) > 0 ? 2 : 3);
      }
      chargingOrder.setStatus(5);
      chargingOrder.setPaymentAmount(payAmount);
      this.updateById(chargingOrder);
      //添加积分
      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 = payAmount.multiply(new BigDecimal(num1)).intValue();
         if(null != appUser.getVipId()){
            TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
            Integer doubleIntegration = vip.getDoubleIntegration();
            //双倍积分
            if(1 == doubleIntegration){
               integral *= 2;
            }
         }
         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());
         appUserClient.updateAppUser(appUser);
         appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange);
   @Override
   public void terminateSuccessfulResponse(PlatformStopChargingReplyVO platformStopChargingReply){
      GetChargingGunByCode code = new GetChargingGunByCode();
      code.setCharging_gun_code(platformStopChargingReply.getCharging_gun_code());
      code.setCharging_pile_code(platformStopChargingReply.getCharging_pile_code());
      TChargingGun chargingGun = chargingGunClient.getChargingGunByCode(code).getData();
      TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, chargingGun.getId())
            .orderByDesc(TChargingOrder::getEndTime).eq(TChargingOrder::getRechargePaymentStatus, 2).last(" limit 0, 1"));
      if(null != order && order.getStatus() != 3){
         return;
      }
      
      //计算优惠券
      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(total.compareTo(tCoupon.getMeetTheConditions()) >= 0){
               refundAmount = refundAmount.add(tCoupon.getDiscountAmount());
               chargingOrder.setCouponDiscountAmount(tCoupon.getDiscountAmount());
               payAmount = payAmount.subtract(tCoupon.getDiscountAmount());
            }else{
               chargingOrder.setAppCouponId(null);
               chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
               appCouponClient.refund(chargingOrder.getAppCouponId().toString());
            }
      String code1 = order.getCode();
      if(0 == platformStopChargingReply.getStop_result()){
         String failure_cause = "";
         switch (platformStopChargingReply.getFailure_cause()){
            case 0:
               failure_cause = "无";
               break;
            case 1:
               failure_cause = "设备编号不匹配";
               break;
            case 2:
               failure_cause = "枪未处于充电状态";
               break;
            case 3:
               failure_cause = "其他";
               break;
         }
         if(2 == preferentialMode){
            //抵扣
            if(total.compareTo(tCoupon.getMeetTheConditions()) >= 0){
               //折扣金额
               BigDecimal divide = total.multiply(new BigDecimal(10).subtract(tCoupon.getDiscount())).divide(new BigDecimal(10));
               divide = divide.compareTo(tCoupon.getMaximumDiscountAmount()) > 0 ? tCoupon.getMaximumDiscountAmount() : divide;
               refundAmount = refundAmount.add(divide);
               chargingOrder.setCouponDiscountAmount(divide);
               payAmount = payAmount.subtract(divide);
            }else{
               chargingOrder.setAppCouponId(null);
               chargingOrder.setCouponDiscountAmount(BigDecimal.ZERO);
               appCouponClient.refund(chargingOrder.getAppCouponId().toString());
            }
         }
         log.error(code1 + ":停机失败:订单号:{},失败原因:{}", order.getCode(), failure_cause);
      }else{
         TChargingOrder chargingOrder = new TChargingOrder();
         chargingOrder.setId(order.getId());
         chargingOrder.setAppUserId(order.getAppUserId());
         chargingOrder.setEndMode(1);
         this.updateById(chargingOrder);
      }
      if(null != chargingOrder.getVipDiscount()){
         BigDecimal subtract = orderAmount.subtract(total);
         chargingOrder.setVipDiscountAmount(subtract);
         payAmount = payAmount.subtract(subtract);
      }
      //开始构建退款费用
      if(refundAmount.compareTo(BigDecimal.ZERO) > 0){
         Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
         //构建退款明细
         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(refundAmount);
         chargingOrderRefund.setRefundStatus(1);
         chargingOrderRefund.setPayType(rechargePaymentType);
         chargingOrderRefund.setRefundStatus(1);
         chargingOrderRefund.setCode(chargingOrder.getCode());
         chargingOrderRefund.setRefundTitle("充电完成退款");
         chargingOrderRefund.setRefundContent("充电完成退款");
         chargingOrderRefund.setRefundReason("充电完成退款");
         chargingOrderRefund.setRefundRemark("充电完成退款");
         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<String> orderR = wxPaymentClient.refundOrderR(model);
            if(200 == orderR.getCode()){
               chargingOrderRefundService.save(chargingOrderRefund);
            }
         }
         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){
               SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-DDTHH:mm:ss+TIMEZONE");
               AjaxResult success = chargingOrderStartupFailureWxRefund(resp.getOutTradeNo(), resp.getTradeNo(), "SUCCESS", sdf1.format(new Date()));
               if(success.isSuccess()){
                  chargingOrderRefundService.save(chargingOrderRefund);
               }
            }
         }
      }
   }
@@ -1324,6 +1258,7 @@
       BigDecimal electronicMoney = new BigDecimal("0");
       BigDecimal serviceMoney = new BigDecimal("0");
      for (ChargingOrderVO chargingOrderVO : list) {
         chargingOrderVO.setUid(chargingOrderVO.getId()+"");
         TChargingGun data3 = chargingGunClient.getChargingGunById(chargingOrderVO.getChargingGunId()).getData();
         TChargingPile data2 = chargingPileClient.getChargingPileById(chargingOrderVO.getChargingPileId()).getData();
         if (chargingOrderVO.getSiteId()!=null){
@@ -1337,38 +1272,24 @@
         }
         if (chargingOrderVO.getChargingCapacity()!=null){
            total = total.add(chargingOrderVO.getChargingCapacity());
            total = total.add(chargingOrderVO.getElectricity());
         }
         // 充电订单 明细记录
         List<TChargingOrderAccountingStrategy> chargingOrderId = chargingOrderAccountingStrategyService.list(new QueryWrapper<TChargingOrderAccountingStrategy>()
               .eq("charging_order_id", chargingOrderVO.getId()));
         // 单个订单累计电费
         BigDecimal electronicMoney1 = new BigDecimal("0");
         // 单个订单累计服务费
         BigDecimal serviceMoney1 = new BigDecimal("0");
         UploadRealTimeMonitoringData data5 = uploadRealTimeMonitoringDataClient.chargingOrderInfo(chargingOrderVO.getCode()).getData();
         if (data5!=null){
            chargingOrderVO.setChargingSecond(data5.getTime_remaining()*60L);
            long l = data5.getCumulative_charging_time() * 60L;
            chargingOrderVO.setChargingSecond(l);
            time+=l;
         }
         // 总收入
         if (chargingOrderVO.getRefundStatus() !=null && chargingOrderVO.getRefundStatus() == 2){
            income = income.add(chargingOrderVO.getPaymentAmount().subtract(chargingOrderVO.getRefundAmount()));
         }else{
            if (chargingOrderVO.getPaymentAmount()!=null){
               income = income.add(chargingOrderVO.getPaymentAmount());
            }
         electronicMoney = electronicMoney.add(chargingOrderVO.getElectrovalence());
         serviceMoney = serviceMoney.add(chargingOrderVO.getServiceCharge());
         income = income.add(chargingOrderVO.getServiceCharge().add(chargingOrderVO.getElectrovalence()));
         if (chargingOrderVO.getRefundAmount()!=null){
            income = income.subtract(chargingOrderVO.getRefundAmount());
         }
         for (TChargingOrderAccountingStrategy tChargingOrderAccountingStrategy : chargingOrderId) {
            // 累计电费
            electronicMoney1 = electronicMoney1.add(tChargingOrderAccountingStrategy.getElectrovalence()
                  .multiply(tChargingOrderAccountingStrategy.getChargingCapacity()));
            electronicMoney = electronicMoney.add(electronicMoney1);
            // 累计服务费
            serviceMoney1 = serviceMoney1.add(tChargingOrderAccountingStrategy.getServiceCharge());
            serviceMoney = serviceMoney.add(serviceMoney1);
         }
         chargingOrderVO.setServiceCharge(serviceMoney1);
         chargingOrderVO.setElectrovalence(electronicMoney1);
         // 充电时段数
         int size = chargingOrderId.size();
         chargingOrderVO.setCount(size);
@@ -1460,13 +1381,8 @@
   public List<Map<String, Object>> getYearData(List<Long> chargingOrderIds) {
      return this.baseMapper.getYearData(chargingOrderIds);
   }
   @Resource
   private SysUserClient sysUserClient;
   @Resource
   private UserSiteClient userSiteClient;
   @Resource
   private RoleSiteClient roleSiteClient;
   @Override
   public ChargingOrderTimeVO chargingList(ChargingListQuery dto) {
      String startTime1 = null;
@@ -1480,10 +1396,40 @@
         startTime2 = split[1];
      }
      ChargingOrderTimeVO chargingOrderTimeVO = new ChargingOrderTimeVO();
      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.getPhone())){
         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);
         }
      }
      PageInfo<ChargingOrderListVO> pageInfo = new PageInfo<>(dto.getPageCurr(),dto.getPageSize());
      List<ChargingOrderListVO> list = this.baseMapper.chargingList(pageInfo,dto,startTime1,startTime2,endTime1,endTime2);
      for (ChargingOrderListVO chargingOrderListVO : list) {
         chargingOrderListVO.setPaymentAmount(chargingOrderListVO.getResidualAmount()==null?chargingOrderListVO.getPaymentAmount():chargingOrderListVO.getPaymentAmount().subtract(chargingOrderListVO.getResidualAmount()));
         chargingOrderListVO.setUid(chargingOrderListVO.getId()+"");
         List<Integer> integers = new ArrayList<>();
         integers.add(chargingOrderListVO.getSiteId());
@@ -1509,7 +1455,7 @@
         // 获取开始SOC 结束soc
         if (chargingOrderListVO.getCode()!=null){
            List<UploadRealTimeMonitoringData> data6 = uploadRealTimeMonitoringDataClient.getDataByOrderCode(chargingOrderListVO.getCode()).getData();
            if (!data6.isEmpty()){
         if (data6!=null && !data6.isEmpty()){
               // 第一条数据soc为开始 最后一条数据soc为结束soc
               chargingOrderListVO.setStartSoc(data6.get(0).getSoc().toString());
               chargingOrderListVO.setEndSoc(data6.get(data6.size()-1).getSoc().toString());
@@ -1527,7 +1473,7 @@
                     if (data4!=null && !data4.isEmpty()) chargingOrderListVO.setLicensePlate(data4.get(0).getLicensePlate());
                  }
               }
               if (data3 != null) chargingOrderListVO.setPhone(data3.getPhone());
               chargingOrderListVO.setPhone(data3.getPhone());
            }
         }
@@ -1681,10 +1627,8 @@
      return chargingOrderTimeVO;
   }
//   @Override
//   public R payRefund(PayOrderRefundDto payOrderQueryDto) {
//      return null;
//   }
   @Override
   public ChargingOrderListInfoVO chargingInfo(String uid) {
@@ -1772,96 +1716,28 @@
    * @param query
    */
   @Override
   @GlobalTransactional(rollbackFor = Exception.class)
   public void chargeMonitoring(UploadRealTimeMonitoringDataQuery query) {
      if(com.ruoyi.common.core.utils.StringUtils.isNotEmpty(query.getCharging_gun_code())){
      if(com.ruoyi.common.core.utils.StringUtils.isNotEmpty(query.getTransaction_serial_number())){
         //获取当前的计费策略
         TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, query.getCharging_gun_code()));
         AccountingStrategyDetailOrder strategyDetail = accountingStrategyDetailOrderClient.getNowAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
         TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = chargingOrderAccountingStrategyService.getOne(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>()
               .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()).orderByDesc(TChargingOrderAccountingStrategy::getCreateTime).last(" limit 0, 1"));
         SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
         if(null == chargingOrderAccountingStrategy){
            chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy();
            chargingOrderAccountingStrategy.setChargingOrderId(chargingOrder.getId());
            chargingOrderAccountingStrategy.setAccountingStrategyDetailId(strategyDetail.getId());
            chargingOrderAccountingStrategy.setType(strategyDetail.getType());
            chargingOrderAccountingStrategy.setStartTime(sdf.format(chargingOrder.getStartTime()));
            chargingOrderAccountingStrategy.setEndTime(sdf.format(new Date()));
            chargingOrderAccountingStrategy.setElectrovalence(strategyDetail.getElectrovalence());
            chargingOrderAccountingStrategy.setServiceCharge(strategyDetail.getServiceCharge());
            chargingOrderAccountingStrategy.setCostServiceCharge(strategyDetail.getCostServiceCharge());
            BigDecimal charging_degree = query.getCharging_degree();
            BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree);
            BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree);
            BigDecimal serviceCharge = originalServicePrice;
            //计算优惠金额
            if(null != chargingOrder.getVipDiscount()){
               serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10)));
            }
            chargingOrderAccountingStrategy.setChargingCapacity(charging_degree);
            chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc);
            chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge);
            chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice);
            chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now());
            chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy);
         }else{
            if(chargingOrderAccountingStrategy.getAccountingStrategyDetailId().equals(strategyDetail.getId())){
               BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodServicePrice();
               BigDecimal periodElectricPrice = chargingOrderAccountingStrategy.getPeriodElectricPrice();
               BigDecimal periodOriginalServicePrice = chargingOrderAccountingStrategy.getPeriodOriginalServicePrice();
               BigDecimal charging_degree = query.getCharging_degree();
               BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree);
               BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree);
               BigDecimal serviceCharge = originalServicePrice;
               //计算优惠金额
               if(null != chargingOrder.getVipDiscount()){
                  serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10)));
               }
               periodServicePrice = periodServicePrice.add(serviceCharge);
               periodOriginalServicePrice = periodOriginalServicePrice.add(originalServicePrice);
               periodElectricPrice = periodElectricPrice.add(electrovalenc);
               chargingOrderAccountingStrategy.setPeriodServicePrice(periodServicePrice);
               chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(periodOriginalServicePrice);
               chargingOrderAccountingStrategy.setPeriodElectricPrice(periodElectricPrice);
               chargingOrderAccountingStrategy.setEndTime(sdf.format(new Date()));
               chargingOrderAccountingStrategyService.updateById(chargingOrderAccountingStrategy);
            }else{
               TChargingOrderAccountingStrategy chargingOrderAccountingStrategy1 = new TChargingOrderAccountingStrategy();
               chargingOrderAccountingStrategy1.setChargingOrderId(chargingOrder.getId());
               chargingOrderAccountingStrategy1.setAccountingStrategyDetailId(strategyDetail.getId());
               chargingOrderAccountingStrategy1.setType(strategyDetail.getType());
               chargingOrderAccountingStrategy1.setStartTime(sdf.format(chargingOrderAccountingStrategy.getEndTime()));
               chargingOrderAccountingStrategy1.setEndTime(sdf.format(new Date()));
               chargingOrderAccountingStrategy1.setElectrovalence(strategyDetail.getElectrovalence());
               chargingOrderAccountingStrategy1.setServiceCharge(strategyDetail.getServiceCharge());
               chargingOrderAccountingStrategy1.setCostServiceCharge(strategyDetail.getCostServiceCharge());
               BigDecimal charging_degree = query.getCharging_degree();
               BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(charging_degree);
               BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(charging_degree);
               BigDecimal serviceCharge = originalServicePrice;
               //计算优惠金额
               if(null != chargingOrder.getVipDiscount()){
                  serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount().divide(new BigDecimal(10)));
               }
               chargingOrderAccountingStrategy1.setChargingCapacity(charging_degree);
               chargingOrderAccountingStrategy1.setPeriodElectricPrice(electrovalenc);
               chargingOrderAccountingStrategy1.setPeriodOriginalServicePrice(originalServicePrice);
               chargingOrderAccountingStrategy1.setPeriodServicePrice(serviceCharge);
               chargingOrderAccountingStrategy1.setCreateTime(LocalDateTime.now());
               chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy1);
            }
         }
         List<TChargingOrderAccountingStrategy> list = chargingOrderAccountingStrategyService.list(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>()
               .eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()));
         BigDecimal t = BigDecimal.ZERO;
         for (TChargingOrderAccountingStrategy coas : list) {
            t = t.add(coas.getPeriodServicePrice()).add(coas.getPeriodElectricPrice());
         }
         BigDecimal residualAmount = chargingOrder.getRechargeAmount().subtract(t).setScale(2, RoundingMode.HALF_EVEN);
         TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, query.getTransaction_serial_number()));
         BigDecimal residualAmount = chargingOrder.getRechargeAmount().add(chargingOrder.getVipDiscountAmount()).subtract(query.getPaid_amount());
         chargingOrder.setResidualAmount(residualAmount);
         BigDecimal divide = query.getOutput_current().multiply(query.getOutput_voltage()).divide(new BigDecimal(1000));
         chargingOrder.setChargingPower(divide);
         if(query.getOutput_current().compareTo(BigDecimal.ZERO) != 0){
            BigDecimal divide = (query.getOutput_current().multiply(query.getOutput_voltage())).divide(new BigDecimal(1000));
            chargingOrder.setChargingPower(divide);
            chargingOrder.setCurrent(query.getOutput_current());
            chargingOrder.setVoltage(query.getOutput_voltage());
            chargingOrder.setPower(divide);
            chargingOrder.setNeedElec(query.getOutput_current());
            TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
            chargingGun.setChargingPower(divide);
            chargingGun.setSoc(query.getSoc());
            chargingGunClient.updateChargingGunById(chargingGun);
         }
         chargingOrder.setElectricity(query.getCharging_degree());
         chargingOrder.setTotalElectricity(new BigDecimal(100 - query.getSoc()));
         this.updateById(chargingOrder);
      }
   }
@@ -1874,67 +1750,12 @@
   @Override
   @GlobalTransactional(rollbackFor = Exception.class)
   public void endCharge(String orderCode, Integer endMode) {
      TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, orderCode));
      Integer status = chargingOrder.getStatus();
      if(status == 4 || status == 5){
         return;
      }
      chargingOrder.setStatus(5);
      TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, orderCode));
      TChargingOrder chargingOrder = new TChargingOrder();
      chargingOrder.setId(order.getId());
      chargingOrder.setAppUserId(order.getAppUserId());
      chargingOrder.setEndMode(endMode);
      this.updateById(chargingOrder);
      //计算费用,处理退款
      endCharge(chargingOrder);
      //处理推荐奖励(被推荐首单奖励)
      TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
      long count = this.count(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getAppUserId, chargingOrder.getAppUserId())
            .eq(TChargingOrder::getStatus, 5).isNull(TChargingOrder::getEndMode).eq(TChargingOrder::getDelFlag, 0));
      if(null != appUser.getInviteUserId() && 1 == count){
         TIntegralRule integralRule = integralRuleClient.getSet().getData();
         String inviteUsersToEarnPoints = integralRule.getInviteUsersToEarnPoints();
         JSONObject jsonObject = JSON.parseObject(inviteUsersToEarnPoints);
         Integer num1 = jsonObject.getInteger("num1");
         TAppUser appUser1 = appUserClient.getUserById(appUser.getInviteUserId()).getData();
         if(null != appUser1.getVipId()){
            TVip vip = vipClient.getInfo1(appUser1.getVipId()).getData();
            Integer doubleIntegration = vip.getDoubleIntegration();
            //双倍积分
            if(1 == doubleIntegration){
               num1 *= 2;
            }
         }
         GetInviteUser query = new GetInviteUser();
         query.setAppUserId(appUser1.getId());
         query.setBeInvitedAppUserId(chargingOrder.getAppUserId());
         TInviteUser inviteUser = inviteUserClient.getInviteUser(query).getData();
         if(null == inviteUser){
            inviteUser = new TInviteUser();
            inviteUser.setAppUserId(appUser1.getId());
            inviteUser.setBeInvitedAppUserId(chargingOrder.getAppUserId());
            inviteUser.setAward(num1);
            inviteUser.setCreateTime(LocalDateTime.now());
            inviteUserClient.saveInviteUser(inviteUser);
         }else{
            inviteUser.setAward(num1);
            inviteUserClient.updateInviteUser(inviteUser);
         }
         TAppUserIntegralChange appUserIntegralChange = new TAppUserIntegralChange();
         String code = Double.valueOf(Math.random() * 1000).intValue() + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
         appUserIntegralChange.setCode(code);
         appUserIntegralChange.setAppUserId(appUser1.getId());
         appUserIntegralChange.setChangeType(5);
         appUserIntegralChange.setHistoricalIntegral(appUser1.getPoints());
         appUserIntegralChange.setCurrentIntegral(appUser1.getPoints() + num1);
         appUserIntegralChange.setCreateTime(LocalDateTime.now());
         appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange);
         appUser1.setPoints(appUser1.getPoints() + num1);
         appUserClient.updateAppUser(appUser1);
      }
   }
   /**
@@ -1945,7 +1766,290 @@
   public void excelEndCharge(String orderCode) {
      endCharge(orderCode, 0);
   }
   /**
    * 停止充电返回账单后计算费用
    * @param vo
    */
   @Override
   @GlobalTransactional(rollbackFor = Exception.class)
   public void endChargeBillingCharge(TransactionRecordMessageVO vo) {
      TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, vo.getTransaction_serial_number()));
      Integer status = chargingOrder.getStatus();
      if(status == 4 || status == 5){
         return;
      }
      //计算用户标签
      editUserTag(chargingOrder);
      //用户推荐奖励
      referralReward(chargingOrder);
      //如果使用优惠券需要判断优惠券是否满足使用条件
      //根据实际的充电金额计算退款金额   退回费用=(原金额/总金额)*(总金额-实际充电金额)
      //退款金额=优惠券金额+剩余充电金额
      BigDecimal periodElectricPrice_total = BigDecimal.ZERO;
      BigDecimal periodServicePrice_total = BigDecimal.ZERO;
      BigDecimal total = BigDecimal.ZERO;
      //获取订单的计费策略
      List<AccountingStrategyDetailOrder> accountingStrategyDetailOrderList = accountingStrategyDetailOrderClient.getAllAccountingStrategyDetailOrder(chargingOrder.getId()).getData();
      chargingOrderAccountingStrategyService.remove(new LambdaQueryWrapper<TChargingOrderAccountingStrategy>().eq(TChargingOrderAccountingStrategy::getChargingOrderId, chargingOrder.getId()));
      for (int i = 0; i < accountingStrategyDetailOrderList.size(); i++) {
         Class<? extends TransactionRecordMessageVO> clazz = vo.getClass();
         try {
            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());
            TChargingOrderAccountingStrategy chargingOrderAccountingStrategy = new TChargingOrderAccountingStrategy();
            chargingOrderAccountingStrategy.setChargingOrderId(chargingOrder.getId());
            chargingOrderAccountingStrategy.setAccountingStrategyDetailId(strategyDetail.getId());
            chargingOrderAccountingStrategy.setType(strategyDetail.getType());
            chargingOrderAccountingStrategy.setStartTime(chargingOrder.getStartTime().format(DateTimeFormatter.ofPattern("HH:mm")));
            chargingOrderAccountingStrategy.setEndTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")));
            chargingOrderAccountingStrategy.setElectrovalence(strategyDetail.getElectrovalence());
            chargingOrderAccountingStrategy.setServiceCharge(strategyDetail.getServiceCharge());
            chargingOrderAccountingStrategy.setCostServiceCharge(strategyDetail.getCostServiceCharge());
            //已充电总度数
            BigDecimal electrovalenc = strategyDetail.getElectrovalence().multiply(sharp_peak_charge).setScale(2, RoundingMode.DOWN);
            BigDecimal originalServicePrice = strategyDetail.getServiceCharge().multiply(sharp_peak_charge).setScale(2, RoundingMode.DOWN);
            BigDecimal serviceCharge = originalServicePrice;
            //计算优惠金额
            if(null != chargingOrder.getVipDiscount()){
               serviceCharge = serviceCharge.multiply(chargingOrder.getVipDiscount()).setScale(2, RoundingMode.DOWN);
            }
            chargingOrderAccountingStrategy.setChargingCapacity(sharp_peak_charge);
            chargingOrderAccountingStrategy.setPeriodElectricPrice(electrovalenc);
            chargingOrderAccountingStrategy.setPeriodServicePrice(serviceCharge);
            chargingOrderAccountingStrategy.setPeriodOriginalServicePrice(originalServicePrice);
            chargingOrderAccountingStrategy.setCreateTime(LocalDateTime.now());
            chargingOrderAccountingStrategyService.save(chargingOrderAccountingStrategy);
            BigDecimal periodElectricPrice = chargingOrderAccountingStrategy.getPeriodElectricPrice();
            BigDecimal periodServicePrice = chargingOrderAccountingStrategy.getPeriodOriginalServicePrice();
            periodElectricPrice_total = periodElectricPrice_total.add(periodElectricPrice);
            periodServicePrice_total = periodServicePrice_total.add(periodServicePrice);
            total = total.add(periodElectricPrice.add(periodServicePrice));
         } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
         } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
         } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
         }
      }
      //原金额
      BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
      BigDecimal vipDiscountAmount = chargingOrder.getVipDiscountAmount();
      //总金额(充值金额+会员折扣金额)
      BigDecimal decimal = rechargeAmount.add(vipDiscountAmount);
      //退款金额(已经计算了折扣优惠部分)
      BigDecimal refundAmount = rechargeAmount.divide(decimal, new MathContext(4, RoundingMode.HALF_EVEN)).multiply(decimal.subtract(total));
      BigDecimal orderAmount = BigDecimal.valueOf(total.doubleValue());
      BigDecimal payAmount = BigDecimal.valueOf(total.doubleValue());
      //折扣金额
      BigDecimal discountAmount = BigDecimal.ZERO;
      if(null != chargingOrder.getVipDiscount()){
         //服务费折扣
         discountAmount = periodServicePrice_total.multiply((new BigDecimal(1).subtract(chargingOrder.getVipDiscount())));
         TAppUser appUser = appUserClient.getUserById(chargingOrder.getAppUserId()).getData();
         if(null != appUser.getVipId()){
            //判断会员是否还有充电优惠次数
            GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
            getAppUserVipDetail.setAppUserId(chargingOrder.getAppUserId());
            getAppUserVipDetail.setVipId(appUser.getVipId());
            TAppUserVipDetail data = appUserVipDetailClient.getAppUserVipDetail(getAppUserVipDetail).getData();
            if(null != data && data.getChargeNum() > 0){
               data.setChargeNum(data.getChargeNum() - 1);
               appUserVipDetailClient.updateAppUserVipDetail(data);
            }
            TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
            BigDecimal maximumDeduction = vip.getMaximumDeduction();
            //普通会员有最高优惠限制
            if(vip.getType() == 1 && discountAmount.compareTo(maximumDeduction) > 0){
               discountAmount = maximumDeduction;
            }
         }
         payAmount = payAmount.subtract(discountAmount);
      }
      TChargingOrder order = new TChargingOrder();
      order.setId(chargingOrder.getId());
      order.setAppUserId(chargingOrder.getAppUserId());
      if(null != chargingOrder.getEndMode() && chargingOrder.getEndMode() == 2){
         order.setEndMode(refundAmount.compareTo(BigDecimal.ZERO) > 0 ? 2 : 3);
      }
      if(null == chargingOrder.getEndMode()){
         order.setEndMode(1);
      }
      order.setResidualAmount(rechargeAmount.subtract(total));
      order.setStartTime(LocalDateTime.parse(vo.getStart_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS")));
      order.setEndTime(LocalDateTime.parse(vo.getEnd_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS")));
      order.setStatus(5);
      order.setOrderAmount(orderAmount);
      order.setVipDiscountAmount(discountAmount);
      order.setServiceCharge(periodServicePrice_total);
      order.setElectrovalence(periodElectricPrice_total);
      order.setChargingCapacity(vo.getTotal_electricity());
      order.setElectricity(vo.getTotal_electricity());
      //计算优惠券
      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){
               refundAmount = refundAmount.add(tCoupon.getDiscountAmount());
               order.setCouponDiscountAmount(tCoupon.getDiscountAmount());
               payAmount = payAmount.subtract(tCoupon.getDiscountAmount());
            }else{
               order.setAppCouponId(null);
               order.setCouponDiscountAmount(BigDecimal.ZERO);
               appCouponClient.refund(chargingOrder.getAppCouponId().toString());
            }
         }
         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;
               refundAmount = refundAmount.add(divide);
               order.setCouponDiscountAmount(divide);
               payAmount = payAmount.subtract(divide);
            }else{
               order.setAppCouponId(null);
               order.setCouponDiscountAmount(BigDecimal.ZERO);
               appCouponClient.refund(chargingOrder.getAppCouponId().toString());
            }
         }
      }
      order.setPaymentAmount(payAmount);
      order.setRefundAmount(refundAmount);
      order.setRefundStatus(1);
      this.updateById(order);
      chargingOrder = this.getById(order.getId());
      // 将枪状态重置为空闲
      TChargingGun chargingGun = chargingGunClient.getChargingGunById(chargingOrder.getChargingGunId()).getData();
      chargingGun.setStatus(2);
      chargingGun.setChargingPower(BigDecimal.ZERO);
      chargingGun.setSoc(0);
      chargingGunClient.updateChargingGunById(chargingGun);
      //添加积分
      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 = payAmount.multiply(new BigDecimal(num1)).intValue();
         if(null != appUser.getVipId()){
            TVip vip = vipClient.getInfo1(appUser.getVipId()).getData();
            Integer doubleIntegration = vip.getDoubleIntegration();
            //双倍积分
            if(1 == doubleIntegration){
               integral *= 2;
            }
         }
         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());
         appUserClient.updateAppUser(appUser);
         appUserIntegralChangeClient.addAppUserIntegralChange(appUserIntegralChange);
      }
      //开始构建退款费用
      if(refundAmount.compareTo(BigDecimal.ZERO) > 0){
         Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
         //构建退款明细
         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(refundAmount);
         chargingOrderRefund.setRefundStatus(1);
         chargingOrderRefund.setPayType(rechargePaymentType);
         chargingOrderRefund.setRefundStatus(1);
         chargingOrderRefund.setCode(chargingOrder.getCode());
         chargingOrderRefund.setRefundTitle("充电完成退款");
         chargingOrderRefund.setRefundContent("充电完成退款");
         chargingOrderRefund.setRefundReason("充电完成退款");
         chargingOrderRefund.setRefundRemark("充电完成退款");
         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<String> orderR = wxPaymentClient.refundOrderR(model);
            if(200 == orderR.getCode()){
               chargingOrderRefundService.save(chargingOrderRefund);
            }
         }
         if(2 == rechargePaymentType){
            RefundReq dto = new RefundReq();
            dto.setOutTradeNo(chargingOrder.getCode());
            dto.setOutRequestNo(chargingOrderRefund.getCode());
            dto.setRefundAmount(refundAmount.toString());
            dto.setRefundReason("充电完成退款");
            RefundResp resp = aliPaymentClient.refund(dto).getData();
            if(null != resp){
               SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-DDTHH:mm:ss+TIMEZONE");
               AjaxResult success = chargingOrderStartupFailureWxRefund(resp.getOutTradeNo(), resp.getTradeNo(), "SUCCESS", sdf1.format(new Date()));
               if(success.isSuccess()){
                  chargingOrderRefundService.save(chargingOrderRefund);
               }
            }
         }
      }
   }
   @Override
   public List<Map<String, Object>> getByDate(List<Long> chargingOrderIds) {
      return this.baseMapper.getByDate(chargingOrderIds);
@@ -1978,6 +2082,10 @@
   @Override
   public List<Map<String, Object>> usersByQuery(ChargingStatisticsQueryDto statisticsQueryDto) {
      return this.baseMapper.usersByQuery(statisticsQueryDto);
   }
   @Override
   public List<Map<String, Object>> usersByQuery1(ChargingStatisticsQueryDto statisticsQueryDto) {
      return this.baseMapper.usersByQuery(statisticsQueryDto);
   }
@@ -2076,10 +2184,10 @@
               RefundResp resp = aliPaymentClient.refund(dto).getData();
               if(null != resp){
                  SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-DDTHH:mm:ss+TIMEZONE");
                  tChargingOrder.setRefundStatus(2);
                  tChargingOrder.setRefundAmount((tChargingOrder.getRefundAmount()==null? BigDecimal.valueOf(0) :tChargingOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
                  chargingOrderRefund.setRefundStatus(2);
                  chargingOrderRefund.setRefundAmount((tChargingOrder.getRefundAmount()==null? BigDecimal.valueOf(0) :tChargingOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
                  this.baseMapper.updateById(tChargingOrder);
                     chargingOrderRefundService.save(chargingOrderRefund);
                  chargingOrderRefundService.save(chargingOrderRefund);
               }
            }
@@ -2389,9 +2497,13 @@
         if (!data1.isEmpty()){
            tSettlementConfirm.setSiteName(data1.get(0).getName());
         }
         meteringElectronic = meteringElectronic.add(tSettlementConfirm.getMeteringElectronic());
         chargingElectronic = chargingElectronic.add(tSettlementConfirm.getChargingElectronic());
         lossElectronic = lossElectronic.add(tSettlementConfirm.getLossElectronic());
         if (tSettlementConfirm.getMeteringElectronic()!=null){
            meteringElectronic = meteringElectronic.add(tSettlementConfirm.getMeteringElectronic());
            chargingElectronic = chargingElectronic.add(tSettlementConfirm.getChargingElectronic());
         }
         if (tSettlementConfirm.getLossElectronic()!=null){
            lossElectronic = lossElectronic.add(tSettlementConfirm.getLossElectronic());
         }
         income = income.add(tSettlementConfirm.getIncome());
         venue = venue.add(tSettlementConfirm.getVenue());
         metering = metering.add(tSettlementConfirm.getMetering());
@@ -2455,13 +2567,22 @@
            settlementConfirm.setIncome(settlementConfirm.getElectrovalence().add(settlementConfirm.getServiceCharge()));
            if (tSettlementConfirm.getSiteId().equals(settlementConfirm.getSiteId())){
               // 电站相同比较收入涨幅跌幅
               BigDecimal subtract = tSettlementConfirm.getIncome().subtract(settlementConfirm.getIncome()).divide(tSettlementConfirm.getIncome()).setScale(2, RoundingMode.HALF_DOWN).multiply(new BigDecimal("100"));
               tSettlementConfirm.setIncomePercentage(subtract+"%");
               if (tSettlementConfirm.getIncome().compareTo(BigDecimal.ZERO)>0){
                  BigDecimal subtract = tSettlementConfirm.getIncome().subtract(settlementConfirm.getIncome()).divide(tSettlementConfirm.getIncome()).setScale(2, RoundingMode.HALF_DOWN).multiply(new BigDecimal("100"));
                  tSettlementConfirm.setIncomePercentage(subtract+"%");
               }else {
                  tSettlementConfirm.setIncomePercentage("100"+"%");
               }
               // 比较总利润 收入合计-成本合计
               BigDecimal subtract1 = tSettlementConfirm.getIncome().subtract(tSettlementConfirm.getCost());
               BigDecimal subtract2 = settlementConfirm.getIncome().subtract(settlementConfirm.getCost());
               tSettlementConfirm.setTotalPercentage(subtract1.subtract(subtract2).divide(subtract2).setScale(2, RoundingMode.HALF_DOWN).multiply(new BigDecimal("100"))+"%");
            }
               BigDecimal bigDecimal1 = subtract1.subtract(subtract2)
                     .divide(subtract2, 2, RoundingMode.HALF_DOWN)
                     .multiply(new BigDecimal("100"))
                     .setScale(2, RoundingMode.HALF_DOWN);
               tSettlementConfirm.setTotalPercentage(bigDecimal1+"%");            }
            beforeCost = beforeCost.add(settlementConfirm.getCost());
            beforeIncome = beforeIncome.add(settlementConfirm.getIncome());
@@ -2511,7 +2632,7 @@
      if (subtract2.compareTo(new BigDecimal("0")) == 0){
         tSettlementConfirm.setTotalPercentage(0+"%");
      }else{
         tSettlementConfirm.setTotalPercentage(subtract1.subtract(subtract2).divide(subtract2).setScale(2, RoundingMode.HALF_DOWN).multiply(new BigDecimal("100"))+"%");
         tSettlementConfirm.setTotalPercentage(subtract1.subtract(subtract2).divide(subtract2,2, RoundingMode.HALF_DOWN).setScale(2, RoundingMode.HALF_DOWN).multiply(new BigDecimal("100"))+"%");
      }
      tSettlementConfirm.setElectronicRefund(0);
      // 查询上次汇报数据 进行比对涨幅跌幅
@@ -2590,12 +2711,33 @@
   public List<Map<String, Object>> needElec1(List<Integer> siteIds, ChargingStatisticsQueryDto statisticsQueryDto) {
      return this.baseMapper.needElec1(siteIds,statisticsQueryDto);
   }
   public static void main(String[] args) {
//      String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日HH:mm:ss"));
//      String format1 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日HH:mm:ss"));
//      System.err.println(format+"至"+format1);
//      LocalDateTime parse = LocalDateTime.parse("2024-01-12 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
//      System.err.println(parse.format(DateTimeFormatter.ofPattern("yyyy-dd")));
   /**
    * 获取充电结束页面详情
    * @param id
    * @return
    */
   @Override
   public EndOfChargePageInfo getEndOfChargePageInfo(String id) {
      EndOfChargePageInfo info = new EndOfChargePageInfo();
      TChargingOrder chargingOrder = this.getById(id);
      info.setId(id);
      info.setCode(chargingOrder.getCode());
      info.setPaymentAmount(chargingOrder.getPaymentAmount());
      info.setCouponDiscountAmount(chargingOrder.getCouponDiscountAmount());
      TAppUserIntegralChange integralChange = appUserIntegralChangeClient.getTAppUserIntegralChangeByOrderCode(chargingOrder.getCode()).getData();
      info.setIntegral(null == integralChange ? 0 : integralChange.getCurrentIntegral() - integralChange.getHistoricalIntegral());
      info.setRechargeAmount(chargingOrder.getRechargeAmount());
      info.setRefundAmount(chargingOrder.getRefundAmount());
      LocalDateTime startTime = chargingOrder.getStartTime();
      LocalDateTime endTime = chargingOrder.getEndTime();
      info.setStartDay(startTime.format(DateTimeFormatter.ofPattern("MM月dd日")) + " 周" + startTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.SIMPLIFIED_CHINESE));
      info.setStartHour(startTime.format(DateTimeFormatter.ofPattern("HH:mm")));
      info.setEndDay(endTime.format(DateTimeFormatter.ofPattern("MM月dd日")) + " 周" + endTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.SIMPLIFIED_CHINESE));
      info.setEndHour(endTime.format(DateTimeFormatter.ofPattern("HH:mm")));
      int hour = endTime.getHour() - startTime.getHour();
      int second = endTime.getMinute() - startTime.getMinute();
      info.setDuration(0 == hour ? String.format("%s分钟", second) : String.format("%s小时%s分钟", hour, second));
      return info;
   }
}