yanderong
2026-08-18 036efa3349b001fc96d1d95ea08cf6997eaf0db9
Merge remote-tracking branch 'origin/2.2' into 2.2
3个文件已修改
92 ■■■■■ 已修改文件
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/controller/TChargingOrderControllerTest.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -220,9 +220,13 @@
        LocalDateTime[] range = franchiseeRange(params);
        List<FranchiseeDayStat> dayStats = franchiseeDayStats(siteIds, range);
        Map<String, Object> summary = new LinkedHashMap<>();
        summary.put("orderAmountWan", franchiseeOrderAmountWan(dayStats));
        BigDecimal incomeWan = franchiseeIncomeWan(dayStats);
        BigDecimal totalChargingCapacityWan = sum(dayStats, FranchiseeDayStat::getCapacity).divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP);
        summary.put("incomeWan", incomeWan);
        summary.put("orderAmountWan", incomeWan);
        summary.put("serviceFeeWan", sum(dayStats, FranchiseeDayStat::getServiceFee).divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP));
        summary.put("chargingPowerWan", sum(dayStats, FranchiseeDayStat::getCapacity).divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP));
        summary.put("totalChargingCapacityWan", totalChargingCapacityWan);
        summary.put("chargingPowerWan", totalChargingCapacityWan);
        summary.put("chargingAmount", sum(dayStats, FranchiseeDayStat::getChargingIncome));
        summary.put("chargingOrderCount", dayStats.stream().mapToLong(stat -> numberValue(stat.getOrderCount())).sum());
        summary.put("powerUtilizationRate", observedPowerUtilization(dayStats));
