longz
2026-08-05 b9b2447a76477c0ea184f0e3a76585b5fb7017c0
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -241,23 +241,47 @@
    @PostMapping("/app/franchisee/income")
    public R<Map<String, Object>> franchiseeIncome(@RequestBody(required = false) Map<String, Object> params) {
        List<Integer> siteIds = franchiseeSiteIds(params);
        LocalDate firstMonth = YearMonth.now().minusMonths(5).atDay(1);
        LocalDate nextMonth = YearMonth.now().plusMonths(1).atDay(1);
        List<FranchiseeDayStat> dayStats = franchiseeDayStats(siteIds,
                new LocalDateTime[]{firstMonth.atStartOfDay(), nextMonth.atStartOfDay()});
        List<SixChargingDto> sixChargingDtos;
        if (siteIds.isEmpty()) {
            // 无授权站点:返回近6月全零骨架,避免空 IN 导致全站点统计
            sixChargingDtos = generateLastSixMonths(LocalDate.now());
        } else {
            // 与后台 数据分析-平台总收入分析 电站收入分析口径一致:历史月读结算账单、当月补原始订单
            LocalDate sixBefore = PreviousSixMonths.get();
            List<SixChargingDto> chargingDtos = chargingOrderService.charge(sixBefore, siteIds, false);
            LocalDate statisticsEndMonth = resolveStatisticsEndMonth(LocalDate.now(), chargingDtos);
            sixChargingDtos = generateLastSixMonths(statisticsEndMonth);
            for (SixChargingDto sixChargingDto : sixChargingDtos) {
                for (SixChargingDto chargingDto : chargingDtos) {
                    if (sixChargingDto.getMonth().equals(chargingDto.getMonth())) {
                        BeanUtils.copyProperties(chargingDto, sixChargingDto);
                    }
                }
            }
        }
        BigDecimal electricity = sixChargingDtos.stream()
                .filter(Objects::nonNull)
                .map(SixChargingDto::getElectrovalence)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal service = sixChargingDtos.stream()
                .filter(Objects::nonNull)
                .map(SixChargingDto::getServiceCharge)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("totalIncome", sum(dayStats, FranchiseeDayStat::getPaymentAmount));
        result.put("electricityFee", sum(dayStats, FranchiseeDayStat::getElectrovalence));
        result.put("serviceFee", sum(dayStats, FranchiseeDayStat::getServiceFee));
        result.put("incomeColumn", franchiseeIncomeTrend(dayStats, firstMonth, 6));
        result.put("totalIncome", electricity.add(service));
        result.put("electricityFee", electricity);
        result.put("serviceFee", service);
        result.put("incomeColumn", franchiseeIncomeTrendFromSix(sixChargingDtos));
        List<Map<String, Object>> incomePie = new ArrayList<>();
        Map<String, Object> electricityItem = new LinkedHashMap<>();
        electricityItem.put("name", "充电费");
        electricityItem.put("value", sum(dayStats, FranchiseeDayStat::getElectrovalence));
        electricityItem.put("value", electricity);
        incomePie.add(electricityItem);
        Map<String, Object> serviceItem = new LinkedHashMap<>();
        serviceItem.put("name", "服务费");
        serviceItem.put("value", sum(dayStats, FranchiseeDayStat::getServiceFee));
        serviceItem.put("value", service);
        incomePie.add(serviceItem);
        result.put("incomePie", incomePie);
        return R.ok(result);
@@ -763,22 +787,28 @@
        List<Map<String, Object>> data = new ArrayList<>(); for (int i = 0; i < names.length; i++) { Map<String, Object> item = new LinkedHashMap<>(); item.put("name", names[i]); item.put("value", counts[i]); data.add(item); }
        return Collections.singletonMap("series", Collections.singletonList(Collections.singletonMap("data", data)));
    }
    private Map<String, Object> franchiseeIncomeTrend(List<FranchiseeDayStat> stats, LocalDate firstMonth, int monthCount) {
    /** 收支分析近6月柱状图:与后台 电站收入分析 一致(历史月结算账单 + 当月原始订单)。 */
    private Map<String, Object> franchiseeIncomeTrendFromSix(List<SixChargingDto> months) {
        List<String> categories = new ArrayList<>();
        List<BigDecimal> electricity = new ArrayList<>(), service = new ArrayList<>();
        Map<YearMonth, List<FranchiseeDayStat>> byMonth = stats.stream().filter(stat -> stat != null && stat.getStatDay() != null)
                .collect(Collectors.groupingBy(stat -> YearMonth.from(stat.getStatDay())));
        for (int i = 0; i < monthCount; i++) {
            YearMonth month = YearMonth.from(firstMonth).plusMonths(i);
            categories.add(String.format("%02d月", month.getMonthValue()));
            List<FranchiseeDayStat> monthStats = byMonth.getOrDefault(month, Collections.emptyList());
            electricity.add(sum(monthStats, FranchiseeDayStat::getElectrovalence));
            service.add(sum(monthStats, FranchiseeDayStat::getServiceFee));
        for (SixChargingDto month : months) {
            if (month == null) {
                continue;
            }
            categories.add(month.getMonth() + "月");
            electricity.add(month.getElectrovalence() == null ? BigDecimal.ZERO : month.getElectrovalence());
            service.add(month.getServiceCharge() == null ? BigDecimal.ZERO : month.getServiceCharge());
        }
        Map<String, Object> chart = new LinkedHashMap<>(); chart.put("categories", categories);
        Map<String, Object> electricitySeries = new LinkedHashMap<>(); electricitySeries.put("name", "充电费"); electricitySeries.put("data", electricity);
        Map<String, Object> serviceSeries = new LinkedHashMap<>(); serviceSeries.put("name", "服务费"); serviceSeries.put("data", service);
        chart.put("series", new ArrayList<>(Arrays.asList(electricitySeries, serviceSeries))); return chart;
        Map<String, Object> chart = new LinkedHashMap<>();
        chart.put("categories", categories);
        Map<String, Object> electricitySeries = new LinkedHashMap<>();
        electricitySeries.put("name", "充电费");
        electricitySeries.put("data", electricity);
        Map<String, Object> serviceSeries = new LinkedHashMap<>();
        serviceSeries.put("name", "服务费");
        serviceSeries.put("data", service);
        chart.put("series", new ArrayList<>(Arrays.asList(electricitySeries, serviceSeries)));
        return chart;
    }