liujie
2026-07-22 fdd6c6769ee253cd20392383aa52a3d73f933619
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -88,6 +88,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -168,6 +169,8 @@
   private IcbcPaymentClient icbcPaymentClient;
   @Resource
   private TChargingOrderShareRecordMapper chargingOrderShareRecordMapper;
   @Value("${icbc.share.online-enabled:false}")
   private boolean icbcOnlineShareEnabled;
   @Resource
   private ChargingOrderSettlementExecutor chargingOrderSettlementExecutor;
   @Resource
@@ -3111,7 +3114,11 @@
   
   @Override
   public Map<String, Object> countAll(List<Integer> siteIds, Boolean partnerView) {
      return this.baseMapper.countAll(siteIds, partnerView);
      Map<String, Object> result = this.baseMapper.countAll(siteIds, partnerView);
      if (!Boolean.TRUE.equals(partnerView) && result != null) {
         result.put("commission_amount", this.baseMapper.sumSuccessfulShareAmount(siteIds));
      }
      return result;
   }
   /**
@@ -3371,7 +3378,6 @@
      PageInfo<ChargingOrderListVO> pageInfo = new PageInfo<>(dto.getPageCurr(), dto.getPageSize());
      List<ChargingOrderListVO> list = new ArrayList<>();
      Map<Integer, BigDecimal> siteServiceShareRatioMap = loadSiteServiceShareRatioMap();
      List<Map<String, Object>> maps = this.baseMapper.chargingList1(pageInfo, dto, startTime1, startTime2, endTime1, endTime2);
      Map<Integer, Site> siteMap = loadChargingPeriodSites(maps);
      Map<Integer, TChargingPile> pileMap = loadChargingPeriodPiles(maps);
@@ -3426,7 +3432,6 @@
            chargingOrderListVO.setSharingAmount(BigDecimal.ZERO);
         }
         chargingOrderListVO.setElectrovalence(null == map.get("electrovalence") ? BigDecimal.ZERO : new BigDecimal(map.get("electrovalence").toString()));
         fillChargingPeriodIncome(chargingOrderListVO, siteServiceShareRatioMap);
         if(null != map.get("tripartitePlatformName")){
            chargingOrderListVO.setTripartitePlatformName(map.get("tripartitePlatformName").toString());
         }
@@ -3482,6 +3487,7 @@
         }
         list.add(chargingOrderListVO);
      }
      fillChargingPeriodShareIncome(list);
@@ -3539,23 +3545,15 @@
      chargingOrderTimeVO.setPaymentAmount(paymentAmount.setScale(2, BigDecimal.ROUND_HALF_EVEN));
      chargingOrderTimeVO.setElectrovalence(electrovalence.setScale(2, BigDecimal.ROUND_HALF_EVEN));
      chargingOrderTimeVO.setServiceCharge(serviceCharge.setScale(2, BigDecimal.ROUND_HALF_EVEN));
      BigDecimal platformIncome = BigDecimal.ZERO;
      BigDecimal partnerIncome = BigDecimal.ZERO;
      for (Map<String, Object> sumMap : list1) {
         if (sumMap == null) {
            continue;
         }
         ChargingOrderListVO item = new ChargingOrderListVO();
         item.setSiteId(getSummaryLong(sumMap, "siteId").intValue());
         item.setOrderSource(getSummaryLong(sumMap, "orderSource").intValue());
         item.setPaymentAmount(getSummaryDecimal(sumMap, "paymentAmount"));
         item.setServiceCharge(getSummaryDecimal(sumMap, "serviceCharge"));
         fillChargingPeriodIncome(item, siteServiceShareRatioMap);
         platformIncome = platformIncome.add(nullToZero(item.getPlatformIncome()));
         partnerIncome = partnerIncome.add(nullToZero(item.getPartnerIncome()));
      }
      chargingOrderTimeVO.setPlatformIncome(platformIncome.setScale(2, RoundingMode.HALF_UP));
      chargingOrderTimeVO.setPartnerIncome(partnerIncome.setScale(2, RoundingMode.HALF_UP));
      List<Long> summaryOrderIds = list1.stream()
            .filter(Objects::nonNull)
            .map(sumMap -> getSummaryLong(sumMap, "id"))
            .filter(Objects::nonNull)
            .distinct()
            .collect(Collectors.toList());
      Map<String, Object> shareIncomeMap = getChargingOrderShareIncomeSummary(summaryOrderIds);
      chargingOrderTimeVO.setPlatformIncome(getSummaryDecimal(shareIncomeMap, "platformIncomeTotal"));
      chargingOrderTimeVO.setPartnerIncome(getSummaryDecimal(shareIncomeMap, "partnerIncomeTotal"));
      // 计算尖峰平谷充电到账占比
      BigDecimal add = jianElectronic.add(fengElectronic).add(pingElectronic).add(guElectronic);
      // 计算尖峰平谷服务费占比
@@ -3752,60 +3750,45 @@
      dto.setSiteIds(siteIds);
      List<ChargingOrderListVO> list1 = this.baseMapper.chargingList(dto, startTime1, startTime2, endTime1, endTime2);
      fillChargingPeriodExportBalanceIncome(list1);
      fillChargingPeriodIncome(list1);
      fillChargingPeriodShareIncome(list1);
      return list1;
   }
   private void fillChargingPeriodIncome(List<ChargingOrderListVO> list) {
   private void fillChargingPeriodShareIncome(List<ChargingOrderListVO> list) {
      if (list == null || list.isEmpty()) {
         return;
      }
      Map<Integer, BigDecimal> siteServiceShareRatioMap = loadSiteServiceShareRatioMap();
      List<Long> orderIds = list.stream()
            .map(ChargingOrderListVO::getId)
            .filter(Objects::nonNull)
            .distinct()
            .collect(Collectors.toList());
      Map<Long, Map<String, Object>> incomeMap = new HashMap<>();
      int batchSize = 500;
      for (int i = 0; i < orderIds.size(); i += batchSize) {
         List<Long> batchIds = orderIds.subList(i, Math.min(i + batchSize, orderIds.size()));
         List<Map<String, Object>> rows = this.baseMapper.chargingOrderShareIncomeByOrderIds(batchIds);
         if (rows == null) {
            continue;
         }
         for (Map<String, Object> row : rows) {
            Long orderId = getSummaryLong(row, "orderId");
            if (orderId != null) {
               incomeMap.put(orderId, row);
            }
         }
      }
      for (ChargingOrderListVO item : list) {
         fillChargingPeriodIncome(item, siteServiceShareRatioMap);
         applyChargingPeriodShareIncome(item, incomeMap.get(item.getId()));
      }
   }
   private void fillChargingPeriodIncome(ChargingOrderListVO item, Map<Integer, BigDecimal> siteServiceShareRatioMap) {
   void applyChargingPeriodShareIncome(ChargingOrderListVO item, Map<String, Object> row) {
      if (item == null) {
         return;
      }
      BigDecimal paymentAmount = nullToZero(item.getPaymentAmount());
      BigDecimal partnerIncome = BigDecimal.ZERO;
      if (!Integer.valueOf(2).equals(item.getOrderSource())) {
         BigDecimal serviceShareRatio = siteServiceShareRatioMap.get(item.getSiteId());
         if (serviceShareRatio != null && serviceShareRatio.compareTo(BigDecimal.ZERO) > 0) {
            partnerIncome = nullToZero(item.getServiceCharge())
                  .multiply(serviceShareRatio)
                  .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
         }
      }
      item.setPartnerIncome(partnerIncome);
      item.setPlatformIncome(paymentAmount.subtract(partnerIncome).max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP));
   }
   private Map<Integer, BigDecimal> loadSiteServiceShareRatioMap() {
      Map<Integer, BigDecimal> ratioMap = new HashMap<>();
      R<List<Site>> siteResult = siteClient.getSiteAll();
      R<List<Partner>> partnerResult = siteClient.getAllPartner();
      List<Site> sites = siteResult == null ? Collections.emptyList() : siteResult.getData();
      List<Partner> partners = partnerResult == null ? Collections.emptyList() : partnerResult.getData();
      if (sites == null || sites.isEmpty() || partners == null || partners.isEmpty()) {
         return ratioMap;
      }
      Map<Integer, Partner> partnerMap = partners.stream()
            .filter(partner -> partner != null && partner.getId() != null)
            .collect(Collectors.toMap(Partner::getId, partner -> partner, (left, right) -> left));
      for (Site site : sites) {
         if (site == null || site.getId() == null || site.getPartnerId() == null) {
            continue;
         }
         Partner partner = partnerMap.get(site.getPartnerId());
         if (partner != null && partner.getServiceShareRatio() != null) {
            ratioMap.put(site.getId(), partner.getServiceShareRatio());
         }
      }
      return ratioMap;
      item.setPlatformIncome(getSummaryDecimal(row, "platformIncome"));
      item.setPartnerIncome(getSummaryDecimal(row, "partnerIncome"));
   }
   /**
@@ -5261,7 +5244,7 @@
         shoppingOrderRefund.setRefundContent("后台退款");
         shoppingOrderRefund.setRefundReason("后台退款");
         shoppingOrderRefund.setRefundRemark(payOrderQueryDto.getRemark());
         shoppingOrderRefund.setRefundTotalAmount(shoppingOrder.getRefundAmount().add(payOrderQueryDto.getRefundAmount()));
         shoppingOrderRefund.setRefundTotalAmount(money(shoppingOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
         shoppingOrderRefund.setPayAmount(shoppingOrder.getPaymentAmount());
         if (1 == shoppingOrder.getPaymentType()) {
@@ -5305,6 +5288,29 @@
               shoppingOrderRefundService.save(shoppingOrderRefund);
            }
         }
         if (3 == shoppingOrder.getPaymentType()) {
            IcbcRefundReq refundReq = new IcbcRefundReq();
            refundReq.setOutTradeNo(shoppingOrder.getCode());
            refundReq.setOrderId(shoppingOrder.getSerialNumber());
            refundReq.setOutRefundNo(shoppingOrderRefund.getRefundCode());
            refundReq.setRefundAmount(payOrderQueryDto.getRefundAmount());
            refundReq.setTotalAmount(shoppingOrder.getPaymentAmount());
            refundReq.setReason("后台商城订单退款");
            R<IcbcRefundResp> refundResult = icbcPaymentClient.refund(refundReq);
            IcbcRefundResp refundResp = refundResult == null ? null : refundResult.getData();
            if (refundResult == null || refundResult.getCode() != 200 || refundResp == null || !"SUCCESS".equals(refundResp.getStatus())) {
               return R.fail(refundResult == null ? "工行退款服务无响应"
                     : firstNotBlank(refundResp == null ? null : refundResp.getRawResponse(), refundResult.getMsg(), "工行退款失败"));
            }
            shoppingOrder.setRefundStatus(2);
            shoppingOrder.setRefundAmount(money(shoppingOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
            shoppingOrder.setRefundSerialNumber(refundResp.getRefundId());
            shoppingOrder.setRefundTime(LocalDateTime.now());
            shoppingOrderService.updateById(shoppingOrder);
            shoppingOrderRefund.setRefundStatus(2);
            shoppingOrderRefund.setRefundSerialNumber(refundResp.getRefundId());
            shoppingOrderRefundService.save(shoppingOrderRefund);
         }
//            if(3 == tChargingOrder.getPaymentType()){
//               RefundReq dto = new RefundReq();
//               dto.setOutTradeNo(tChargingOrder.getCode());
@@ -5342,7 +5348,7 @@
         vipOrderRefund.setRefundContent("后台退款");
         vipOrderRefund.setRefundReason("后台退款");
         vipOrderRefund.setRefundRemark(payOrderQueryDto.getRemark());
         vipOrderRefund.setRefundTotalAmount(vipOrder.getRefundAmount().add(payOrderQueryDto.getRefundAmount()));
         vipOrderRefund.setRefundTotalAmount(money(vipOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
         vipOrderRefund.setPayAmount(vipOrder.getPaymentAmount());
         
         if (1 == vipOrder.getPaymentType()) {
@@ -5385,6 +5391,27 @@
               vipOrderService.updateById(vipOrder);
               vipOrderRefundService.save(vipOrderRefund);
            }
         }
         if (3 == vipOrder.getPaymentType()) {
            IcbcRefundReq refundReq = new IcbcRefundReq();
            refundReq.setOutTradeNo(vipOrder.getCode());
            refundReq.setOrderId(vipOrder.getSerialNumber());
            refundReq.setOutRefundNo(vipOrderRefund.getRefundCode());
            refundReq.setRefundAmount(payOrderQueryDto.getRefundAmount());
            refundReq.setTotalAmount(vipOrder.getPaymentAmount());
            refundReq.setReason("后台会员订单退款");
            R<IcbcRefundResp> refundResult = icbcPaymentClient.refund(refundReq);
            IcbcRefundResp refundResp = refundResult == null ? null : refundResult.getData();
            if (refundResult == null || refundResult.getCode() != 200 || refundResp == null || !"SUCCESS".equals(refundResp.getStatus())) {
               return R.fail(refundResult == null ? "工行退款服务无响应"
                     : firstNotBlank(refundResp == null ? null : refundResp.getRawResponse(), refundResult.getMsg(), "工行退款失败"));
            }
            vipOrder.setRefundStatus(2);
            vipOrder.setRefundAmount(money(vipOrder.getRefundAmount()).add(payOrderQueryDto.getRefundAmount()));
            vipOrderService.updateById(vipOrder);
            vipOrderRefund.setRefundStatus(2);
            vipOrderRefund.setRefundSerialNumber(refundResp.getRefundId());
            vipOrderRefundService.save(vipOrderRefund);
         }
//         if(3 == tChargingOrder.getPaymentType()){
//            RefundReq dto = new RefundReq();
@@ -7555,11 +7582,13 @@
         record.setSubMerId(partner.getIcbcSubMerId());
         record.setSubMerPrtclNo(partner.getIcbcSubMerPrtclNo());
      }
      boolean needOnlineShare = shouldProcessIcbcOnlineShare(payChannel, record.getShareAmount(), partner);
      boolean needOnlineShare = shouldProcessIcbcOnlineShare(icbcOnlineShareEnabled, payChannel, record.getShareAmount(), partner);
      record.setNeedOnlineShare(needOnlineShare);
      record.setOnlineShareStatus(needOnlineShare ? "INIT" : "RECORDED");
      if ("ICBC".equals(payChannel) && record.getShareAmount().compareTo(BigDecimal.ZERO) > 0 && !needOnlineShare) {
         record.setFailReason("未配置完整工行二级商户参数,仅记录本地分账");
         record.setFailReason(icbcOnlineShareEnabled
               ? "未配置完整工行二级商户参数,仅记录本地分账"
               : "工行线上分账已关闭,仅记录本地分账");
      }
      record.setRetryCount(0);
      record.setDelFlag(false);
@@ -7752,7 +7781,12 @@
   }
   static boolean shouldProcessIcbcOnlineShare(String payChannel, BigDecimal shareAmount, Partner partner) {
      return "ICBC".equals(payChannel)
      return shouldProcessIcbcOnlineShare(true, payChannel, shareAmount, partner);
   }
   static boolean shouldProcessIcbcOnlineShare(boolean onlineShareEnabled, String payChannel, BigDecimal shareAmount, Partner partner) {
      return onlineShareEnabled
            && "ICBC".equals(payChannel)
            && shareAmount != null
            && shareAmount.compareTo(BigDecimal.ZERO) > 0
            && partner != null