xyc
4 天以前 f329f504040f3608478c687a99aa36a3cf5720b7
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java
@@ -31,6 +31,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
@@ -77,8 +78,6 @@
        }
        String currentTotal = formatNumber(current.getTotalPersonFlow());
        String cumulativeTotalYi = formatNumber(currentCumulative.getTotalPersonFlow() == null
                ? null : HolidayNumberUtils.divide(currentCumulative.getTotalPersonFlow(), BigDecimal.valueOf(10000)));
        String ringRatioClause = previousDay == null ? "" : ",环比" + ratioPhrase(
                current.getTotalPersonFlow(), previousDay.getTotalPersonFlow());
        String paragraph1 = String.format("%d月%d日(假期第%d天),全省全社会跨区域人员流动量%s万人次%s,比2025年同期%s,比2024年同期%s。",
@@ -86,12 +85,7 @@
                ringRatioClause,
                ratioPhrase(current.getTotalPersonFlow(), previousYear == null ? null : previousYear.getTotalPersonFlow()),
                ratioPhrase(current.getTotalPersonFlow(), twoYearsAgo == null ? null : twoYearsAgo.getTotalPersonFlow()));
        String paragraph2 = String.format("假期以来,全省全社会跨区域人员流动量累计%s亿人次,比2025年同期%s,比2024年同期%s。",
                cumulativeTotalYi,
                ratioPhrase(currentCumulative.getTotalPersonFlow(),
                        previousYearCumulative == null ? null : previousYearCumulative.getTotalPersonFlow()),
                ratioPhrase(currentCumulative.getTotalPersonFlow(),
                        twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getTotalPersonFlow()));
        String paragraph2 = cumulativeParagraph(currentCumulative, previousYearCumulative, twoYearsAgoCumulative);
        File template = resolveTemplateFile();
        if (!template.exists() || !template.isFile()) {
@@ -131,6 +125,10 @@
        if (table == null) {
            throw new IllegalArgumentException("快报模板中找不到数据表");
        }
        DailyMetrics previousYearCivilCumulative = comparableCumulative(
                current, previousYear, DailyMetrics::getCivilAviation);
        DailyMetrics twoYearsAgoCivilCumulative = comparableCumulative(
                current, twoYearsAgo, DailyMetrics::getCivilAviation);
        writeTableRow(table, 2, new String[]{
                number(current.getNonBusinessPersonFlow()),
                ratio(current.getNonBusinessPersonFlow(), previousDay == null ? null : previousDay.getNonBusinessPersonFlow()),
@@ -174,8 +172,8 @@
                previousYear == null ? null : previousYear.getCivilAviation(),
                twoYearsAgo == null ? null : twoYearsAgo.getCivilAviation(),
                currentCumulative.getCivilAviation(),
                previousYearCumulative == null ? null : previousYearCumulative.getCivilAviation(),
                twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getCivilAviation()));
                previousYearCivilCumulative == null ? null : previousYearCivilCumulative.getCivilAviation(),
                twoYearsAgoCivilCumulative == null ? null : twoYearsAgoCivilCumulative.getCivilAviation()));
        writeTableRow(table, 7, transportRow(current.getWater(),
                previousDay == null ? null : previousDay.getWater(),
                previousYear == null ? null : previousYear.getWater(),
@@ -332,6 +330,31 @@
        return (percent.signum() > 0 ? "增长" : "下降") + HolidayNumberUtils.format1(percent.abs()) + "%";
    }
    private DailyMetrics comparableCumulative(DailyMetrics current, DailyMetrics comparisonYear,
                                              Function<DailyMetrics, BigDecimal> selector) {
        if (current == null || comparisonYear == null) return null;
        int coveredDay = 0;
        for (int day = current.getDayIndex(); day >= 1; day--) {
            DailyMetrics metrics = statService.dailyMetrics(current.getYear(), current.getHolidayType(), day);
            if (metrics != null && selector.apply(metrics) != null) {
                coveredDay = day;
                break;
            }
        }
        if (coveredDay == 0) return null;
        return statService.cumulativeMetrics(comparisonYear.getYear(), current.getHolidayType(), coveredDay);
    }
    private String cumulativeParagraph(DailyMetrics currentCumulative,
                                       DailyMetrics previousYearCumulative,
                                       DailyMetrics twoYearsAgoCumulative) {
        BigDecimal total = currentCumulative == null ? null : currentCumulative.getTotalPersonFlow();
        return String.format("假期以来,全省全社会跨区域人员流动量累计%s万人次,比2025年同期%s,比2024年同期%s。",
                formatNumber(total),
                ratioPhrase(total, previousYearCumulative == null ? null : previousYearCumulative.getTotalPersonFlow()),
                ratioPhrase(total, twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getTotalPersonFlow()));
    }
    private String ratio(BigDecimal current, BigDecimal base) {
        if (current == null || base == null || base.abs().compareTo(EPSILON) < 0) return "—";
        BigDecimal ratio = HolidayNumberUtils.divide(current, base);