longz
2026-07-13 6fc77feef6337bc478423efad5de91fa520b4990
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -5,6 +5,7 @@
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.api.feignClient.*;
@@ -61,6 +62,8 @@
import com.ruoyi.order.util.mongodb.service.TransactionRecordService;
import com.ruoyi.order.util.mongodb.service.UploadRealTimeMonitoringDataService;
import com.ruoyi.order.vo.EndOfChargePageInfo;
import com.ruoyi.order.vo.ChargingSimulationVO;
import com.ruoyi.order.vo.IcbcAdminSubOrderVO;
import com.ruoyi.order.vo.OrderCountByDate;
import com.ruoyi.order.vo.StatisticsOfBatteryVO;
import com.ruoyi.other.api.domain.*;
@@ -77,6 +80,7 @@
import com.ruoyi.payment.api.vo.*;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
@@ -155,6 +159,8 @@
   private IcbcPaymentClient icbcPaymentClient;
   @Resource
   private TChargingOrderShareRecordMapper chargingOrderShareRecordMapper;
   @Resource
   private ChargingOrderSettlementExecutor chargingOrderSettlementExecutor;
   
   @Resource
   private AppCouponClient appCouponClient;
@@ -817,7 +823,7 @@
      chargingOrder.setWhitelistServiceRefundAmount(BigDecimal.ZERO);
      chargingOrder.setVipDiscountAmount(BigDecimal.ZERO);
      chargingOrder.setOrderSource(1);
      if (thirdPayAmount.compareTo(BigDecimal.ZERO) > 0) {
      if (thirdPayAmount.compareTo(BigDecimal.ZERO) > 0 && Integer.valueOf(1).equals(addChargingOrder.getPaymentType())) {
         chargingOrder.setSourceName("ICBC");
      }
      chargingOrder.setTitle("【充电桩充电】" + chargingPile.getNumber() + "号桩/" + tChargingGun.getCode() + "号枪");
@@ -880,21 +886,371 @@
      }
      //会员优惠折扣将其计入增加充电时长(增加总充电金额)
      //如果充电总金额未使用完,则需要退回费用=(原金额/总金额)*(总金额-实际充电金额)
      IcbcPaymentReq req = new IcbcPaymentReq();
      req.setOutTradeNo(chargingOrder.getCode());
      req.setAmount(thirdPayAmount);
      req.setSubject("充电充值");
      req.setBody("充电充值");
      req.setPaymentType(addChargingOrder.getPaymentType());
      req.setNotifyUrl("/payment/icbc/callBack");
      req.setReturnUrl(addChargingOrder.getReturnUrl());
      req.setOpenId(Integer.valueOf(1).equals(addChargingOrder.getPaymentType()) ? appUser.getWxOpenid() : appUser.getAliOpenid());
      req.setProfitSharing(buildIcbcProfitSharing(site));
      IcbcPaymentResp data = icbcPaymentClient.payment(req).getData();
      if (isIcbcPaymentCreated(data)) {
         return AjaxResult.success(data);
      if (Integer.valueOf(1).equals(addChargingOrder.getPaymentType())) {
         IcbcPaymentReq req = new IcbcPaymentReq();
         req.setOutTradeNo(chargingOrder.getCode());
         req.setAmount(thirdPayAmount);
         req.setSubject("充电充值");
         req.setBody("充电充值");
         req.setPaymentType(1);
         req.setNotifyUrl("/payment/icbc/callBack");
         req.setReturnUrl(addChargingOrder.getReturnUrl());
         req.setOpenId(appUser.getWxOpenid());
         req.setProfitSharing(buildIcbcProfitSharing(site));
         IcbcPaymentResp data = icbcPaymentClient.payment(req).getData();
         if (isIcbcPaymentCreated(data)) {
            if (StringUtils.hasLength(data.getTradeNo())) {
               chargingOrder.setRechargeSerialNumber(data.getTradeNo());
               this.updateById(chargingOrder);
            }
            return AjaxResult.success(data);
         }
         throw new RuntimeException("调起工行支付失败");
      }
      throw new RuntimeException("调起工行支付失败");
      if (Integer.valueOf(2).equals(addChargingOrder.getPaymentType())) {
         AliPaymentReq req = new AliPaymentReq();
         req.setOutTradeNo(chargingOrder.getCode());
         req.setTotalAmount(thirdPayAmount.toString());
         req.setSubject("充电充值");
         req.setBuyerOpenId(appUser.getAliOpenid());
         req.setBody("充电充值");
         req.setNotifyUrl("/payment/ali/callBack");
         AliPaymentResp data = aliPaymentClient.payment(req).getData();
         if (data != null) {
            return AjaxResult.success(data);
         }
         throw new RuntimeException("调起支付宝支付失败");
      }
      if (Integer.valueOf(3).equals(addChargingOrder.getPaymentType())) {
         AliPaymentReq req = new AliPaymentReq();
         req.setOutTradeNo(chargingOrder.getCode());
         req.setTotalAmount(thirdPayAmount.toString());
         req.setSubject("充电充值");
         req.setBuyerOpenId(appUser.getAliOpenid());
         req.setBody("充电充值");
         req.setNotifyUrl("/payment/aliH5/callBack");
         req.setReturnUrl(addChargingOrder.getReturnUrl());
         String data = h5AliPaymentClient.payment(req).getData();
         if (StringUtils.hasLength(data)) {
            return AjaxResult.success("操作成功", data);
         }
      }
      throw new RuntimeException("无效的支付方式");
   }
   @Override
   public ChargingSimulationVO getCurrentSimulationOrder(Integer gunId) {
      if (gunId == null) {
         throw new ServiceException("充电枪不能为空");
      }
      Long userId = tokenService.getLoginUserApplet().getUserId();
      return buildSimulationVO(findSimulationOrder(userId, gunId));
   }
   @Override
   public ChargingSimulationVO completeSimulation(ChargingSimulationReq request) {
      if (request == null || request.getGunId() == null) {
         throw new ServiceException("充电枪不能为空");
      }
      Long userId = tokenService.getLoginUserApplet().getUserId();
      TChargingOrder order = findSimulationOrder(userId, request.getGunId());
      List<UploadRealTimeMonitoringData> monitoringData = uploadRealTimeMonitoringDataService.getDataByOrderCode(order.getCode());
      if (monitoringData != null && !monitoringData.isEmpty()) {
         throw new ServiceException("订单已存在真实充电监控数据,禁止模拟结算");
      }
      BigDecimal electricityFee = money(request.getElectricityFee());
      BigDecimal serviceFee = money(request.getServiceFee());
      BigDecimal simulationTotal = electricityFee.add(serviceFee).setScale(2, RoundingMode.HALF_UP);
      BigDecimal availableAmount = money(order.getChargeAmount()).compareTo(BigDecimal.ZERO) > 0
            ? money(order.getChargeAmount()) : money(order.getRechargeAmount());
      if (simulationTotal.compareTo(availableAmount) > 0) {
         throw new ServiceException("模拟消费金额不能超过订单可消费金额" + availableAmount.toPlainString() + "元");
      }
      List<AccountingStrategyDetailOrder> tariffs = accountingStrategyDetailOrderService.list(
            new LambdaQueryWrapper<AccountingStrategyDetailOrder>()
                  .eq(AccountingStrategyDetailOrder::getChargingOrderId, order.getId())
                  .orderByAsc(AccountingStrategyDetailOrder::getStartTime));
      ChargingSimulationSupport.PreparedSimulation prepared;
      try {
         prepared = ChargingSimulationSupport.prepare(order.getCode(), tariffs, electricityFee, serviceFee, LocalDateTime.now());
      } catch (IllegalArgumentException e) {
         throw new ServiceException(e.getMessage());
      }
      accountingStrategyDetailOrderService.updateById(prepared.getTariff());
      TChargingGun gun = chargingGunClient.getChargingGunById(order.getChargingGunId()).getData();
      TChargingPile pile = chargingPileClient.getChargingPileById(order.getChargingPileId()).getData();
      TransactionRecordMessageVO record = prepared.getRecord();
      record.setCharging_gun_code(gun == null ? null : gun.getCode());
      record.setCharging_pile_code(pile == null ? null : pile.getCode());
      if (Integer.valueOf(2).equals(order.getStatus())) {
         TChargingOrder charging = new TChargingOrder();
         charging.setId(order.getId());
         charging.setStatus(3);
         charging.setStartTime(LocalDateTime.now().minusSeconds(1));
         this.updateById(charging);
      }
      R settlement = chargingOrderSettlementExecutor.settle(record);
      if (R.isError(settlement)) {
         throw new ServiceException(StringUtils.hasLength(settlement.getMsg()) ? settlement.getMsg() : "模拟结算失败");
      }
      return buildSimulationVO(this.getById(order.getId()));
   }
   private TChargingOrder findSimulationOrder(Long userId, Integer gunId) {
      TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>()
            .eq(TChargingOrder::getAppUserId, userId)
            .eq(TChargingOrder::getChargingGunId, gunId)
            .eq(TChargingOrder::getSourceName, "ICBC")
            .eq(TChargingOrder::getRechargePaymentStatus, 2)
            .in(TChargingOrder::getStatus, Arrays.asList(2, 3, 4))
            .eq(TChargingOrder::getDelFlag, 0)
            .isNull(TChargingOrder::getRefundStatus)
            .orderByDesc(TChargingOrder::getId)
            .last("limit 1"));
      if (order == null) {
         throw new ServiceException("当前枪没有属于你的可模拟ICBC已支付订单");
      }
      return order;
   }
   private ChargingSimulationVO buildSimulationVO(TChargingOrder order) {
      ChargingSimulationVO result = new ChargingSimulationVO();
      result.setOrderId(order.getId());
      result.setOrderCode(order.getCode());
      result.setOrderStatus(order.getStatus());
      result.setRechargeAmount(order.getRechargeAmount());
      result.setChargeAmount(order.getChargeAmount());
      result.setElectricityFee(order.getElectrovalence());
      result.setServiceFee(order.getServiceCharge());
      result.setPaymentAmount(order.getPaymentAmount());
      result.setRefundAmount(order.getRefundAmount());
      result.setRefundStatus(order.getRefundStatus());
      result.setIcbcOrderId(order.getRechargeSerialNumber());
      TChargingOrderShareRecord shareRecord = chargingOrderShareRecordMapper.selectOne(
            new LambdaQueryWrapper<TChargingOrderShareRecord>()
                  .eq(TChargingOrderShareRecord::getChargingOrderId, order.getId())
                  .eq(TChargingOrderShareRecord::getPayChannel, "ICBC")
                  .eq(TChargingOrderShareRecord::getDelFlag, false)
                  .orderByDesc(TChargingOrderShareRecord::getId)
                  .last("limit 1"));
      if (shareRecord != null) {
         result.setShareAmount(shareRecord.getShareAmount());
         result.setShareStatus(shareRecord.getOnlineShareStatus());
         result.setSubOrderId(shareRecord.getSubOrderId());
         result.setSubOrderSeq(shareRecord.getSubOrderSeq());
         result.setSubOrderTrxid(shareRecord.getSubOrderTrxid());
      }
      return result;
   }
   @Override
   public IcbcPaymentResp queryIcbcAdminPayment(String orderCode) {
      TChargingOrder order = loadIcbcAdminOrder(orderCode);
      return requireFeignData(icbcPaymentClient.query(order.getCode()), "工行支付查询失败");
   }
   @Override
   public IcbcRefundResp refundIcbcAdminPayment(IcbcAdminFundOperationReq request) {
      if (request == null) {
         throw new ServiceException("请求参数不能为空");
      }
      TChargingOrder order = loadIcbcAdminOrder(request.getOrderCode());
      BigDecimal amount;
      try {
         amount = IcbcAdminFundOperationSupport.requireAmount(request.getAmount());
      } catch (IllegalArgumentException e) {
         throw new ServiceException(e.getMessage());
      }
      BigDecimal paidAmount = money(order.getThirdPayAmount()).compareTo(BigDecimal.ZERO) > 0
            ? money(order.getThirdPayAmount()) : money(order.getRechargeAmount());
      if (amount.compareTo(paidAmount) > 0) {
         throw new ServiceException("退款金额不能超过订单第三方支付金额" + paidAmount.toPlainString() + "元");
      }
      RLock lock = redissonClient.getLock("icbcAdminFund:order:" + order.getCode());
      if (!lock.tryLock()) {
         throw new ServiceException("该订单正在执行工行资金操作,请勿重复提交");
      }
      try {
         IcbcPaymentResp payment = requireFeignData(icbcPaymentClient.query(order.getCode()), "工行支付查询失败");
         String orderId = extractIcbcOrderId(payment);
         order.setRechargeSerialNumber(orderId);
         RBucket<String> pendingRefund = redissonClient.getBucket("icbcAdminFund:pending:main:" + order.getCode());
         String generatedRefundNo = "ICBCADMINREFUND" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
         String pendingValue = pendingRefund.get();
         boolean reusingPending = StringUtils.hasLength(pendingValue);
         String refundNo;
         try {
            refundNo = IcbcAdminFundOperationSupport.resolveRefundNo(pendingValue, amount, generatedRefundNo);
         } catch (IllegalArgumentException e) {
            throw new ServiceException(e.getMessage());
         }
         IcbcRefundReq refundRequest = IcbcAdminFundOperationSupport.buildRefundRequest(order, amount, refundNo);
         if (!reusingPending) {
            pendingRefund.set(IcbcAdminFundOperationSupport.buildPendingRefundValue(refundNo, amount));
         }
         IcbcRefundResp response = requireFeignData(icbcPaymentClient.refund(refundRequest), "工行退款调用失败");
         if (IcbcAdminFundOperationSupport.shouldClearPendingRefund(
               reusingPending, response.getStatus(), isDefinitiveIcbcResponse(response.getRawResponse()))) {
            pendingRefund.delete();
         }
         return response;
      } finally {
         if (lock.isHeldByCurrentThread()) {
            lock.unlock();
         }
      }
   }
   @Override
   public List<IcbcAdminSubOrderVO> queryIcbcAdminSubOrders(String orderCode) {
      TChargingOrder order = loadIcbcAdminOrder(orderCode);
      List<TChargingOrderShareRecord> records = chargingOrderShareRecordMapper.selectList(
            new LambdaQueryWrapper<TChargingOrderShareRecord>()
                  .eq(TChargingOrderShareRecord::getChargingOrderId, order.getId())
                  .eq(TChargingOrderShareRecord::getPayChannel, "ICBC")
                  .eq(TChargingOrderShareRecord::getDelFlag, false)
                  .orderByAsc(TChargingOrderShareRecord::getId));
      List<IcbcAdminSubOrderVO> result = new ArrayList<>();
      for (TChargingOrderShareRecord record : records) {
         IcbcAdminSubOrderVO item = buildIcbcAdminSubOrderVO(record);
         try {
            IcbcSubOrderQueryReq query = IcbcAdminFundOperationSupport.buildSubOrderQueryRequest(order, record);
            item.applyQuery(requireFeignData(icbcPaymentClient.querySubOrder(query), "工行子订单查询失败"));
         } catch (Exception e) {
            item.setQueryStatus("FAIL");
            item.setErrorMessage(e.getMessage());
         }
         result.add(item);
      }
      return result;
   }
   @Override
   public IcbcSubOrderRefundResp refundIcbcAdminSubOrder(IcbcAdminFundOperationReq request) {
      if (request == null || request.getShareRecordId() == null) {
         throw new ServiceException("请选择需要退款的分账子订单");
      }
      TChargingOrder order = loadIcbcAdminOrder(request.getOrderCode());
      TChargingOrderShareRecord shareRecord = chargingOrderShareRecordMapper.selectById(request.getShareRecordId());
      if (shareRecord == null || !order.getId().equals(shareRecord.getChargingOrderId())) {
         throw new ServiceException("分账记录不属于当前订单");
      }
      BigDecimal amount;
      try {
         amount = IcbcAdminFundOperationSupport.requireAmount(request.getAmount());
      } catch (IllegalArgumentException e) {
         throw new ServiceException(e.getMessage());
      }
      if (shareRecord.getShareAmount() != null && amount.compareTo(shareRecord.getShareAmount()) > 0) {
         throw new ServiceException("分账退款金额不能超过分账金额" + shareRecord.getShareAmount().toPlainString() + "元");
      }
      RLock lock = redissonClient.getLock("icbcAdminFund:order:" + order.getCode());
      if (!lock.tryLock()) {
         throw new ServiceException("该分账子订单正在退款,请勿重复提交");
      }
      try {
         String suffix = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
         RBucket<String> pendingRefund = redissonClient.getBucket("icbcAdminFund:pending:sub:" + shareRecord.getId());
         String generatedToken = "ICBCSUBREFUND" + suffix + ":ICBCSUBREFUNDNO" + suffix;
         String pendingValue = pendingRefund.get();
         boolean reusingPending = StringUtils.hasLength(pendingValue);
         String operationToken;
         try {
            operationToken = IcbcAdminFundOperationSupport.resolveRefundNo(pendingValue, amount, generatedToken);
         } catch (IllegalArgumentException e) {
            throw new ServiceException(e.getMessage());
         }
         String[] refundNumbers = operationToken.split(":", 2);
         if (refundNumbers.length != 2) {
            throw new ServiceException("工行分账退款幂等记录格式错误");
         }
         IcbcSubOrderRefundReq refundRequest;
         try {
            refundRequest = IcbcAdminFundOperationSupport.buildSubOrderRefundRequest(
                  order, shareRecord, amount, refundNumbers[0], refundNumbers[1]);
         } catch (IllegalArgumentException e) {
            throw new ServiceException(e.getMessage());
         }
         if (!reusingPending) {
            pendingRefund.set(IcbcAdminFundOperationSupport.buildPendingRefundValue(operationToken, amount));
         }
         IcbcSubOrderRefundResp response = requireFeignData(
               icbcPaymentClient.refundSubOrder(refundRequest), "工行分账退款调用失败");
         if (IcbcAdminFundOperationSupport.shouldClearPendingRefund(
               reusingPending, response.getStatus(), isDefinitiveIcbcResponse(response.getRawResponse()))) {
            pendingRefund.delete();
         }
         return response;
      } finally {
         if (lock.isHeldByCurrentThread()) {
            lock.unlock();
         }
      }
   }
   private TChargingOrder loadIcbcAdminOrder(String orderCode) {
      if (!StringUtils.hasLength(orderCode)) {
         throw new ServiceException("订单号不能为空");
      }
      TChargingOrder order = this.getOne(new LambdaQueryWrapper<TChargingOrder>()
            .eq(TChargingOrder::getCode, orderCode)
            .eq(TChargingOrder::getDelFlag, 0)
            .last("limit 1"));
      try {
         IcbcAdminFundOperationSupport.validateOrder(order);
      } catch (IllegalArgumentException e) {
         throw new ServiceException(e.getMessage());
      }
      return order;
   }
   private String extractIcbcOrderId(IcbcPaymentResp payment) {
      try {
         JSONObject response = JSON.parseObject(payment.getRawResponse());
         String orderId = response == null ? null : response.getString("order_id");
         if (StringUtils.hasLength(orderId)) {
            return orderId;
         }
      } catch (Exception ignored) {
      }
      throw new ServiceException("工行支付查询未返回真实order_id,禁止退款");
   }
   private boolean isDefinitiveIcbcResponse(String rawResponse) {
      if (!StringUtils.hasLength(rawResponse)) {
         return false;
      }
      try {
         JSONObject response = JSON.parseObject(rawResponse);
         return response != null && (response.containsKey("returnCode") || response.containsKey("return_code"));
      } catch (Exception ignored) {
         return false;
      }
   }
   private IcbcAdminSubOrderVO buildIcbcAdminSubOrderVO(TChargingOrderShareRecord record) {
      IcbcAdminSubOrderVO item = new IcbcAdminSubOrderVO();
      item.setShareRecordId(record.getId());
      item.setOrderCode(record.getChargingOrderCode());
      item.setShareAmount(record.getShareAmount());
      item.setOnlineShareStatus(record.getOnlineShareStatus());
      item.setSubOrderId(record.getSubOrderId());
      item.setSubMerId(record.getSubMerId());
      item.setSubMerPrtclNo(record.getSubMerPrtclNo());
      item.setOriTrxDate(record.getOriTrxDate());
      item.setBankOrderId(record.getIcbcOrderId());
      item.setSubOrderSeq(record.getSubOrderSeq());
      item.setSubOrderTrxid(record.getSubOrderTrxid());
      return item;
   }
   private <T> T requireFeignData(R<T> result, String message) {
      if (result == null || R.isError(result) || result.getData() == null) {
         throw new ServiceException(result != null && StringUtils.hasLength(result.getMsg()) ? result.getMsg() : message);
      }
      return result.getData();
   }
   
   
