From 8b8971e94db61fb346598a2402d65c8ddb196d6b Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期六, 03 十月 2026 20:23:30 +0800
Subject: [PATCH] fix(holiday): 快报民航累计同比只与往年已覆盖日期比较
---
HANDOFF.md | 7 +++
traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java | 65 ++++++++++++++++++++++++++++++++
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java | 24 +++++++++++-
3 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/HANDOFF.md b/HANDOFF.md
index 8ab0814..189008f 100644
--- a/HANDOFF.md
+++ b/HANDOFF.md
@@ -23,6 +23,13 @@
- **楠岃瘉**锛歁aven 缂栬瘧鍜屾祴璇曢�氳繃锛涢噸鏂扮敓鎴� 2026-10-01 蹇姤锛屾鏂囦粛涓衡�滃闀�2.3%鈥濅笖涓嶅惈鈥滃闀夸簡鈥濓紱Word 瀵煎嚭鐢� 2 椤垫仮澶嶄负 1 椤碉紝鏁板瓧涓嶅啀鎷嗚銆傛渶缁堟牱鎶ヨ鏈湴 `_tmp_holiday_verify/bulletin_final_signed_styled_2026-10-01.docx`銆�
- **鐘舵��**锛�2026-10-03 鐢ㄦ埛楠屾敹閫氳繃锛涙湰娆℃彁浜ゅ彧鍖呭惈浠g爜銆佸洖褰掓祴璇曞拰鏈氦鎺ヨ褰曪紝涓嶅寘鍚� `_tmp_*` 杩囩▼浜х墿鍙婄敤鎴锋湭鎻愪氦鐨勬暟鎹枃浠堕噸鍛藉悕銆�
+### 10-03 娣卞锛�2锛夛細缂哄綋鏃ユ皯鑸暟鎹椂鐨勭疮璁″悓姣斿姣旀湡闂翠慨姝�
+- **蹇姤姘戣埅绱鍚屾瘮瀵规瘮鏈熼棿淇锛�2026-10-03锛岀己褰撴棩姘戣埅鏁版嵁鍦烘櫙锛�**锛氬綋鏌愯繍杈撴柟寮忓綋骞寸疮璁¤鐩栫殑鏃ユ湡鐭簬鎵�閫夋棩鏈燂紙鍏稿瀷涓� 10 鏈� 2 鏃ユ皯鑸暟鎹湭鍑恒�佹皯鑸疮璁″彧鏈� 10-01锛夛紝绱鍚屾瘮鏀逛负銆屽彧鍜屽線骞村凡缁忚鐩栧埌鐨勬棩鏈熸瘮杈冦�嶁�斺�斿厛鎵惧綋骞存渶鍚庝竴涓湁璇ユ寚鏍囨暟鎹殑鏃ユ湡锛屽啀鍙栧線骞村悓鏃ョ疮璁°�備慨澶嶅悗缂哄け姘戣埅鐨� 10 鏈� 2 鏃ュ揩鎶ユ皯鑸疮璁″悓姣旂敱 `-50.5%/-49.9%` 鍙樹负 `-10.0%/-0.9%`锛堜笌鎵嬪伐绋� -10.03%/-0.87% 鐨� 1 浣嶅皬鏁板�间竴鑷达級銆傚疄鐜拌 `HolidayBulletinService.comparableCumulative`锛堜粎浣滅敤浜庢皯鑸锛夛紝鍏朵綑琛屼笌鎬讳汉鍛樻祦鍔ㄩ噺鍙e緞涓嶅彉銆�
+- **銆岀疮璁″悓姣� -4.65% vs 蹇姤 -4.6%銆嶇粨璁猴紙2026-10-03锛屾棤闇�鏀逛唬鐮侊級**锛欵xcel 鏄剧ず鐨� -4.65% 鏄�**涓や綅灏忔暟**缁撴灉锛涘簳灞傜簿纭瘮鍊兼槸 `-4.64633%`锛�2026 绱 3082.23818銆�2025 绱 3232.42742锛夛紝**涓�娆″洓鑸嶄簲鍏ュ埌 1 浣嶅皬鏁板氨鏄� -4.6%**銆傛妸宸茬粡鍙栧埌涓や綅灏忔暟鐨� -4.65 鍐嶅彇涓�浣嶆墠寰楀埌 -4.7锛屽睘浜屾鍙栨暣锛屼笉閲囩敤銆傚悓鐞� 2026 瀵� 2024 涓� `-1.7710%` 鈫� `-1.8%`銆傚揩鎶ョ櫨鍒嗘瘮缁熶竴 1 浣嶅皬鏁板彛寰勪笉鍙樸��
+- **銆屾殏缂烘皯鑸�嶆彁绀�**锛氱敤鎴风‘璁ょ敱浜哄伐鍦ㄧ敓鎴愮殑蹇姤绋夸笂淇敼锛岀郴缁熶笉鐢熸垚璇ユ彁绀鸿锛�**涓嶅仛浠g爜鏀瑰姩**銆�
+- **楠岃瘉**锛歚HolidayBulletinServiceTest` 3 涓敤渚嬮�氳繃锛堟柊澧� 2 涓鐩栨皯鑸疮璁″姣旀湡闂翠笌鏃犳暟鎹繑鍥� null锛夛紱绔埌绔敤搴撳唴鐪熷疄 2026-10-02 鏁版嵁锛堥搧璺�/閬撹矾/姘磋矾/杞︽祦榻愬叏銆佺己姘戣埅锛夐噸鏂扮敓鎴愬揩鎶ワ紝姘戣埅绱鍚屾瘮 `-10.0%/-0.9%`銆佹皯鑸疮璁� `6.75`銆佹�昏绱 `3082.24`銆佹�昏绱鍚屾瘮 `-4.6%/-1.8%`锛屼笌鎵嬪伐绋垮彛寰勪竴鑷淬��
+- **Git**锛氭湰娆℃敼鍔ㄥ緟鐢ㄦ埛銆岄獙鏀堕�氳繃銆嶅悗鍐嶆彁浜�/鎺ㄩ�併��
+
---
### 琛ュ厖锛�10-03 涓嬪崍锛夛細鏈嶅姟鍣ㄩ儴缃叉姤 鈥淎ccess denied ... (using password: NO)鈥� 鈥斺�� 鏍瑰洜涓庝慨澶�
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java
index 1ef5884..a80ca4f 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java
+++ b/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;
@@ -131,6 +132,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 +179,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 +337,21 @@
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 ratio(BigDecimal current, BigDecimal base) {
if (current == null || base == null || base.abs().compareTo(EPSILON) < 0) return "鈥�";
BigDecimal ratio = HolidayNumberUtils.divide(current, base);
diff --git a/traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java b/traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java
index 4830de8..7f585b3 100644
--- a/traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java
+++ b/traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayBulletinServiceTest.java
@@ -1,11 +1,19 @@
package com.trafficaudit.holiday.service;
+import com.trafficaudit.holiday.service.HolidayStatService.DailyMetrics;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
import java.math.BigDecimal;
+import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
class HolidayBulletinServiceTest {
@@ -21,6 +29,63 @@
assertEquals("鈥�", ratio(service, "100", "0"));
}
+ @Test
+ void comparesCivilAviationOnlyThroughCoveredDay() throws Exception {
+ HolidayStatService stat = mock(HolidayStatService.class);
+ HolidayBulletinService service = new HolidayBulletinService(stat);
+
+ DailyMetrics current = new DailyMetrics();
+ current.setYear(2026);
+ current.setHolidayType("NATIONAL_DAY");
+ current.setDayIndex(2);
+
+ DailyMetrics coveredDay = new DailyMetrics();
+ coveredDay.setCivilAviation(new BigDecimal("6.7482"));
+ DailyMetrics missingDay = new DailyMetrics();
+
+ when(stat.dailyMetrics(2026, "NATIONAL_DAY", 2)).thenReturn(missingDay);
+ when(stat.dailyMetrics(2026, "NATIONAL_DAY", 1)).thenReturn(coveredDay);
+
+ DailyMetrics previousYear = new DailyMetrics();
+ previousYear.setYear(2025);
+ DailyMetrics previousYearThroughDay1 = new DailyMetrics();
+ previousYearThroughDay1.setCivilAviation(new BigDecimal("7.5003"));
+ when(stat.cumulativeMetrics(2025, "NATIONAL_DAY", 1)).thenReturn(previousYearThroughDay1);
+
+ Object result = comparableCumulative(service, current, previousYear, DailyMetrics::getCivilAviation);
+
+ assertSame(previousYearThroughDay1, result);
+ verify(stat).cumulativeMetrics(2025, "NATIONAL_DAY", 1);
+ verify(stat, never()).cumulativeMetrics(2025, "NATIONAL_DAY", 2);
+ }
+
+ @Test
+ void comparableCumulativeIsNullWhenCurrentYearHasNoMetricData() throws Exception {
+ HolidayStatService stat = mock(HolidayStatService.class);
+ HolidayBulletinService service = new HolidayBulletinService(stat);
+
+ DailyMetrics current = new DailyMetrics();
+ current.setYear(2026);
+ current.setHolidayType("NATIONAL_DAY");
+ current.setDayIndex(2);
+ when(stat.dailyMetrics(2026, "NATIONAL_DAY", 2)).thenReturn(new DailyMetrics());
+ when(stat.dailyMetrics(2026, "NATIONAL_DAY", 1)).thenReturn(new DailyMetrics());
+
+ Object result = comparableCumulative(service, current, new DailyMetrics(), DailyMetrics::getCivilAviation);
+
+ assertNull(result);
+ verify(stat, never()).cumulativeMetrics(0, "NATIONAL_DAY", 1);
+ }
+
+ private Object comparableCumulative(HolidayBulletinService service, DailyMetrics current,
+ DailyMetrics comparisonYear,
+ Function<DailyMetrics, BigDecimal> selector) throws Exception {
+ Method method = HolidayBulletinService.class.getDeclaredMethod(
+ "comparableCumulative", DailyMetrics.class, DailyMetrics.class, Function.class);
+ method.setAccessible(true);
+ return method.invoke(service, current, comparisonYear, selector);
+ }
+
private String ratio(HolidayBulletinService service, String current, String base) throws Exception {
Method method = HolidayBulletinService.class.getDeclaredMethod("ratio", BigDecimal.class, BigDecimal.class);
method.setAccessible(true);
--
Gitblit v1.9.1