From faaf70b3fc0cff90d25fa30b37f225f679a0d5a5 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期一, 20 七月 2026 19:30:08 +0800
Subject: [PATCH] 特殊退款查询

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java |  120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 113 insertions(+), 7 deletions(-)

diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java
index 29e25b1..b3d838c 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingBillServiceImpl.java
@@ -36,6 +36,7 @@
 import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
 import java.util.ArrayList;
@@ -43,6 +44,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -1057,10 +1060,10 @@
         List<Map<String, Object>> list = chargingSettlementBillService.queryList(pageInfo, dto.getType(), dto.getState(), dto.getDateRange(), statisticalDateType, dto.getSiteIds());
         ChargingBillWapper chargingBillVO = new ChargingBillWapper();
         List<Map<String, Object>> pageList = new ArrayList<>();
-        List<TChargingOrder> total = chargingOrderList.selectList(new LambdaQueryWrapper<>(TChargingOrder.class)
-                .isNotNull(TChargingOrder::getPayTime));
-        List<TChargingOrderAccountingStrategy> strategyList = chargingOrderAccountingStrategyService.list();
         Map<Integer, BigDecimal> siteServiceShareRatioMap = loadSiteServiceShareRatioMap();
+        PageInfo<Map<String, Object>> sumPageInfo = new PageInfo<>(1, 100000);
+        List<Map<String, Object>> sumList = chargingSettlementBillService.queryList(sumPageInfo, dto.getType(), dto.getState(), dto.getDateRange(), statisticalDateType, dto.getSiteIds());
+        Map<String, Map<String, BigDecimal>> incomeIndex = buildChargingBillIncomeIndex(sumList, siteServiceShareRatioMap);
         if(null != list){
             for (Map<String, Object> map : list) {
                 Integer site_id = Integer.valueOf(map.get("site_id").toString());
@@ -1077,7 +1080,7 @@
                 String chargingCapacity = map.get("total_electricity").toString();
                 String electrovalence = map.get("total_electricity_charge").toString();
                 String serviceCharge = map.get("total_service_fee").toString();
-                Map<String, BigDecimal> incomeMap = calculateChargingBillIncome(dto.getType(), site_id, billingCycle, total, strategyList, siteServiceShareRatioMap);
+                Map<String, BigDecimal> incomeMap = getChargingBillIncome(incomeIndex, site_id, billingCycle);
                 Map<String, Object> data1 = new HashMap<>();
                 data1.put("code", code);
                 data1.put("orderState", 2);
@@ -1118,13 +1121,11 @@
         BigDecimal discount = (null == map || null == map.get("couponDeduction")) ? BigDecimal.ZERO : new BigDecimal(map.get("couponDeduction").toString());
         BigDecimal platformIncome = BigDecimal.ZERO;
         BigDecimal partnerIncome = BigDecimal.ZERO;
-        PageInfo<Map<String, Object>> sumPageInfo = new PageInfo<>(1, 100000);
-        List<Map<String, Object>> sumList = chargingSettlementBillService.queryList(sumPageInfo, dto.getType(), dto.getState(), dto.getDateRange(), statisticalDateType, dto.getSiteIds());
         if (sumList != null) {
             for (Map<String, Object> row : sumList) {
                 Integer siteId = Integer.valueOf(row.get("site_id").toString());
                 String billingCycle = row.get("billingCycle").toString();
-                Map<String, BigDecimal> incomeMap = calculateChargingBillIncome(dto.getType(), siteId, billingCycle, total, strategyList, siteServiceShareRatioMap);
+                Map<String, BigDecimal> incomeMap = getChargingBillIncome(incomeIndex, siteId, billingCycle);
                 platformIncome = platformIncome.add(incomeMap.get("platformIncome"));
                 partnerIncome = partnerIncome.add(incomeMap.get("partnerIncome"));
             }
@@ -1145,6 +1146,111 @@
         return chargingBillVO;
     }
 
+    private Map<String, Map<String, BigDecimal>> buildChargingBillIncomeIndex(List<Map<String, Object>> billRows,
+                                                                               Map<Integer, BigDecimal> siteServiceShareRatioMap) {
+        Map<String, Map<String, BigDecimal>> incomeIndex = new HashMap<>();
+        if (billRows == null || billRows.isEmpty()) {
+            return incomeIndex;
+        }
+        Set<String> billingCycles = billRows.stream()
+                .map(row -> row.get("billingCycle"))
+                .filter(Objects::nonNull)
+                .map(Object::toString)
+                .collect(Collectors.toSet());
+        if (billingCycles.isEmpty()) {
+            return incomeIndex;
+        }
+        LocalDate firstMonth = billingCycles.stream()
+                .map(cycle -> LocalDate.parse(cycle + "-01"))
+                .min(LocalDate::compareTo)
+                .orElse(null);
+        LocalDate lastMonth = billingCycles.stream()
+                .map(cycle -> LocalDate.parse(cycle + "-01"))
+                .max(LocalDate::compareTo)
+                .orElse(null);
+        if (firstMonth == null || lastMonth == null) {
+            return incomeIndex;
+        }
+
+        List<TChargingOrder> orders = chargingOrderList.selectList(new LambdaQueryWrapper<>(TChargingOrder.class)
+                .select(TChargingOrder::getId, TChargingOrder::getSiteId, TChargingOrder::getPayTime, TChargingOrder::getOrderSource)
+                .ge(TChargingOrder::getPayTime, firstMonth.atStartOfDay())
+                .lt(TChargingOrder::getPayTime, lastMonth.plusMonths(1).atStartOfDay()));
+        if (orders == null || orders.isEmpty()) {
+            return incomeIndex;
+        }
+
+        Map<Long, BigDecimal[]> strategyAmountMap = new HashMap<>();
+        List<Long> orderIds = orders.stream().map(TChargingOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());
+        final int batchSize = 1000;
+        for (int from = 0; from < orderIds.size(); from += batchSize) {
+            List<Long> batchIds = orderIds.subList(from, Math.min(from + batchSize, orderIds.size()));
+            List<TChargingOrderAccountingStrategy> strategies = chargingOrderAccountingStrategyService.list(
+                    new LambdaQueryWrapper<TChargingOrderAccountingStrategy>()
+                            .select(TChargingOrderAccountingStrategy::getChargingOrderId,
+                                    TChargingOrderAccountingStrategy::getPeriodElectricPrice,
+                                    TChargingOrderAccountingStrategy::getPeriodServicePrice)
+                            .in(TChargingOrderAccountingStrategy::getChargingOrderId, batchIds));
+            for (TChargingOrderAccountingStrategy strategy : strategies) {
+                BigDecimal[] amounts = strategyAmountMap.computeIfAbsent(strategy.getChargingOrderId(), key -> new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO});
+                amounts[0] = amounts[0].add(strategy.getPeriodElectricPrice() == null ? BigDecimal.ZERO : strategy.getPeriodElectricPrice());
+                amounts[1] = amounts[1].add(strategy.getPeriodServicePrice() == null ? BigDecimal.ZERO : strategy.getPeriodServicePrice());
+            }
+        }
+
+        for (TChargingOrder order : orders) {
+            if (order.getPayTime() == null || order.getSiteId() == null) {
+                continue;
+            }
+            String billingCycle = order.getPayTime().format(DateTimeFormatter.ofPattern("yyyy-MM"));
+            if (!billingCycles.contains(billingCycle)) {
+                continue;
+            }
+            BigDecimal[] amounts = strategyAmountMap.getOrDefault(order.getId(), new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO});
+            BigDecimal paymentAmount;
+            BigDecimal partnerIncome = BigDecimal.ZERO;
+            if (Integer.valueOf(2).equals(order.getOrderSource())) {
+                paymentAmount = amounts[0].add(amounts[1].multiply(new BigDecimal("0.8")).setScale(2, RoundingMode.DOWN));
+            } else {
+                paymentAmount = amounts[0].add(amounts[1]);
+                if (Integer.valueOf(1).equals(order.getOrderSource())) {
+                    BigDecimal serviceShareRatio = siteServiceShareRatioMap.get(order.getSiteId());
+                    if (serviceShareRatio != null && serviceShareRatio.compareTo(BigDecimal.ZERO) > 0) {
+                        partnerIncome = amounts[1].multiply(serviceShareRatio).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
+                    }
+                }
+            }
+            addChargingBillIncome(incomeIndex, chargingBillIncomeKey(0, billingCycle), paymentAmount, partnerIncome);
+            addChargingBillIncome(incomeIndex, chargingBillIncomeKey(order.getSiteId(), billingCycle), paymentAmount, partnerIncome);
+        }
+        return incomeIndex;
+    }
+
+    private void addChargingBillIncome(Map<String, Map<String, BigDecimal>> incomeIndex, String key,
+                                       BigDecimal paymentAmount, BigDecimal partnerIncome) {
+        Map<String, BigDecimal> income = incomeIndex.computeIfAbsent(key, ignored -> {
+            Map<String, BigDecimal> value = new HashMap<>();
+            value.put("platformIncome", BigDecimal.ZERO);
+            value.put("partnerIncome", BigDecimal.ZERO);
+            return value;
+        });
+        income.put("platformIncome", income.get("platformIncome").add(paymentAmount).subtract(partnerIncome));
+        income.put("partnerIncome", income.get("partnerIncome").add(partnerIncome));
+    }
+
+    private Map<String, BigDecimal> getChargingBillIncome(Map<String, Map<String, BigDecimal>> incomeIndex,
+                                                           Integer siteId, String billingCycle) {
+        Map<String, BigDecimal> income = incomeIndex.get(chargingBillIncomeKey(siteId, billingCycle));
+        Map<String, BigDecimal> result = new HashMap<>();
+        result.put("platformIncome", income == null ? BigDecimal.ZERO : income.get("platformIncome").max(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_UP));
+        result.put("partnerIncome", income == null ? BigDecimal.ZERO : income.get("partnerIncome").setScale(2, RoundingMode.HALF_UP));
+        return result;
+    }
+
+    private String chargingBillIncomeKey(Integer siteId, String billingCycle) {
+        return (siteId == null ? 0 : siteId) + "|" + billingCycle;
+    }
+
     @Override
     public ChargingBillVO chargingBillListExport(ChargingListQuery dto) {
         if (dto.getState()!=null){

--
Gitblit v1.7.1