@@ -649,8 +653,8 @@
        return new LocalDateTime[]{today.atStartOfDay(), today.plusDays(1).atStartOfDay()};
    }
    static BigDecimal franchiseeOrderAmountWan(List<FranchiseeDayStat> stats) {
        return stats.stream().map(FranchiseeDayStat::getPaymentAmount)
    static BigDecimal franchiseeIncomeWan(List<FranchiseeDayStat> stats) {
        return stats.stream().map(FranchiseeDayStat::getChargingIncome)
                .map(value -> value == null ? BigDecimal.ZERO : value)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP);
ruoyi-service/ruoyi-order/src/main/resources/mapper/order/TChargingOrderMapper.xml
@@ -3615,47 +3615,50 @@
            ArrayIndexOutOfBoundsException:17 / "is not being grouped" 规划崩溃;
         2) 聚合表达式内禁用 LEAST(),LEAST(ROUND(...)) 会触发 NPE,用嵌套 CASE 等价封顶替代。 -->
    <!-- 按 end_time 日聚合: 订单数/金额/服务费/电费/电量/功率/需求满足率/利用率 -->
    <!-- 按 end_time 日聚合: 关键数据收入/服务费/总充电电量与管理后台 chargingOrderBaseSummary 保持一致 -->
    <select id="franchiseeDayStats" resultType="com.ruoyi.order.dto.FranchiseeDayStat">
        SELECT DATE(end_time)                       AS statDay,
               COUNT(*)                             AS orderCount,
               SUM(IFNULL(order_amount, 0))         AS orderAmount,
               SUM(COALESCE(order_amount, payment_amount)) AS orderAmountEffective,
               SUM(IFNULL(payment_amount, 0))       AS paymentAmount,
               SUM(IFNULL(service_charge, 0))       AS serviceFee,
               SUM(IFNULL(electrovalence, 0))       AS electrovalence,
               SUM(IFNULL(electrovalence, 0) + CASE
                       WHEN order_source = 1 THEN IFNULL(service_charge, 0)
                       ELSE IFNULL(service_charge, 0) * 0.8
                   END + CASE
                       WHEN is_whitelist = 1 THEN IFNULL(whitelist_electric_refund_amount, 0)
                               + IFNULL(whitelist_service_refund_amount, 0)
                       ELSE 0
                   END)                              AS chargingIncome,
               SUM(IFNULL(charging_capacity, 0))    AS capacity,
               SUM(IFNULL(charging_power, power))   AS totalPower,
               COUNT(IFNULL(charging_power, power)) AS powerCount,
               MAX(IFNULL(IFNULL(charging_power, power), 0)) AS maxPower,
               SUM(CASE WHEN `current` IS NOT NULL AND need_elec IS NOT NULL AND need_elec &gt; 0
                        THEN CASE WHEN ROUND(`current` * 100 / need_elec, 4) &gt; 100 THEN 100
                                  ELSE ROUND(`current` * 100 / need_elec, 4) END ELSE 0 END) AS elecSatSum,
               SUM(CASE WHEN `current` IS NOT NULL AND need_elec IS NOT NULL AND need_elec &gt; 0
                        THEN 1 ELSE 0 END)          AS elecSatCount,
               SUM(CASE WHEN IFNULL(IFNULL(charging_power, power), 0) &gt; 0
                        THEN IFNULL(IFNULL(charging_power, power), 0) ELSE 0 END) AS utilPowerSum,
               SUM(CASE WHEN IFNULL(IFNULL(charging_power, power), 0) &gt; 0
                        THEN 1 ELSE 0 END)          AS utilPowerCount
        FROM t_charging_order
        WHERE del_flag = 0
          AND recharge_payment_status = 2
        SELECT DATE(b.end_time)                       AS statDay,
               COUNT(*)                               AS orderCount,
               SUM(IFNULL(b.order_amount, 0))         AS orderAmount,
               SUM(COALESCE(b.order_amount, b.payment_amount)) AS orderAmountEffective,
               SUM(IFNULL(b.payment_amount, 0))       AS paymentAmount,
               SUM(COALESCE(summary.service_price, CASE
                       WHEN b.order_source = 1 THEN IFNULL(b.service_charge, 0)
                       ELSE IFNULL(b.service_charge, 0) * 0.8
                   END))                               AS serviceFee,
               SUM(COALESCE(summary.electric_price, IFNULL(b.electrovalence, 0))) AS electrovalence,
               SUM(COALESCE(summary.income, IFNULL(b.electrovalence, 0) + CASE
                       WHEN b.order_source = 1 THEN IFNULL(b.service_charge, 0)
                       ELSE IFNULL(b.service_charge, 0) * 0.8
                   END))                               AS chargingIncome,
               SUM(COALESCE(summary.charging_capacity, IFNULL(b.charging_capacity, 0))) AS capacity,
               SUM(IFNULL(b.charging_power, b.power))  AS totalPower,
               COUNT(IFNULL(b.charging_power, b.power)) AS powerCount,
               MAX(IFNULL(IFNULL(b.charging_power, b.power), 0)) AS maxPower,
               SUM(CASE WHEN b.`current` IS NOT NULL AND b.need_elec IS NOT NULL AND b.need_elec &gt; 0
                        THEN CASE WHEN ROUND(b.`current` * 100 / b.need_elec, 4) &gt; 100 THEN 100
                                  ELSE ROUND(b.`current` * 100 / b.need_elec, 4) END ELSE 0 END) AS elecSatSum,
               SUM(CASE WHEN b.`current` IS NOT NULL AND b.need_elec IS NOT NULL AND b.need_elec &gt; 0
                        THEN 1 ELSE 0 END)             AS elecSatCount,
               SUM(CASE WHEN IFNULL(IFNULL(b.charging_power, b.power), 0) &gt; 0
                        THEN IFNULL(IFNULL(b.charging_power, b.power), 0) ELSE 0 END) AS utilPowerSum,
               SUM(CASE WHEN IFNULL(IFNULL(b.charging_power, b.power), 0) &gt; 0
                        THEN 1 ELSE 0 END)             AS utilPowerCount
        FROM `charging_pile_order`.t_charging_order b
        LEFT JOIN `charging_pile_order`.t_charging_order_summary_data summary
          ON summary.charging_order_id = b.id
        WHERE b.del_flag = 0
          AND b.recharge_payment_status = 2
          AND b.start_time IS NOT NULL
          AND b.end_time IS NOT NULL
        <if test="siteIds != null and siteIds.size() > 0">
            AND site_id IN
            AND b.site_id IN
            <foreach collection="siteIds" item="siteId" open="(" separator="," close=")">
                #{siteId}
            </foreach>
        </if>
          AND end_time &gt;= #{start}
          AND end_time &lt; #{end}
          AND b.end_time &gt;= #{start}
          AND b.end_time &lt; #{end}
        GROUP BY 1
    </select>
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/controller/TChargingOrderControllerTest.java
@@ -36,13 +36,14 @@
class TChargingOrderControllerTest {
    @Test
    void franchiseeOrderAmountWanUsesActualPaymentInsteadOfOperatingIncome() {
    void franchiseeIncomeWanUsesManagementOrderSummaryIncome() {
        FranchiseeDayStat discountedOrder = new FranchiseeDayStat();
        discountedOrder.setPaymentAmount(new BigDecimal("90"));
        discountedOrder.setChargingIncome(new BigDecimal("104"));
        FranchiseeDayStat emptyIncomeOrder = new FranchiseeDayStat();
        assertEquals(new BigDecimal("0.0090"),
                TChargingOrderController.franchiseeOrderAmountWan(Arrays.asList(discountedOrder)));
        assertEquals(new BigDecimal("0.0104"),
                TChargingOrderController.franchiseeIncomeWan(Arrays.asList(discountedOrder, emptyIncomeOrder)));
    }
    @Test