From 14ac49d64602ddcf3b5057601e829f29f078b2f2 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期二, 04 八月 2026 16:53:45 +0800
Subject: [PATCH] fix:碳减排量

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java |   73 +++++++++++++++++++++++++++---------
 1 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
index 992e9c3..978b52a 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -68,7 +68,6 @@
 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.order.vo.LargeChargingPowerVo;
 import com.ruoyi.order.vo.ReservationRecommendationVO;
@@ -6809,6 +6808,26 @@
     }
 
     @Override
+    public BigDecimal getLargeScreenTotalCapacity(List<Integer> siteIds) {
+        String cacheKey = largeScreenCacheKey("capacity", siteIds);
+        BigDecimal cached = redisService.getCacheObject(cacheKey);
+        if (cached != null) {
+            return cached;
+        }
+        BigDecimal capacity = BigDecimal.ZERO;
+        try {
+            BigDecimal fromStat = this.baseMapper.capacityFromStat(siteIds);
+            if (fromStat != null) {
+                capacity = fromStat;
+            }
+        } catch (Exception e) {
+            log.warn("大屏累计充电量读取预聚合表失败, siteIds={}", siteIds, e);
+        }
+        redisService.setCacheObject(cacheKey, capacity, LARGE_SCREEN_CACHE_SECONDS, TimeUnit.SECONDS);
+        return capacity;
+    }
+
+    @Override
     public void rebuildLargeScreenStat() {
         log.info("大屏预聚合表全量重建开始");
         long start = System.currentTimeMillis();
@@ -7329,6 +7348,11 @@
      */
     @Override
     public R<StatisticsOfBatteryVO> getStatisticsOfBattery(List<Integer> siteIds) {
+        String cacheKey = largeScreenCacheKey("battery", siteIds);
+        StatisticsOfBatteryVO cached = redisService.getCacheObject(cacheKey);
+        if (cached != null) {
+            return R.ok(cached);
+        }
         StatisticsOfBatteryVO vo = new StatisticsOfBatteryVO();
         List<Integer> effectiveSiteIds = siteIds == null ? Arrays.asList(25, 26) : siteIds;
         if (effectiveSiteIds.isEmpty()) {
@@ -7343,39 +7367,52 @@
             return R.ok(vo);
         }
         List<Integer> gunIds = r.getData();
-        //统计
+        // 统计: gunIds 分批查询, 避免超大 IN 列表撑爆 MyCat 规划器
         Long total = 0L;
         if (gunIds != null && !gunIds.isEmpty()) {
-            total = this.baseMapper.selectCount(new LambdaQueryWrapper<TChargingOrder>()
-                    .eq(TChargingOrder::getDelFlag, 0)//未删除
-                    .in(TChargingOrder::getStatus, Arrays.asList(3, 5))//充电中、已结束
-                    .in(TChargingOrder::getChargingGunId, gunIds));//符合条件的充电枪
+            for (List<Integer> chunk : chunkList(gunIds, 500)) {
+                Long chunkCount = this.baseMapper.selectCount(new LambdaQueryWrapper<TChargingOrder>()
+                        .eq(TChargingOrder::getDelFlag, 0)//未删除
+                        .in(TChargingOrder::getStatus, Arrays.asList(3, 5))//充电中、已结束
+                        .in(TChargingOrder::getChargingGunId, chunk));//符合条件的充电枪
+                total += chunkCount == null ? 0L : chunkCount;
+            }
         }
         vo.setTotal(total.intValue());
         List<LocalDate> dates = new ArrayList<>();
         List<Integer> counts = new ArrayList<>();
         LocalDate today = LocalDate.now();
-        LocalDateTime startDate = today.minusDays(7).atStartOfDay();
-        LocalDateTime endDate = today.minusDays(1).atTime(LocalTime.MAX);
-        Map<LocalDate, Long> countByDate = new HashMap<>();
-        if (gunIds != null && !gunIds.isEmpty()) {
-            List<OrderCountByDate> orderCounts = this.baseMapper.countOrdersByDate(startDate, endDate, gunIds);
-            if (orderCounts != null) {
-                for (OrderCountByDate orderCount : orderCounts) {
-                    countByDate.put(orderCount.getDate(), orderCount.getCount());
-                }
-            }
-        }
         for (int i = 7; i >= 1; i--) {//升序
             LocalDate day = today.minusDays(i);
+            LocalDateTime dayStart = day.atStartOfDay();
+            LocalDateTime dayEnd = day.plusDays(1).atStartOfDay();
+            long dayCount = 0L;
+            if (gunIds != null && !gunIds.isEmpty()) {
+                for (List<Integer> chunk : chunkList(gunIds, 500)) {
+                    Long chunkCount = this.baseMapper.countOrdersInRangeByGunIds(dayStart, dayEnd, chunk);
+                    dayCount += chunkCount == null ? 0L : chunkCount;
+                }
+            }
             dates.add(day);
-            counts.add(countByDate.getOrDefault(day, 0L).intValue());
+            counts.add((int) dayCount);
         }
         vo.setDates(dates);
         vo.setCounts(counts);
+        redisService.setCacheObject(cacheKey, vo, LARGE_SCREEN_CACHE_SECONDS, TimeUnit.SECONDS);
         return R.ok(vo);
     }
 
+    /**
+     * 列表分批, 控制单条 SQL 的 IN 列表规模
+     */
+    private <T> List<List<T>> chunkList(List<T> list, int size) {
+        List<List<T>> chunks = new ArrayList<>();
+        for (int i = 0; i < list.size(); i += size) {
+            chunks.add(list.subList(i, Math.min(i + size, list.size())));
+        }
+        return chunks;
+    }
+
     @Override
     public Double getSumDegreeBySiteIds(List<Integer> siteIds) {
         Double sumDegreeBySiteIds = this.baseMapper.getSumDegreeBySiteIds(siteIds);

--
Gitblit v1.7.1