@@ -911,7 +1267,26 @@
   @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 == null) {
         return AjaxResult.error("支付回调订单不存在");
      }
      if (chargingOrder.getRechargePaymentStatus() == 2) {
         if (isIcbcOrder(chargingOrder) && StringUtils.hasLength(transaction_id)
               && !transaction_id.equals(chargingOrder.getRechargeSerialNumber())) {
            chargingOrder.setRechargeSerialNumber(transaction_id);
            this.updateById(chargingOrder);
         }
         return AjaxResult.success();
      }
      LocalDateTime callbackPayTime = LocalDateTime.now();
      int claimed = this.baseMapper.update(null, new LambdaUpdateWrapper<TChargingOrder>()
            .eq(TChargingOrder::getId, chargingOrder.getId())
            .eq(TChargingOrder::getRechargePaymentStatus, 1)
            .set(TChargingOrder::getRechargePaymentStatus, 2)
            .set(TChargingOrder::getRechargeSerialNumber, transaction_id)
            .set(TChargingOrder::getStatus, 2)
            .set(TChargingOrder::getPayTime, callbackPayTime));
      if (claimed == 0) {
         return AjaxResult.success();
      }
      if (isBalancePayMode(chargingOrder.getPayMethod())
@@ -927,7 +1302,7 @@
      chargingOrder.setRechargePaymentStatus(2);
      chargingOrder.setRechargeSerialNumber(transaction_id);
      chargingOrder.setStatus(2);
      chargingOrder.setPayTime(LocalDateTime.now());
      chargingOrder.setPayTime(callbackPayTime);
      
      //添加安全检测数据到缓存中,每步安全检测完成后需要更新缓存数据
      PreChargeCheck preChargeCheck = new PreChargeCheck();
@@ -3183,15 +3558,19 @@
    @Transactional
   public R endChargeBillingCharge(TransactionRecordMessageVO vo) {
      RLock lock = redissonClient.getLock("endOrder:" + vo.getTransaction_serial_number());
      boolean locked = false;
      try {
            boolean tryLock = lock.tryLock(60, 60, TimeUnit.SECONDS);
            locked = lock.tryLock(60, 60, TimeUnit.SECONDS);
            if (!locked) {
                return R.fail("订单正在结算,请勿重复操作");
            }
            //添加redis缓存数据,过期时间,用于防止处理缓慢且硬件重复发送报文导致的重复退款
            Boolean hasKey = redisService.hasKey("END_ORDER:" + vo.getTransaction_serial_number());
            if(hasKey){
                return R.fail("不能重复退款");
            }
            redisService.setCacheObject("END_ORDER:" + vo.getTransaction_serial_number(), System.currentTimeMillis() + "", 10L, TimeUnit.MINUTES);
            if(tryLock){
            if(locked){
                TChargingOrder chargingOrder = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getCode, vo.getTransaction_serial_number()));
                if (null == chargingOrder) {
                    log.error("订单不存在,订单号:{}", vo.getTransaction_serial_number());
@@ -3683,8 +4062,15 @@
                            this.updateById(chargingOrder);
                            triggerChargingOrderShare(chargingOrder);
                        } else if (isIcbcOrder(chargingOrder)) {
                            refundByIcbcAndFinish(chargingOrder, chargingOrderRefund, thirdRefundAmount, "充电完成退款", false,
                                    refundAmount, balanceRefundAmount);
                            boolean refundSuccess = refundByIcbcAndFinish(chargingOrder, chargingOrderRefund, thirdRefundAmount,
                                    "充电完成退款", false, refundAmount, balanceRefundAmount);
                            if (!refundSuccess) {
                                chargingOrderRefund.setRefundStatus(1);
                                chargingOrderRefundService.save(chargingOrderRefund);
                                chargingOrder.setRefundStatus(1);
                                this.updateById(chargingOrder);
                                throw new ServiceException("工行退款失败,结算未完成,请检查支付流水后重试退款");
                            }
                        } else if (1 == rechargePaymentType) {
                            WxPaymentRefundModel model = new WxPaymentRefundModel();
                            model.setOut_trade_no(chargingOrder.getCode());
@@ -3827,9 +4213,12 @@
                chargingMessageClient.pushOrderStatus(chargingOrderVo);
            }
      } catch (Exception e) {
         e.printStackTrace();
         log.error("充电订单结算失败,订单号:{}", vo == null ? null : vo.getTransaction_serial_number(), e);
         return R.fail("充电订单结算失败:" + firstNotBlank(e.getMessage(), "未知异常"));
      } finally {
         lock.unlock();
         if (locked && lock.isHeldByCurrentThread()) {
            lock.unlock();
         }
      }
      return R.ok();
   }
@@ -6131,7 +6520,15 @@
      if (resp == null || !StringUtils.hasLength(resp.getStatus())) {
         return false;
      }
      return "SUCCESS".equals(resp.getStatus());
      if (!"SUCCESS".equals(resp.getStatus()) || !StringUtils.hasLength(resp.getPayData())) {
         return false;
      }
      try {
         JSONObject payData = JSON.parseObject(resp.getPayData());
         return StringUtils.hasLength(payData.getString("wxDataPackage")) || StringUtils.hasLength(payData.getString("package"));
      } catch (Exception e) {
         return false;
      }
   }
   private void triggerChargingOrderShare(TChargingOrder chargingOrder, Site site) {