From bf82d9f70479a5ea99ff2ea00b35cb3b6b7d500f Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期三, 02 九月 2026 15:40:38 +0800
Subject: [PATCH] 修改刷卡充电订单查询报错

---
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java |   28 +++++++++
 ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/CardChargingOrderSummaryMapperTest.java  |    7 ++
 ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TCardChargingOrderMapper.java            |    2 
 ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TCardChargingOrderMapper.xml                  |   31 +++++-----
 sql/20260902_add_charging_order_vin.sql                                                                 |   56 ++++++++++++++++++
 ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/TCardChargingOrderSummaryTest.java |   29 +++++++++
 6 files changed, 138 insertions(+), 15 deletions(-)

diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TCardChargingOrderMapper.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TCardChargingOrderMapper.java
index d61b57e..488b355 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TCardChargingOrderMapper.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/mapper/TCardChargingOrderMapper.java
@@ -41,6 +41,8 @@
 
     Map<String, Object> accountingSummaryByOrderIds(@Param("orderIds") List<Long> orderIds);
 
+    List<Map<String, Object>> capacitySummaryByOrderIds(@Param("orderIds") List<Long> orderIds);
+
     List<Map<String, Object>> balanceIncomeDetail(@Param("query") CardChargingOrderQuery query);
 
     List<Map<String, Object>> accountingStrategyList(@Param("chargingOrderId") Long chargingOrderId);
diff --git a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java
index 97e9a87..e83d8f3 100644
--- a/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java
+++ b/ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TCardChargingOrderServiceImpl.java
@@ -316,10 +316,38 @@
         query.setSiteIds(siteIds);
     }
 
+    private void fillElectronicProportion(List<ChargingOrderVO> list) {
+        List<Long> orderIds = list.stream().map(ChargingOrderVO::getId).filter(Objects::nonNull).collect(Collectors.toList());
+        if (orderIds.isEmpty()) {
+            return;
+        }
+        List<Map<String, Object>> capacityRows = new ArrayList<>();
+        int batchSize = 500;
+        for (int i = 0; i < orderIds.size(); i += batchSize) {
+            List<Long> batchIds = orderIds.subList(i, Math.min(i + batchSize, orderIds.size()));
+            capacityRows.addAll(Optional.ofNullable(baseMapper.capacitySummaryByOrderIds(batchIds))
+                    .orElse(Collections.emptyList()));
+        }
+        Map<Long, Map<String, Object>> capacityByOrderId = capacityRows.stream()
+                .filter(item -> item.get("orderId") != null)
+                .collect(Collectors.toMap(item -> Long.valueOf(item.get("orderId").toString()), item -> item, (a, b) -> a));
+        for (ChargingOrderVO order : list) {
+            Map<String, Object> capacity = capacityByOrderId.get(order.getId());
+            Map<String, BigDecimal> summary = emptyAccountingSummary();
+            if (capacity != null) {
+                for (String key : new String[]{"capacityTotal", "capacity1", "capacity2", "capacity3", "capacity4"}) {
+                    summary.put(key, summaryDecimal(capacity, key));
+                }
+            }
+            order.setElectronicProportion(buildProportion(summary, "capacity"));
+        }
+    }
+
     private void fillPageExtra(List<ChargingOrderVO> list) {
         if (list == null || list.isEmpty()) {
             return;
         }
+        fillElectronicProportion(list);
         List<Integer> siteIds = list.stream().map(ChargingOrderVO::getSiteId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
         List<Integer> gunIds = list.stream().map(ChargingOrderVO::getChargingGunId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
         List<Long> carIds = list.stream().map(ChargingOrderVO::getAppUserCarId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
diff --git a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TCardChargingOrderMapper.xml b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TCardChargingOrderMapper.xml
index 28d6fed..8a46d55 100644
--- a/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TCardChargingOrderMapper.xml
+++ b/ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TCardChargingOrderMapper.xml
@@ -39,22 +39,8 @@
     </sql>
 
     <select id="pageList" resultType="com.ruoyi.order.api.vo.ChargingOrderVO">
-        SELECT o.*,
-               CONCAT(IFNULL(ROUND(a.capacity1 / NULLIF(a.capacity_total, 0) * 100, 2), 0), '%-',
-                      IFNULL(ROUND(a.capacity2 / NULLIF(a.capacity_total, 0) * 100, 2), 0), '%-',
-                      IFNULL(ROUND(a.capacity3 / NULLIF(a.capacity_total, 0) * 100, 2), 0), '%-',
-                      IFNULL(ROUND(a.capacity4 / NULLIF(a.capacity_total, 0) * 100, 2), 0), '%') AS electronicProportion
+        SELECT o.*
         FROM t_card_charging_order o
-        LEFT JOIN (
-            SELECT charging_order_id,
-                   SUM(charging_capacity) AS capacity_total,
-                   SUM(CASE WHEN type = 1 THEN charging_capacity ELSE 0 END) AS capacity1,
-                   SUM(CASE WHEN type = 2 THEN charging_capacity ELSE 0 END) AS capacity2,
-                   SUM(CASE WHEN type = 3 THEN charging_capacity ELSE 0 END) AS capacity3,
-                   SUM(CASE WHEN type = 4 THEN charging_capacity ELSE 0 END) AS capacity4
-            FROM t_card_charging_order_accounting_strategy
-            GROUP BY charging_order_id
-        ) a ON a.charging_order_id = o.id
         <include refid="queryCondition"/>
         ORDER BY o.create_time DESC
         LIMIT #{offset}, #{pageSize}
@@ -122,6 +108,21 @@
         </foreach>
     </select>
 
+    <select id="capacitySummaryByOrderIds" resultType="java.util.LinkedHashMap">
+        SELECT charging_order_id AS orderId,
+               IFNULL(SUM(charging_capacity), 0) AS capacityTotal,
+               IFNULL(SUM(CASE WHEN type = 1 THEN charging_capacity ELSE 0 END), 0) AS capacity1,
+               IFNULL(SUM(CASE WHEN type = 2 THEN charging_capacity ELSE 0 END), 0) AS capacity2,
+               IFNULL(SUM(CASE WHEN type = 3 THEN charging_capacity ELSE 0 END), 0) AS capacity3,
+               IFNULL(SUM(CASE WHEN type = 4 THEN charging_capacity ELSE 0 END), 0) AS capacity4
+        FROM t_card_charging_order_accounting_strategy
+        WHERE charging_order_id IN
+        <foreach collection="orderIds" item="orderId" open="(" separator="," close=")">
+            #{orderId}
+        </foreach>
+        GROUP BY charging_order_id
+    </select>
+
     <select id="balanceIncomeDetail" resultType="java.util.LinkedHashMap">
         SELECT o.card_id AS cardId,
                o.card_no AS cardNo,
diff --git a/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/CardChargingOrderSummaryMapperTest.java b/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/CardChargingOrderSummaryMapperTest.java
index f18cd5d..8aa69d9 100644
--- a/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/CardChargingOrderSummaryMapperTest.java
+++ b/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/mapper/CardChargingOrderSummaryMapperTest.java
@@ -18,11 +18,16 @@
     @Test
     void splitsSummaryQueriesForMyCatAndRequiresCompleteTimeRanges() throws IOException {
         String mapper = resource("mapper/order/TCardChargingOrderMapper.xml");
+        String pageList = select(mapper, "pageList");
         String summary = select(mapper, "summary");
         String orderIds = select(mapper, "summaryOrderIds");
         String share = select(mapper, "shareIncomeSummaryByOrderIds");
         String accounting = select(mapper, "accountingSummaryByOrderIds");
+        String capacity = select(mapper, "capacitySummaryByOrderIds");
 
+        assertTrue(pageList.contains("SELECT o.*"));
+        assertFalse(pageList.contains(" JOIN "));
+        assertFalse(pageList.contains("t_card_charging_order_accounting_strategy"));
         assertTrue(summary.contains("FROM t_card_charging_order o"));
         assertFalse(summary.contains(" JOIN "));
         assertFalse(summary.contains("t_card_charging_order_share_record"));
@@ -30,6 +35,8 @@
         assertTrue(orderIds.contains("<include refid=\"queryCondition\"/>"));
         assertTrue(share.contains("charging_order_id IN"));
         assertTrue(accounting.contains("charging_order_id IN"));
+        assertTrue(capacity.contains("charging_order_id AS orderId"));
+        assertTrue(capacity.contains("GROUP BY charging_order_id"));
         assertTrue(mapper.contains("startTime1 != null and startTime1 != '' and startTime2 != null and startTime2 != ''"));
         assertTrue(mapper.contains("endTime1 != null and endTime1 != '' and endTime2 != null and endTime2 != ''"));
     }
diff --git a/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/TCardChargingOrderSummaryTest.java b/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/TCardChargingOrderSummaryTest.java
index 84d5ef0..4e1b0de 100644
--- a/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/TCardChargingOrderSummaryTest.java
+++ b/ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/TCardChargingOrderSummaryTest.java
@@ -16,6 +16,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyList;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -24,6 +25,34 @@
 class TCardChargingOrderSummaryTest {
 
     @Test
+    void fillsElectronicProportionFromCapacitySummaryInBatches() {
+        TCardChargingOrderServiceImpl service = new TCardChargingOrderServiceImpl();
+        TCardChargingOrderMapper mapper = mock(TCardChargingOrderMapper.class);
+        ReflectionTestUtils.setField(service, "baseMapper", mapper);
+        List<com.ruoyi.order.api.vo.ChargingOrderVO> orders = new ArrayList<>();
+        for (long id = 1; id <= 501; id++) {
+            com.ruoyi.order.api.vo.ChargingOrderVO order = new com.ruoyi.order.api.vo.ChargingOrderVO();
+            order.setId(id);
+            orders.add(order);
+        }
+        Map<String, Object> capacity = new HashMap<>();
+        capacity.put("orderId", 1L);
+        capacity.put("capacityTotal", new BigDecimal("10"));
+        capacity.put("capacity1", new BigDecimal("4"));
+        capacity.put("capacity2", new BigDecimal("3"));
+        capacity.put("capacity3", new BigDecimal("2"));
+        capacity.put("capacity4", BigDecimal.ONE);
+        doReturn(Collections.singletonList(capacity), Collections.emptyList())
+                .when(mapper).capacitySummaryByOrderIds(anyList());
+
+        ReflectionTestUtils.invokeMethod(service, "fillElectronicProportion", orders);
+
+        assertEquals("40%-30%-20%-10%", orders.get(0).getElectronicProportion());
+        assertEquals("0%-0%-0%-0%", orders.get(500).getElectronicProportion());
+        verify(mapper, times(2)).capacitySummaryByOrderIds(anyList());
+    }
+
+    @Test
     void mergesShareAndAccountingSummariesInBatches() {
         TCardChargingOrderServiceImpl service = new TCardChargingOrderServiceImpl();
         TCardChargingOrderMapper mapper = mock(TCardChargingOrderMapper.class);
diff --git a/sql/20260902_add_charging_order_vin.sql b/sql/20260902_add_charging_order_vin.sql
new file mode 100644
index 0000000..5025040
--- /dev/null
+++ b/sql/20260902_add_charging_order_vin.sql
@@ -0,0 +1,56 @@
+-- Add VIN snapshot column to every physical charging-order shard.
+-- Execute directly on the backend MySQL instance, not through the database proxy.
+-- The procedure is idempotent and only alters existing tables that lack the column.
+
+USE `charging_pile_order`;
+
+DROP PROCEDURE IF EXISTS `add_charging_order_vin`;
+DELIMITER $$
+CREATE PROCEDURE `add_charging_order_vin`()
+BEGIN
+    DECLARE shard_no INT DEFAULT 0;
+    DECLARE target_table VARCHAR(64);
+    DECLARE table_exists INT DEFAULT 0;
+    DECLARE column_exists INT DEFAULT 0;
+
+    WHILE shard_no < 50 DO
+        SET target_table = CONCAT('t_charging_order_', shard_no);
+
+        SELECT COUNT(*) INTO table_exists
+        FROM information_schema.tables
+        WHERE table_schema = DATABASE()
+          AND table_name = target_table;
+
+        SELECT COUNT(*) INTO column_exists
+        FROM information_schema.columns
+        WHERE table_schema = DATABASE()
+          AND table_name = target_table
+          AND column_name = 'vin';
+
+        IF table_exists = 1 AND column_exists = 0 THEN
+            SET @ddl = CONCAT(
+                'ALTER TABLE `', target_table,
+                '` ADD COLUMN `vin` varchar(17) NULL AFTER `reservation_time`'
+            );
+            PREPARE stmt FROM @ddl;
+            EXECUTE stmt;
+            DEALLOCATE PREPARE stmt;
+        END IF;
+
+        SET shard_no = shard_no + 1;
+    END WHILE;
+END$$
+DELIMITER ;
+
+CALL `add_charging_order_vin`();
+DROP PROCEDURE `add_charging_order_vin`;
+
+SELECT COUNT(*) AS shard_count,
+       SUM(CASE WHEN c.column_name = 'vin' THEN 1 ELSE 0 END) AS vin_column_count
+FROM information_schema.tables t
+LEFT JOIN information_schema.columns c
+       ON c.table_schema = t.table_schema
+      AND c.table_name = t.table_name
+      AND c.column_name = 'vin'
+WHERE t.table_schema = DATABASE()
+  AND t.table_name REGEXP '^t_charging_order_[0-9]+$';

--
Gitblit v1.7.1