From 67cd940347bfe38ef6aab075a2dbd738bec41ed3 Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期六, 03 十月 2026 14:43:44 +0800
Subject: [PATCH] feat(holiday): support 2019 and previous-day data in new templates

---
 deploy-templates/db/sql_holiday_previous_day_migration.sql                                      |    8 +
 deploy-templates/db/init.sql                                                                    |    2 
 traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayWorkbookService.java |  217 ++++++++++++++++++++++++++++--
 docs/init.sql                                                                                   |    2 
 docs/专项统计/重要节假日/湖北省国庆假期综合运输客流快报模板.docx                                                          |    0 
 docs/sql_holiday_previous_day_migration.sql                                                     |    8 +
 docs/专项统计/重要节假日/2026年十一数据.xlsx                                                                  |    0 
 traffic-audit-web/src/views/SystemConfig.vue                                                    |   17 +
 traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java     |   16 +
 HANDOFF.md                                                                                      |   11 +
 deploy-templates/README-部署说明.txt                                                                |    3 
 traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayConfigService.java   |   13 +
 docs/database.md                                                                                |   12 +
 docs/打包部署说明.md                                                                                  |    5 
 docs/专项统计/重要节假日/备份/2026年十一数据.xlsx                                                               |    0 
 deploy-templates/db/sql_holiday.sql                                                             |    1 
 traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayBulletinService.java |   98 +++++++++----
 17 files changed, 346 insertions(+), 67 deletions(-)

diff --git a/HANDOFF.md b/HANDOFF.md
index 9b7f4af..f550548 100644
--- a/HANDOFF.md
+++ b/HANDOFF.md
@@ -6,6 +6,17 @@
 
 ## 鏈�鏂帮紙2026-10-03锛�
 
+### 10-03 鏅氾細閲嶈鑺傚亣鏃ユ柊妯℃澘锛�2019/鍓嶄竴鏃ワ級閫傞厤
+- **妯℃澘鍙樺寲**锛歚2026骞村崄涓�鏁版嵁.xlsx` 鐨勯亾璺〃澧炲姞 2019 骞村強鍚屾瘮2019锛涢搧璺�佹皯鑸鍔犫�滃墠涓�鏃モ�濊锛涘揩鎶ユā鏉垮鍔犲悓姣�2024 鍒椼�傛棫妯℃澘宸叉斁鍦� `docs/涓撻」缁熻/閲嶈鑺傚亣鏃�/澶囦唤/`銆�
+- **鏁版嵁搴撳垵濮嬪寲**锛氬惎鍔ㄦ椂鐩存帴鍐欏叆 2019 閬撹矾鏁版嵁锛屼互鍙� 2024/2025/2026 骞撮搧璺�佹皯鑸墠涓�鏃ユ暟鎹紱`holiday_calendar.day_index=0` 琛ㄧず鈥滃墠涓�鏃モ�濓紝鏃у簱鍚姩浼氳嚜鍔ㄨˉ榻愬凡鏈夊勾浠界殑鍓嶄竴鏃ラ厤缃锛屼笖涓嶈鐩栫鐞嗗憳宸茬淮鎶ょ殑鏃ユ湡銆�
+- **姝e父瀵煎叆鍙e緞**锛氬彧璇诲彇鎵�閫夊勾浠界殑褰撳勾鍒楋紙2026 骞撮搧璺�/姘戣埅/閬撹矾/姘磋矾涓� C 鍒椼�侀珮閫熶负 C 鍒椼�佹櫘閫氬浗鐪侀亾涓� D 鍒楋級锛涘悓鏃跺彧棰濆璇诲彇褰撳墠骞翠唤閾佽矾/姘戣埅鐨勨�滃墠涓�鏃モ�濊銆�2019/2024/2025 鍘嗗彶鍒椾笉鍙備笌瀵煎叆銆�
+- **蹇姤鍙e緞**锛氬悓姣斿彧浣跨敤 2025銆�2024锛涘亣鏈熺 1 鏃ョ殑閾佽矾銆佹皯鑸幆姣斾娇鐢ㄢ�滃墠涓�鏃モ�濇暟鎹紝鍏矾銆佹按璺�佹�昏鍙婂叾浠栧彛寰勭 1 鏃ヤ粛鏄剧ず鈥溾�斺�濓紱绗� 2 鏃ヨ捣姝e父璁$畻鐜瘮銆�
+- **杩佺Щ鑴氭湰**锛歚docs/sql_holiday_previous_day_migration.sql`锛岄儴缃插寘鍚屾涓� `deploy-templates/db/sql_holiday_previous_day_migration.sql`锛岃剼鏈彲閲嶅鎵ц銆�
+- **楠岃瘉锛堟湰鏈� 3305 搴� + 鐪熷疄妯℃澘锛�**锛氭帴鍙e鍏ョ粨鏋� `passengerRows=10, vehicleRows=4, successRows=14, failRows=0`锛涙暟鎹簱鎶芥煡 2026-09-30 閾佽矾=82.1銆佹皯鑸�=6.6994锛�2026-10-01 閾佽矾=113.8銆佹皯鑸�=6.7482銆侀亾璺�=78.82銆佹按璺�=1.311锛�2026-10-02 閾佽矾=82.0銆佹皯鑸�=6.3914銆侀亾璺�=75.61銆佹按璺�=3.3373锛�2026-10-01 蹇姤閾佽矾鐜瘮=+38.6%銆佹皯鑸幆姣�=+0.7%锛屾�昏鐜瘮涓衡�溾�斺�濓紱2026-10-02 閾佽矾鐜瘮=-27.9%銆佹皯鑸幆姣�=-5.3%銆�
+- **杩愯鐘舵��**锛氬悗绔� 8090锛堥噸鍚悗宸插姞杞芥柊浠g爜锛夈�佸墠绔� 8080 鍧囧湪杩愯锛涜闂� `http://localhost:8080`銆�
+
+---
+
 ### 琛ュ厖锛�10-03 涓嬪崍锛夛細鏈嶅姟鍣ㄩ儴缃叉姤 鈥淎ccess denied ... (using password: NO)鈥� 鈥斺�� 鏍瑰洜涓庝慨澶�
 - **鐜拌薄**锛氭妸 `deploy/traffic-audit-release-20261002/` 閮ㄧ讲鍒� `61.183.254.94` 鍚庯紝鍚庣鍚姩鎶� `java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)`銆�
 - **鏍瑰洜**锛歫ar 鍐呯疆閰嶇疆閲屽簱鍙d护鏄崰浣嶇 `${TRAFFIC_DB_PASSWORD:}`锛堥粯璁ょ┖涓诧級锛岃�� 10-02 閭d釜鍖�**鍙惈 jar + web + dist**锛屾病鏈夊缃� `application.yml`銆佹病鏈� `docs/`銆乣db/`銆佸惎鍔ㄨ剼鏈�傞儴缃叉満娌℃湁浠讳綍澶栭儴閰嶇疆瑕嗙洊锛孲pring 灏辨嬁绌哄瘑鐮佽繛鏈満 MySQL 鈫� `using password: NO`锛堟敞鎰忥細杩欐槸鈥滄湯浼犲瘑鐮佲�濓紝涓嶆槸瀵嗙爜閿欙級銆�
diff --git "a/deploy-templates/README-\351\203\250\347\275\262\350\257\264\346\230\216.txt" "b/deploy-templates/README-\351\203\250\347\275\262\350\257\264\346\230\216.txt"
index 9c4b6a7..357a775 100644
--- "a/deploy-templates/README-\351\203\250\347\275\262\350\257\264\346\230\216.txt"
+++ "b/deploy-templates/README-\351\203\250\347\275\262\350\257\264\346\230\216.txt"
@@ -39,6 +39,7 @@
     sql_holiday.sql                          涓撻」缁熻-閲嶈鑺傚亣鏃ヨ〃锛堟棫搴撶己琛ㄦ椂鎵ц锛�
     sql_holiday_decimal_migration.sql        鑺傚亣鏃ユ暟鍊煎垪绮惧害杩佺Щ锛堟棫搴撳崌绾э級
     sql_holiday_comparison_base_migration.sql 鑺傚亣鏃ョ幆姣斿熀鏈熷瓧娈佃縼绉伙紙鏃у簱鍗囩骇锛�
+    sql_holiday_previous_day_migration.sql    鑺傚亣鏃ュ墠涓�鏃ラ厤缃縼绉伙紙鏃у簱鍗囩骇锛�
   README-閮ㄧ讲璇存槑.txt
 
 銆愰儴缃叉満鐜瑕佹眰銆�
@@ -68,7 +69,7 @@
        mysql --default-character-set=utf8mb4 -u root -p traffic_audit < db/sql_city_bus.sql
        mysql --default-character-set=utf8mb4 -u root -p traffic_audit < db/sql_city_taxi.sql
        mysql --default-character-set=utf8mb4 -u root -p traffic_audit < db/sql_wyc.sql
-     娉細鍏ㄦ柊搴撶殑 init.sql 宸插惈鑺傚亣鏃� 4 寮犺〃锛涜嫢鏄湪鏃╂湡鐗堟湰搴撲笂琛ヨ妭鍋囨棩妯″潡锛屽啀鎵ц db/sql_holiday.sql锛屽苟鎸夐渶鎵ц涓や釜杩佺Щ鑴氭湰銆�
+     娉細鍏ㄦ柊搴撶殑 init.sql 宸插惈鑺傚亣鏃� 4 寮犺〃锛涜嫢鏄湪鏃╂湡鐗堟湰搴撲笂琛ヨ妭鍋囨棩妯″潡锛屽啀鎵ц db/sql_holiday.sql锛屽苟鎸夐渶鎵ц涓変釜杩佺Щ鑴氭湰锛堟暟鍊肩簿搴︺�佺幆姣斿熀鏈熴�佸墠涓�鏃ラ厤缃級銆傚墠涓�鏃ヨ縼绉昏剼鏈彲閲嶅鎵ц銆�
      棰勭疆璐﹀彿锛歛dmin / admin123锛堥娆$櫥褰曞悗璇锋敼瀵嗙爜锛�
 
   2. 鏀归厤缃� backend/application.yml
diff --git a/deploy-templates/db/init.sql b/deploy-templates/db/init.sql
index dcc9932..70df0b6 100644
--- a/deploy-templates/db/init.sql
+++ b/deploy-templates/db/init.sql
@@ -632,7 +632,7 @@
   year INT NOT NULL COMMENT '骞翠唤',
   holiday_type VARCHAR(32) NOT NULL COMMENT '鑺傚亣鏃ュ垎绫伙細SPRING_FESTIVAL/LABOR_DAY/NATIONAL_DAY',
   holiday_date DATE NOT NULL COMMENT '鑺傚亣鏃ュ叿浣撴棩鏈�',
-  day_index INT NOT NULL COMMENT '绗嚑鏃ワ紝浠� 1 寮�濮�',
+  day_index INT NOT NULL COMMENT '0=鍓嶄竴鏃ワ紝1..N=鍋囨湡绗琋鏃�',
   created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
   updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (id),
diff --git a/deploy-templates/db/sql_holiday.sql b/deploy-templates/db/sql_holiday.sql
index ca39066..a2b6b59 100644
--- a/deploy-templates/db/sql_holiday.sql
+++ b/deploy-templates/db/sql_holiday.sql
@@ -4,6 +4,7 @@
   year INT NOT NULL,
   holiday_type VARCHAR(32) NOT NULL,
   holiday_date DATE NOT NULL,
+  -- 0 is the configured previous day; normal holiday days are 1..N.
   day_index INT NOT NULL,
   created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
   updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
diff --git a/deploy-templates/db/sql_holiday_previous_day_migration.sql b/deploy-templates/db/sql_holiday_previous_day_migration.sql
new file mode 100644
index 0000000..c2c1de9
--- /dev/null
+++ b/deploy-templates/db/sql_holiday_previous_day_migration.sql
@@ -0,0 +1,8 @@
+-- Add the previous-day row used by rail and civil-aviation ring-ratio calculations.
+-- day_index = 0 identifies the configured previous day; normal holiday days remain 1..N.
+INSERT IGNORE INTO holiday_calendar
+  (year, holiday_type, holiday_date, day_index, created_at, updated_at)
+VALUES
+  (2024, 'NATIONAL_DAY', '2024-09-30', 0, NOW(), NOW()),
+  (2025, 'NATIONAL_DAY', '2025-09-30', 0, NOW(), NOW()),
+  (2026, 'NATIONAL_DAY', '2026-09-30', 0, NOW(), NOW());
diff --git a/docs/database.md b/docs/database.md
index 96057a4..b7ffc90 100644
--- a/docs/database.md
+++ b/docs/database.md
@@ -491,7 +491,7 @@
 
 ## 涔濄�佷笓椤圭粺璁�-閲嶈鑺傚亣鏃ユā鍧�
 
-> 鏁版嵁鏉ユ簮涓庢ā鏉匡細`docs/涓撻」缁熻/閲嶈鑺傚亣鏃�/2026骞村崄涓�鏁版嵁.xlsx`锛涘揩鎶ユā鏉匡細`docs/涓撻」缁熻/閲嶈鑺傚亣鏃�/婀栧寳鐪佸浗搴嗗亣鏈熺患鍚堣繍杈撳娴佸揩鎶ユā鏉�.docx`銆傞娆″惎鍔ㄤ細浠庡伐浣滅翱鍒濆鍖� 2024/2025 骞村崄涓�瀹㈡祦銆佽溅娴佹暟鎹紝骞跺垵濮嬪寲 2024-2026 骞村杩愮郴鏁般��
+> 鏁版嵁鏉ユ簮涓庢ā鏉匡細`docs/涓撻」缁熻/閲嶈鑺傚亣鏃�/2026骞村崄涓�鏁版嵁.xlsx`锛涘揩鎶ユā鏉匡細`docs/涓撻」缁熻/閲嶈鑺傚亣鏃�/婀栧寳鐪佸浗搴嗗亣鏈熺患鍚堣繍杈撳娴佸揩鎶ユā鏉�.docx`銆傞娆″惎鍔ㄤ細浠庡伐浣滅翱鍒濆鍖� 2024/2025 骞村崄涓�瀹㈡祦銆佽溅娴佹暟鎹��2024-2026 骞撮搧璺�/姘戣埅鍓嶄竴鏃ユ暟鎹��2019 骞撮亾璺暟鎹紝骞跺垵濮嬪寲 2024-2026 骞村杩愮郴鏁般��
 
 ### holiday_calendar 鑺傚亣鏃ユ棩鏈熼厤缃�
 | 瀛楁 | 绫诲瀷 | 璇存槑 |
@@ -500,10 +500,10 @@
 | year | int | 骞翠唤 |
 | holiday_type | varchar(32) | 鏄ヨ妭 SPRING_FESTIVAL / 浜斾竴 LABOR_DAY / 鍗佷竴 NATIONAL_DAY |
 | holiday_date | date | 鑺傚亣鏃ュ叿浣撴棩鏈� |
-| day_index | int | 绗嚑鏃ワ紝浠� 1 寮�濮� |
+| day_index | int | 0=鍓嶄竴鏃ワ紝1..N=鍋囨湡绗� N 鏃� |
 | created_at / updated_at | datetime | 鍒涘缓/鏇存柊鏃堕棿 |
 
-鍞竴閿細`(year, holiday_type, day_index)`銆乣(year, holiday_type, holiday_date)`銆備粎 admin 鍙�氳繃绯荤粺閰嶇疆鑿滃崟缁存姢銆�
+鍞竴閿細`(year, holiday_type, day_index)`銆乣(year, holiday_type, holiday_date)`銆備粎 admin 鍙�氳繃绯荤粺閰嶇疆鑿滃崟缁存姢锛沗day_index=0` 鐢ㄤ簬閾佽矾銆佹皯鑸殑鍓嶄竴鏃ョ幆姣斿熀鏁般��
 
 ### holiday_passenger_flow 鑺傚亣鏃ョ患鍚堣繍杈撹惀涓氭�у娴�
 | 瀛楁 | 绫诲瀷 | 璇存槑 |
@@ -547,6 +547,8 @@
   - 2026 骞存櫘閫氬浗鐪侀亾濡傚~鍐欑幆姣斿熀鏈燂紝鍒欏彧褰卞搷鏅�氬浗鐪侀亾杞︽祦閲忚嚜韬幆姣旓細濉啓鏃舵寜鈥滃綋鏃� / 鐜瘮鍩烘湡 - 1鈥濓紝鏈~鍐欐椂鎸夆�滃綋鏃� / 鍓嶄竴鏃� - 1鈥濓紱鎶樼畻浜哄憳娴佸姩閲忋�佹�讳汉鍛樻祦鍔ㄩ噺绛夌户缁寜 Excel 鍘熷叕寮忚绠椼��2024銆�2025 鍘嗗彶鏁版嵁涓嶄娇鐢ㄨ瀛楁銆�
   - 鍏矾浜哄憳娴佸姩閲� = 閬撹矾钀ヤ笟鎬у杩愰噺 + 闈炶惀涓氭�т汉鍛樻祦鍔ㄩ噺銆�
 - 鎬讳汉鍛樻祦鍔ㄩ噺 = 鍏矾 + 閾佽矾 + 姘戣埅 + 姘磋矾銆�
-- 瀵煎叆鎸夆�滃勾浠� + 鑺傚亣鏃ュ垎绫烩�濊鍙� `holiday_calendar` 鐨勬棩鏈燂紝灏嗗伐浣滅翱鈥滅N鏃モ�濊瑕嗙洊鍐欏叆褰撳勾瀹㈡祦/杞︽祦锛涙棩甯稿彧璇诲彇鎵�閫夊勾浠界殑褰撳勾鍒楋紝鍘嗗彶骞翠唤浠呴娆″垵濮嬪寲銆�
+- 瀵煎叆鎸夆�滃勾浠� + 鑺傚亣鏃ュ垎绫烩�濊鍙� `holiday_calendar` 涓� `day_index>=1` 鐨勬棩鏈燂紝灏嗗伐浣滅翱鈥滅N鏃モ�濊瑕嗙洊鍐欏叆褰撳勾瀹㈡祦/杞︽祦锛涘悓鏃惰鍙栧綋鍓嶅勾浠介搧璺�佹皯鑸殑鈥滃墠涓�鏃モ�濊锛屽啓鍏� `day_index=0` 瀵瑰簲鐨勬棩鏈熴��
+- 鏃ュ父瀵煎叆鍙鍙栨墍閫夊勾浠界殑褰撳勾鍒楋紙閬撹矾琛ㄧ殑 2019/2024/2025 鍒楀潎涓嶈鍙栵級锛�2019 骞撮亾璺暟鎹拰 2024/2025/2026 骞村墠涓�鏃ラ搧璺�佹皯鑸暟鎹敱鍚姩鍒濆鍖栫洿鎺ュ啓鍏ユ暟鎹簱銆�
 - 瀵煎叆鍓嶆鏌ユ瘮鏈鏈�鏂板鍏ユ棩鏇存棭鐨勫巻鍙叉棩鏈熸槸鍚﹀彂鐢熷彉鍖栵紱濡傛湁鍙樺寲鍏堜笉鍐欏簱锛岃繑鍥炲樊寮傛竻鍗曪紝鐢ㄦ埛纭鍚庢墠鍏佽瑕嗙洊銆�
-- 瀵煎嚭浠ユ簮宸ヤ綔绨夸负搴曠锛屽洖濉簱鍐呮暟鎹笌瀹㈣繍绯绘暟锛涘揩鎶ユ寜鏃ユ湡鐢熸垚 Word 骞舵浛鎹㈡ā鏉夸腑鐨勫綋鏃ャ�佺疮璁°�佺幆姣斿拰鍚屾瘮鍐呭銆�
+- 璁板綍鈥滃墠涓�鏃モ�濈殑閾佽矾銆佹皯鑸暟鎹悗锛屽亣鏈熺 1 鏃ョ殑閾佽矾銆佹皯鑸幆姣旀寜璇ユ暟鎹绠楋紱鍏矾銆佹按璺�佹�讳汉鍛樻祦鍔ㄩ噺鍦ㄧ 1 鏃ヤ粛涓嶈绠楃幆姣斻��
+- 瀵煎嚭浠ユ簮宸ヤ綔绨夸负搴曠锛屽洖濉簱鍐呮暟鎹笌瀹㈣繍绯绘暟锛涘揩鎶ユ寜鏃ユ湡鐢熸垚 Word锛屽悓姣斿浐瀹氫娇鐢� 2025銆�2024 涓ゅ勾锛屼笉浣跨敤 2019 鏁版嵁銆�
diff --git a/docs/init.sql b/docs/init.sql
index dcc9932..70df0b6 100644
--- a/docs/init.sql
+++ b/docs/init.sql
@@ -632,7 +632,7 @@
   year INT NOT NULL COMMENT '骞翠唤',
   holiday_type VARCHAR(32) NOT NULL COMMENT '鑺傚亣鏃ュ垎绫伙細SPRING_FESTIVAL/LABOR_DAY/NATIONAL_DAY',
   holiday_date DATE NOT NULL COMMENT '鑺傚亣鏃ュ叿浣撴棩鏈�',
-  day_index INT NOT NULL COMMENT '绗嚑鏃ワ紝浠� 1 寮�濮�',
+  day_index INT NOT NULL COMMENT '0=鍓嶄竴鏃ワ紝1..N=鍋囨湡绗琋鏃�',
   created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
   updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   PRIMARY KEY (id),
diff --git a/docs/sql_holiday_previous_day_migration.sql b/docs/sql_holiday_previous_day_migration.sql
new file mode 100644
index 0000000..c2c1de9
--- /dev/null
+++ b/docs/sql_holiday_previous_day_migration.sql
@@ -0,0 +1,8 @@
+-- Add the previous-day row used by rail and civil-aviation ring-ratio calculations.
+-- day_index = 0 identifies the configured previous day; normal holiday days remain 1..N.
+INSERT IGNORE INTO holiday_calendar
+  (year, holiday_type, holiday_date, day_index, created_at, updated_at)
+VALUES
+  (2024, 'NATIONAL_DAY', '2024-09-30', 0, NOW(), NOW()),
+  (2025, 'NATIONAL_DAY', '2025-09-30', 0, NOW(), NOW()),
+  (2026, 'NATIONAL_DAY', '2026-09-30', 0, NOW(), NOW());
diff --git "a/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/2026\345\271\264\345\215\201\344\270\200\346\225\260\346\215\256.xlsx" "b/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/2026\345\271\264\345\215\201\344\270\200\346\225\260\346\215\256.xlsx"
index cc214e3..4b57043 100644
--- "a/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/2026\345\271\264\345\215\201\344\270\200\346\225\260\346\215\256.xlsx"
+++ "b/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/2026\345\271\264\345\215\201\344\270\200\346\225\260\346\215\256.xlsx"
Binary files differ
diff --git "a/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/\345\244\207\344\273\275/2026\345\271\264\345\215\201\344\270\200\346\225\260\346\215\256.xlsx" "b/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/\345\244\207\344\273\275/2026\345\271\264\345\215\201\344\270\200\346\225\260\346\215\256.xlsx"
index d75764f..cc214e3 100644
--- "a/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/\345\244\207\344\273\275/2026\345\271\264\345\215\201\344\270\200\346\225\260\346\215\256.xlsx"
+++ "b/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/\345\244\207\344\273\275/2026\345\271\264\345\215\201\344\270\200\346\225\260\346\215\256.xlsx"
Binary files differ
diff --git "a/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/\346\271\226\345\214\227\347\234\201\345\233\275\345\272\206\345\201\207\346\234\237\347\273\274\345\220\210\350\277\220\350\276\223\345\256\242\346\265\201\345\277\253\346\212\245\346\250\241\346\235\277.docx" "b/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/\346\271\226\345\214\227\347\234\201\345\233\275\345\272\206\345\201\207\346\234\237\347\273\274\345\220\210\350\277\220\350\276\223\345\256\242\346\265\201\345\277\253\346\212\245\346\250\241\346\235\277.docx"
index 26794b6..e988487 100644
--- "a/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/\346\271\226\345\214\227\347\234\201\345\233\275\345\272\206\345\201\207\346\234\237\347\273\274\345\220\210\350\277\220\350\276\223\345\256\242\346\265\201\345\277\253\346\212\245\346\250\241\346\235\277.docx"
+++ "b/docs/\344\270\223\351\241\271\347\273\237\350\256\241/\351\207\215\350\246\201\350\212\202\345\201\207\346\227\245/\346\271\226\345\214\227\347\234\201\345\233\275\345\272\206\345\201\207\346\234\237\347\273\274\345\220\210\350\277\220\350\276\223\345\256\242\346\265\201\345\277\253\346\212\245\346\250\241\346\235\277.docx"
Binary files differ
diff --git "a/docs/\346\211\223\345\214\205\351\203\250\347\275\262\350\257\264\346\230\216.md" "b/docs/\346\211\223\345\214\205\351\203\250\347\275\262\350\257\264\346\230\216.md"
index b095f22..9b69a64 100644
--- "a/docs/\346\211\223\345\214\205\351\203\250\347\275\262\350\257\264\346\230\216.md"
+++ "b/docs/\346\211\223\345\214\205\351\203\250\347\275\262\350\257\264\346\230\216.md"
@@ -73,7 +73,8 @@
 鈹�  鈹溾攢 sql_wyc.sql                               缃戠害杞﹀叏鐪佹�婚噺/璁㈠崟鍒嗗競宸炶〃锛堝繀椤绘墽琛岋級
 鈹�  鈹溾攢 sql_holiday.sql                           涓撻」缁熻-閲嶈鑺傚亣鏃ヨ〃锛堟棫搴撹ˉ寤烘椂鎵ц锛�
 鈹�  鈹溾攢 sql_holiday_decimal_migration.sql         鑺傚亣鏃ユ暟鍊煎垪绮惧害杩佺Щ锛堟棫搴撳崌绾э級
-鈹�  鈹斺攢 sql_holiday_comparison_base_migration.sql 鑺傚亣鏃ョ幆姣斿熀鏈熷瓧娈佃縼绉伙紙鏃у簱鍗囩骇锛�
+鈹�  鈹溾攢 sql_holiday_comparison_base_migration.sql 鑺傚亣鏃ョ幆姣斿熀鏈熷瓧娈佃縼绉伙紙鏃у簱鍗囩骇锛�
+鈹�  鈹斺攢 sql_holiday_previous_day_migration.sql    鑺傚亣鏃ュ墠涓�鏃ラ厤缃縼绉伙紙鏃у簱鍗囩骇锛�
 鈹斺攢 README-閮ㄧ讲璇存槑.txt
 ```
 
@@ -94,7 +95,7 @@
 ```
 
 > 鈿狅笍 **`init.sql` 鏄牬鍧忔�х殑**锛氶噷闈㈢殑鍩虹琛ㄩ兘甯� `DROP TABLE IF EXISTS`銆�**宸叉湁鏁版嵁鐨勫簱涓婂崈涓囦笉瑕佸啀璺� init.sql**锛屽惁鍒欒〃鏁版嵁浼氳娓呯┖閲嶅缓銆�
-> 鏃╂湡鐗堟湰搴撹嫢娌℃湁鑺傚亣鏃� 4 寮犺〃锛屾墽琛� `sql_holiday.sql`锛涜嫢宸叉湁鑺傚亣鏃ヨ〃浣嗙己绮惧害鎴栫幆姣斿熀鏈熷瓧娈碉紝鎸夐渶鎵ц涓や釜杩佺Щ鑴氭湰銆�
+> 鏃╂湡鐗堟湰搴撹嫢娌℃湁鑺傚亣鏃� 4 寮犺〃锛屾墽琛� `sql_holiday.sql`锛涜嫢宸叉湁鑺傚亣鏃ヨ〃浣嗙己绮惧害銆佺幆姣斿熀鏈熷瓧娈垫垨鍓嶄竴鏃ラ厤缃紝鎸夐渶鎵ц `sql_holiday_decimal_migration.sql`銆乣sql_holiday_comparison_base_migration.sql`銆乣sql_holiday_previous_day_migration.sql`銆�
 > 4 涓剼鏈叡瑕嗙洊 33 寮犺〃锛坕nit.sql 28 寮狅紝鍏朵腑鍚妭鍋囨棩 4 寮� + 鍩庡競瀹㈣繍 3 寮� + 缃戠害杞� 2 寮狅級銆�
 
 #### 璺嚎 B锛氭妸鐜扮綉/寮�鍙戞満鐨勬暟鎹暣濂楁惉杩囧幓锛堟帹鑽愶紝涓嶇敤璺戣剼鏈級
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 1c686ee..e6ef8ac 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
@@ -1,6 +1,7 @@
 package com.trafficaudit.holiday.service;
 
 import com.trafficaudit.holiday.HolidayNumberUtils;
+import com.trafficaudit.holiday.entity.HolidayCalendar;
 import com.trafficaudit.holiday.service.HolidayStatService.DailyMetrics;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
@@ -10,6 +11,7 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
+import javax.annotation.Resource;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
@@ -43,6 +45,8 @@
     private String bulletinTemplatePath;
 
     private final HolidayStatService statService;
+    @Resource
+    private HolidayConfigService configService;
     private static final ThreadLocal<Document> CURRENT_DOCUMENT = new ThreadLocal<>();
 
     public HolidayBulletinService(HolidayStatService statService) {
@@ -56,9 +60,16 @@
         }
         DailyMetrics previousDay = current.getDayIndex() > 1
                 ? statService.dailyMetrics(current.getYear(), current.getHolidayType(), current.getDayIndex() - 1) : null;
+        HolidayCalendar previousDayConfig = configService.findPreviousDay(current.getYear(), current.getHolidayType());
+        LocalDate previousDayDate = previousDayConfig == null || previousDayConfig.getHolidayDate() == null
+                ? current.getDate().minusDays(1) : previousDayConfig.getHolidayDate();
+        DailyMetrics previousCalendarDay = previousDay != null
+                ? previousDay : statService.dailyMetricsByDate(previousDayDate);
         DailyMetrics previousYear = statService.dailyMetrics(current.getYear() - 1, current.getHolidayType(), current.getDayIndex());
+        DailyMetrics twoYearsAgo = statService.dailyMetrics(current.getYear() - 2, current.getHolidayType(), current.getDayIndex());
         DailyMetrics currentCumulative = statService.cumulativeMetrics(current.getYear(), current.getHolidayType(), current.getDayIndex());
         DailyMetrics previousYearCumulative = statService.cumulativeMetrics(current.getYear() - 1, current.getHolidayType(), current.getDayIndex());
+        DailyMetrics twoYearsAgoCumulative = statService.cumulativeMetrics(current.getYear() - 2, current.getHolidayType(), current.getDayIndex());
 
         if (current.getTotalPersonFlow() == null) {
             throw new IllegalArgumentException("鎵�閫夋棩鏈熺殑鍏ㄧぞ浼氳法鍖哄煙浜哄憳娴佸姩閲忔病鏈夎冻澶熸暟鎹紝鏃犳硶鐢熸垚蹇姤");
@@ -69,14 +80,17 @@
                 ? 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銆�",
+        String paragraph1 = String.format("%d鏈�%d鏃ワ紙鍋囨湡绗�%d澶╋級锛屽叏鐪佸叏绀句細璺ㄥ尯鍩熶汉鍛樻祦鍔ㄩ噺%s涓囦汉娆�%s锛屾瘮2025骞村悓鏈�%s锛屾瘮2024骞村悓鏈�%s銆�",
                 date.getMonthValue(), date.getDayOfMonth(), current.getDayIndex(), currentTotal,
                 ringRatioClause,
-                ratioPhrase(current.getTotalPersonFlow(), previousYear == null ? null : previousYear.getTotalPersonFlow()));
-        String paragraph2 = String.format("鍋囨湡浠ユ潵锛屽叏鐪佸叏绀句細璺ㄥ尯鍩熶汉鍛樻祦鍔ㄩ噺绱%s浜夸汉娆★紝姣�2025骞村悓鏈�%s銆�",
+                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()));
+                        previousYearCumulative == null ? null : previousYearCumulative.getTotalPersonFlow()),
+                ratioPhrase(currentCumulative.getTotalPersonFlow(),
+                        twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getTotalPersonFlow()));
 
         File template = resolveTemplateFile();
         if (!template.exists() || !template.isFile()) {
@@ -94,7 +108,8 @@
             try {
                 replaceParagraph(document, text -> text.startsWith("10鏈�") && text.contains("鍋囨湡绗�"), paragraph1);
                 replaceParagraph(document, text -> text.startsWith("鍋囨湡浠ユ潵"), paragraph2);
-                fillTable(document, current, previousDay, previousYear, currentCumulative, previousYearCumulative);
+                fillTable(document, current, previousDay, previousCalendarDay, previousYear, twoYearsAgo,
+                        currentCumulative, previousYearCumulative, twoYearsAgoCumulative);
                 byte[] replacedXml = serializeDocument(document);
                 return replaceZipEntry(templateBytes, "word/document.xml", replacedXml);
             } finally {
@@ -106,8 +121,11 @@
     }
 
     private void fillTable(Document document, DailyMetrics current, DailyMetrics previousDay,
-                           DailyMetrics previousYear, DailyMetrics currentCumulative,
-                           DailyMetrics previousYearCumulative) {
+                           DailyMetrics previousCalendarDay, DailyMetrics previousYear, DailyMetrics twoYearsAgo,
+                           DailyMetrics currentCumulative, DailyMetrics previousYearCumulative,
+                           DailyMetrics twoYearsAgoCumulative) {
+        DailyMetrics firstDayRailBase = previousDay == null ? previousCalendarDay : previousDay;
+        DailyMetrics firstDayCivilAviationBase = previousDay == null ? previousCalendarDay : previousDay;
         Element table = firstElement(document, "tbl");
         if (table == null) {
             throw new IllegalArgumentException("蹇姤妯℃澘涓壘涓嶅埌鏁版嵁琛�");
@@ -116,54 +134,74 @@
                 number(current.getNonBusinessPersonFlow()),
                 ratio(current.getNonBusinessPersonFlow(), previousDay == null ? null : previousDay.getNonBusinessPersonFlow()),
                 ratio(current.getNonBusinessPersonFlow(), previousYear == null ? null : previousYear.getNonBusinessPersonFlow()),
-                "鈥�",
+                ratio(current.getNonBusinessPersonFlow(), twoYearsAgo == null ? null : twoYearsAgo.getNonBusinessPersonFlow()),
                 number(currentCumulative.getNonBusinessPersonFlow()),
                 ratio(currentCumulative.getNonBusinessPersonFlow(),
                         previousYearCumulative == null ? null : previousYearCumulative.getNonBusinessPersonFlow()),
-                "鈥�"
+                ratio(currentCumulative.getNonBusinessPersonFlow(),
+                        twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getNonBusinessPersonFlow())
         });
         writeTableRow(table, 3, new String[]{
                 number(current.getRoad()),
                 ratio(current.getRoad(), previousDay == null ? null : previousDay.getRoad()),
                 ratio(current.getRoad(), previousYear == null ? null : previousYear.getRoad()),
-                "鈥�",
+                ratio(current.getRoad(), twoYearsAgo == null ? null : twoYearsAgo.getRoad()),
                 number(currentCumulative.getRoad()),
                 ratio(currentCumulative.getRoad(), previousYearCumulative == null ? null : previousYearCumulative.getRoad()),
-                "鈥�"
+                ratio(currentCumulative.getRoad(), twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getRoad())
         });
         writeTableRow(table, 4, new String[]{
                 number(current.getRoadPersonFlow()),
                 ratio(current.getRoadPersonFlow(), previousDay == null ? null : previousDay.getRoadPersonFlow()),
                 ratio(current.getRoadPersonFlow(), previousYear == null ? null : previousYear.getRoadPersonFlow()),
-                "鈥�",
+                ratio(current.getRoadPersonFlow(), twoYearsAgo == null ? null : twoYearsAgo.getRoadPersonFlow()),
                 number(currentCumulative.getRoadPersonFlow()),
-                ratio(currentCumulative.getRoadPersonFlow(), previousYearCumulative == null ? null : previousYearCumulative.getRoadPersonFlow()),
-                "鈥�"
+                ratio(currentCumulative.getRoadPersonFlow(),
+                        previousYearCumulative == null ? null : previousYearCumulative.getRoadPersonFlow()),
+                ratio(currentCumulative.getRoadPersonFlow(),
+                        twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getRoadPersonFlow())
         });
-        writeTableRow(table, 5, transportRow(current.getRail(), previousDay == null ? null : previousDay.getRail(),
-                previousYear == null ? null : previousYear.getRail(), currentCumulative.getRail(),
-                previousYearCumulative == null ? null : previousYearCumulative.getRail()));
-        writeTableRow(table, 6, transportRow(current.getCivilAviation(), previousDay == null ? null : previousDay.getCivilAviation(),
-                previousYear == null ? null : previousYear.getCivilAviation(), currentCumulative.getCivilAviation(),
-                previousYearCumulative == null ? null : previousYearCumulative.getCivilAviation()));
-        writeTableRow(table, 7, transportRow(current.getWater(), previousDay == null ? null : previousDay.getWater(),
-                previousYear == null ? null : previousYear.getWater(), currentCumulative.getWater(),
-                previousYearCumulative == null ? null : previousYearCumulative.getWater()));
-        writeTableRow(table, 8, transportRow(current.getTotalPersonFlow(), previousDay == null ? null : previousDay.getTotalPersonFlow(),
-                previousYear == null ? null : previousYear.getTotalPersonFlow(), currentCumulative.getTotalPersonFlow(),
-                previousYearCumulative == null ? null : previousYearCumulative.getTotalPersonFlow()));
+        writeTableRow(table, 5, transportRow(current.getRail(),
+                firstDayRailBase == null ? null : firstDayRailBase.getRail(),
+                previousYear == null ? null : previousYear.getRail(),
+                twoYearsAgo == null ? null : twoYearsAgo.getRail(),
+                currentCumulative.getRail(),
+                previousYearCumulative == null ? null : previousYearCumulative.getRail(),
+                twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getRail()));
+        writeTableRow(table, 6, transportRow(current.getCivilAviation(),
+                firstDayCivilAviationBase == null ? null : firstDayCivilAviationBase.getCivilAviation(),
+                previousYear == null ? null : previousYear.getCivilAviation(),
+                twoYearsAgo == null ? null : twoYearsAgo.getCivilAviation(),
+                currentCumulative.getCivilAviation(),
+                previousYearCumulative == null ? null : previousYearCumulative.getCivilAviation(),
+                twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getCivilAviation()));
+        writeTableRow(table, 7, transportRow(current.getWater(),
+                previousDay == null ? null : previousDay.getWater(),
+                previousYear == null ? null : previousYear.getWater(),
+                twoYearsAgo == null ? null : twoYearsAgo.getWater(),
+                currentCumulative.getWater(),
+                previousYearCumulative == null ? null : previousYearCumulative.getWater(),
+                twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getWater()));
+        writeTableRow(table, 8, transportRow(current.getTotalPersonFlow(),
+                previousDay == null ? null : previousDay.getTotalPersonFlow(),
+                previousYear == null ? null : previousYear.getTotalPersonFlow(),
+                twoYearsAgo == null ? null : twoYearsAgo.getTotalPersonFlow(),
+                currentCumulative.getTotalPersonFlow(),
+                previousYearCumulative == null ? null : previousYearCumulative.getTotalPersonFlow(),
+                twoYearsAgoCumulative == null ? null : twoYearsAgoCumulative.getTotalPersonFlow()));
     }
 
     private String[] transportRow(BigDecimal current, BigDecimal previousDay, BigDecimal previousYear,
-                                  BigDecimal currentCumulative, BigDecimal previousYearCumulative) {
+                                  BigDecimal twoYearsAgo, BigDecimal currentCumulative,
+                                  BigDecimal previousYearCumulative, BigDecimal twoYearsAgoCumulative) {
         return new String[]{
                 number(current),
                 ratio(current, previousDay),
                 ratio(current, previousYear),
-                "鈥�",
+                ratio(current, twoYearsAgo),
                 number(currentCumulative),
                 ratio(currentCumulative, previousYearCumulative),
-                "鈥�"
+                ratio(currentCumulative, twoYearsAgoCumulative)
         };
     }
 
@@ -175,7 +213,7 @@
         int logicalColumn = 0;
         for (Element cell : cells) {
             int span = gridSpan(cell);
-            if (logicalColumn >= 2 && logicalColumn < 9) {
+            if (logicalColumn >= 2) {
                 int valueIndex = logicalColumn - 2;
                 if (valueIndex < values.length) {
                     setCellText(cell, values[valueIndex]);
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayConfigService.java b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayConfigService.java
index 6b281c7..455faca 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayConfigService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayConfigService.java
@@ -39,7 +39,16 @@
         return holidayCalendarMapper.selectList(new LambdaQueryWrapper<HolidayCalendar>()
                 .eq(HolidayCalendar::getYear, year)
                 .eq(HolidayCalendar::getHolidayType, holidayType)
+                .ge(HolidayCalendar::getDayIndex, 1)
                 .orderByAsc(HolidayCalendar::getDayIndex));
+    }
+
+    public HolidayCalendar findPreviousDay(int year, String holidayType) {
+        return holidayCalendarMapper.selectOne(new LambdaQueryWrapper<HolidayCalendar>()
+                .eq(HolidayCalendar::getYear, year)
+                .eq(HolidayCalendar::getHolidayType, holidayType)
+                .eq(HolidayCalendar::getDayIndex, 0)
+                .last("limit 1"));
     }
 
     public HolidayCalendar findHolidayByDate(LocalDate date) {
@@ -65,8 +74,8 @@
         if (holidayDate == null || holidayDate.getYear() != year) {
             throw new IllegalArgumentException("鏃ユ湡蹇呴』灞炰簬鎵�閫夊勾浠�");
         }
-        if (dayIndex == null || dayIndex < 1) {
-            throw new IllegalArgumentException("绗嚑鏃ュ繀椤讳粠 1 寮�濮�");
+        if (dayIndex == null || dayIndex < 0) {
+            throw new IllegalArgumentException("鏃ユ湡搴忓彿涓嶈兘灏忎簬 0");
         }
         LambdaQueryWrapper<HolidayCalendar> duplicate = new LambdaQueryWrapper<HolidayCalendar>()
                 .eq(HolidayCalendar::getYear, year)
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java
index 8ccd624..3015c71 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayStatService.java
@@ -138,16 +138,24 @@
             }
         }
         if (target == null) return null;
+        return dailyMetrics(year, holidayType, dayIndex, target.getHolidayDate());
+    }
 
+    public DailyMetrics dailyMetricsByDate(LocalDate date) {
+        if (date == null) return null;
+        return dailyMetrics(date.getYear(), null, 0, date);
+    }
+
+    private DailyMetrics dailyMetrics(int year, String holidayType, int dayIndex, LocalDate date) {
         Map<LocalDate, Map<String, BigDecimal>> passengerByDate = loadPassengerByDate(year);
         Map<LocalDate, Map<String, BigDecimal>> vehicleByDate = loadVehicleByDate(year);
         Map<LocalDate, BigDecimal> comparisonBaseByDate = loadComparisonBaseByDate(year);
-        Map<String, BigDecimal> passenger = passengerByDate.getOrDefault(target.getHolidayDate(), Collections.emptyMap());
-        Map<String, BigDecimal> vehicle = vehicleByDate.getOrDefault(target.getHolidayDate(), Collections.emptyMap());
+        Map<String, BigDecimal> passenger = passengerByDate.getOrDefault(date, Collections.emptyMap());
+        Map<String, BigDecimal> vehicle = vehicleByDate.getOrDefault(date, Collections.emptyMap());
         BigDecimal coefficient = configService.coefficientOf(year, HolidayConstants.CATEGORY_HOLIDAY);
         BigDecimal expressway = vehicle.get(HolidayConstants.ROAD_EXPRESSWAY);
         BigDecimal nationalProvincial = vehicle.get(HolidayConstants.ROAD_NATIONAL_PROVINCIAL);
-        BigDecimal comparisonBase = comparisonBaseByDate.get(target.getHolidayDate());
+        BigDecimal comparisonBase = comparisonBaseByDate.get(date);
         BigDecimal nonBusiness = null;
         if (coefficient != null && (expressway != null || nationalProvincial != null)) {
             nonBusiness = HolidayNumberUtils.multiply(
@@ -158,7 +166,7 @@
         metrics.setYear(year);
         metrics.setHolidayType(holidayType);
         metrics.setDayIndex(dayIndex);
-        metrics.setDate(target.getHolidayDate());
+        metrics.setDate(date);
         metrics.setRail(passenger.get(HolidayConstants.MODE_RAIL));
         metrics.setCivilAviation(passenger.get(HolidayConstants.MODE_CIVIL_AVIATION));
         metrics.setRoad(passenger.get(HolidayConstants.MODE_ROAD));
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayWorkbookService.java b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayWorkbookService.java
index 3fc5d2e..5775f22 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayWorkbookService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayWorkbookService.java
@@ -46,6 +46,7 @@
 
     private static final Map<String, String> PASSENGER_SHEET_MODE = new LinkedHashMap<>();
     private static final int FIRST_DATA_ROW_INDEX = 2;
+    private static final int DAY_ROW_SCAN_LIMIT = 30;
     private static final int[] REFERENCE_YEARS = {2024, 2025, 2026};
 
     static {
@@ -115,7 +116,7 @@
         ImportSummary summary = new ImportSummary();
         try (InputStream in = file.getInputStream(); Workbook workbook = WorkbookFactory.create(in)) {
             FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
-            importPassengerSheets(workbook, evaluator, year, dateByDay, summary);
+            importPassengerSheets(workbook, evaluator, year, holidayType, dateByDay, summary);
             importVehicleSheets(workbook, evaluator, year, dateByDay, summary);
         } catch (Exception e) {
             throw new IllegalArgumentException("宸ヤ綔绨胯В鏋愬け璐�: " + e.getMessage(), e);
@@ -161,7 +162,7 @@
             if (sheet == null) continue;
             Integer yearColumn = findYearColumn(sheet, evaluator, year, 2, 7);
             if (yearColumn == null) continue;
-            Row row = sheet.getRow(FIRST_DATA_ROW_INDEX + dayIndex - 1);
+            Row row = findDayRow(sheet, evaluator, dayIndex);
             if (row == null) continue;
             BigDecimal value = numberValue(row.getCell(yearColumn), evaluator);
             if (value != null) return true;
@@ -174,7 +175,7 @@
         if (expressway != null) {
             Integer yearColumn = findYearColumn(expressway, evaluator, year, 2, 7);
             if (yearColumn != null) {
-                Row row = expressway.getRow(FIRST_DATA_ROW_INDEX + dayIndex - 1);
+                Row row = findDayRow(expressway, evaluator, dayIndex);
                 if (row != null && numberValue(row.getCell(yearColumn), evaluator) != null) return true;
             }
         }
@@ -182,7 +183,7 @@
         if (nationalProvincial != null) {
             Integer yearColumn = findYearColumn(nationalProvincial, evaluator, year, 3, 8);
             if (yearColumn != null) {
-                Row row = nationalProvincial.getRow(FIRST_DATA_ROW_INDEX + dayIndex - 1);
+                Row row = findDayRow(nationalProvincial, evaluator, dayIndex);
                 if (row != null && numberValue(row.getCell(yearColumn), evaluator) != null) return true;
             }
         }
@@ -200,7 +201,7 @@
             if (yearColumn == null) continue;
             for (Map.Entry<Integer, LocalDate> day : dateByDay.entrySet()) {
                 if (day.getKey() >= latestDay) continue;
-                Row row = sheet.getRow(FIRST_DATA_ROW_INDEX + day.getKey() - 1);
+                Row row = findDayRow(sheet, evaluator, day.getKey());
                 if (row == null) continue;
                 BigDecimal incoming = numberValue(row.getCell(yearColumn), evaluator);
                 if (incoming == null) continue;
@@ -236,7 +237,7 @@
         if (yearColumn == null) return;
         for (Map.Entry<Integer, LocalDate> day : dateByDay.entrySet()) {
             if (day.getKey() >= latestDay) continue;
-            Row row = sheet.getRow(FIRST_DATA_ROW_INDEX + day.getKey() - 1);
+            Row row = findDayRow(sheet, evaluator, day.getKey());
             if (row == null) continue;
             BigDecimal incoming = numberValue(row.getCell(yearColumn), evaluator);
             if (incoming == null) continue;
@@ -261,7 +262,7 @@
             if (day.getKey() >= latestDay) continue;
             Map<String, BigDecimal> existingDay = existingVehicle.get(day.getValue());
             if (existingDay == null || existingDay.get(HolidayConstants.ROAD_NATIONAL_PROVINCIAL) == null) continue;
-            Row row = sheet.getRow(FIRST_DATA_ROW_INDEX + day.getKey() - 1);
+            Row row = findDayRow(sheet, evaluator, day.getKey());
             if (row == null) continue;
             BigDecimal incoming;
             try {
@@ -278,8 +279,8 @@
         }
     }
 
-        Map<LocalDate, Map<String, BigDecimal>> result = new LinkedHashMap<>();
     private Map<LocalDate, Map<String, BigDecimal>> loadPassengerByDate(int year) {
+        Map<LocalDate, Map<String, BigDecimal>> result = new LinkedHashMap<>();
         List<HolidayPassengerFlow> rows = passengerFlowMapper.selectList(
                 new LambdaQueryWrapper<HolidayPassengerFlow>().eq(HolidayPassengerFlow::getYear, year));
         for (HolidayPassengerFlow row : rows) {
@@ -337,6 +338,7 @@
         try (InputStream in = new FileInputStream(reference); Workbook workbook = WorkbookFactory.create(in)) {
             FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
             seedNationalDayCalendar();
+            ensurePreviousDayCalendarIfMissing();
             for (int year : REFERENCE_YEARS) {
                 if (passengerFlowMapper.selectCount(new LambdaQueryWrapper<HolidayPassengerFlow>()
                         .eq(HolidayPassengerFlow::getYear, year)) == 0) {
@@ -351,6 +353,8 @@
                     seedCoefficientYear(workbook, evaluator, year);
                 }
             }
+            seedPreviousDayPassengerIfMissing(workbook, evaluator);
+            seedRoad2019IfMissing(workbook, evaluator);
         } catch (Exception e) {
             log.error("Failed to seed holiday reference data", e);
         }
@@ -381,7 +385,8 @@
     }
 
     private void importPassengerSheets(Workbook workbook, FormulaEvaluator evaluator, int year,
-                                       Map<Integer, LocalDate> dateByDay, ImportSummary summary) {
+                                       String holidayType, Map<Integer, LocalDate> dateByDay,
+                                       ImportSummary summary) {
         for (Map.Entry<String, String> entry : PASSENGER_SHEET_MODE.entrySet()) {
             Sheet sheet = workbook.getSheet(entry.getKey());
             if (sheet == null) {
@@ -394,7 +399,7 @@
                 continue;
             }
             for (Map.Entry<Integer, LocalDate> day : dateByDay.entrySet()) {
-                Row row = sheet.getRow(FIRST_DATA_ROW_INDEX + day.getKey() - 1);
+                Row row = findDayRow(sheet, evaluator, day.getKey());
                 if (row == null) {
                     summary.addError(entry.getKey() + " 绗�" + day.getKey() + "鏃ワ細宸ヤ綔琛ㄧ己灏戣琛�");
                     continue;
@@ -418,6 +423,39 @@
                 upsertPassenger(year, day.getValue(), entry.getValue(), value);
                 summary.incrementPassenger();
             }
+        }
+        importPreviousDayPassengerRows(workbook, evaluator, year, holidayType, dateByDay, summary);
+    }
+
+    private void importPreviousDayPassengerRows(Workbook workbook, FormulaEvaluator evaluator, int year,
+                                                 String holidayType, Map<Integer, LocalDate> dateByDay,
+                                                 ImportSummary summary) {
+        LocalDate previousDate = previousDayDate(year, holidayType, dateByDay);
+        if (previousDate == null) return;
+        for (Map.Entry<String, String> entry : PASSENGER_SHEET_MODE.entrySet()) {
+            if (!HolidayConstants.MODE_RAIL.equals(entry.getValue())
+                    && !HolidayConstants.MODE_CIVIL_AVIATION.equals(entry.getValue())) {
+                continue;
+            }
+            Sheet sheet = workbook.getSheet(entry.getKey());
+            if (sheet == null) continue;
+            Integer yearColumn = findYearColumn(sheet, evaluator, year, 2, 7);
+            if (yearColumn == null) continue;
+            Row row = findPreviousDayRow(sheet, evaluator);
+            if (row == null) continue;
+            BigDecimal value;
+            try {
+                value = numberValue(row.getCell(yearColumn), evaluator);
+            } catch (Exception e) {
+                summary.addError(entry.getKey() + " 鍓嶄竴鏃ヨ锛�" + e.getMessage());
+                continue;
+            }
+            if (value == null) {
+                summary.incrementSkipped();
+                continue;
+            }
+            upsertPassenger(year, previousDate, entry.getValue(), value);
+            summary.incrementPassenger();
         }
     }
 
@@ -445,7 +483,7 @@
             return;
         }
         for (Map.Entry<Integer, LocalDate> day : dateByDay.entrySet()) {
-            Row row = sheet.getRow(FIRST_DATA_ROW_INDEX + day.getKey() - 1);
+            Row row = findDayRow(sheet, evaluator, day.getKey());
             if (row == null) {
                 summary.addError(sheetName + " 绗�" + day.getKey() + "鏃ワ細宸ヤ綔琛ㄧ己灏戣琛�");
                 continue;
@@ -491,7 +529,17 @@
                 Map<LocalDate, BigDecimal> values = loadPassengerValues(year, entry.getValue());
                 for (Map.Entry<Integer, LocalDate> day : dayDates.entrySet()) {
                     if (!values.containsKey(day.getValue())) continue;
-                    setNumeric(sheet, FIRST_DATA_ROW_INDEX + day.getKey() - 1, yearColumn, values.get(day.getValue()));
+                    Row row = findDayRow(sheet, evaluator, day.getKey());
+                    if (row == null) continue;
+                    setNumeric(sheet, row.getRowNum(), yearColumn, values.get(day.getValue()));
+                }
+                LocalDate previousDate = previousDayDate(year, holidayType, dayDates);
+                Row previousRow = findPreviousDayRow(sheet, evaluator);
+                if (previousDate != null && previousRow != null) {
+                    BigDecimal previousValue = values.get(previousDate);
+                    if (previousValue != null) {
+                        setNumeric(sheet, previousRow.getRowNum(), yearColumn, previousValue);
+                    }
                 }
             }
         }
@@ -515,17 +563,23 @@
             Map<LocalDate, BigDecimal> values = loadVehicleValues(year, roadCategory);
             for (Map.Entry<Integer, LocalDate> day : dayDates.entrySet()) {
                 if (!values.containsKey(day.getValue())) continue;
-                setNumeric(sheet, FIRST_DATA_ROW_INDEX + day.getKey() - 1, yearColumn, values.get(day.getValue()));
+                Row row = findDayRow(sheet, evaluator, day.getKey());
+                if (row == null) continue;
+                setNumeric(sheet, row.getRowNum(), yearColumn, values.get(day.getValue()));
             }
             if (comparisonBaseColumn != null && HolidayConstants.supportsComparisonBase(year)) {
                 Map<LocalDate, BigDecimal> bases = loadComparisonBaseValues(year);
                 for (Map.Entry<Integer, LocalDate> day : dayDates.entrySet()) {
                     if (!bases.containsKey(day.getValue())) continue;
-                    setNumeric(sheet, FIRST_DATA_ROW_INDEX + day.getKey() - 1, comparisonBaseColumn, bases.get(day.getValue()));
+                    Row row = findDayRow(sheet, evaluator, day.getKey());
+                    if (row == null) continue;
+                    setNumeric(sheet, row.getRowNum(), comparisonBaseColumn, bases.get(day.getValue()));
                 }
                 for (Map.Entry<Integer, LocalDate> day : dayDates.entrySet()) {
                     if (!bases.containsKey(day.getValue())) continue;
-                    int rowIndex = FIRST_DATA_ROW_INDEX + day.getKey() - 1;
+                    Row row = findDayRow(sheet, evaluator, day.getKey());
+                    if (row == null) continue;
+                    int rowIndex = row.getRowNum();
                     int excelRow = rowIndex + 1;
                     setFormula(sheet, rowIndex, 4, "=(D" + excelRow + "-C" + excelRow + ")/C" + excelRow);
                 }
@@ -579,6 +633,84 @@
                 calendar.setUpdatedAt(LocalDateTime.now());
                 configService.saveHoliday(toMap(calendar));
             }
+            HolidayCalendar previousDay = new HolidayCalendar();
+            previousDay.setYear(year);
+            previousDay.setHolidayType(HolidayConstants.TYPE_NATIONAL_DAY);
+            previousDay.setHolidayDate(LocalDate.of(year, 10, 1).minusDays(1));
+            previousDay.setDayIndex(0);
+            previousDay.setCreatedAt(LocalDateTime.now());
+            previousDay.setUpdatedAt(LocalDateTime.now());
+            configService.saveHoliday(toMap(previousDay));
+        }
+    }
+
+    private void ensurePreviousDayCalendarIfMissing() {
+        for (int year : REFERENCE_YEARS) {
+            if (configService.findPreviousDay(year, HolidayConstants.TYPE_NATIONAL_DAY) != null) {
+                continue;
+            }
+            LocalDate firstHolidayDate = firstDate(dayDates(year, HolidayConstants.TYPE_NATIONAL_DAY));
+            if (firstHolidayDate == null) {
+                continue;
+            }
+            HolidayCalendar previousDay = new HolidayCalendar();
+            previousDay.setYear(year);
+            previousDay.setHolidayType(HolidayConstants.TYPE_NATIONAL_DAY);
+            previousDay.setHolidayDate(firstHolidayDate.minusDays(1));
+            previousDay.setDayIndex(0);
+            previousDay.setCreatedAt(LocalDateTime.now());
+            previousDay.setUpdatedAt(LocalDateTime.now());
+            configService.saveHoliday(toMap(previousDay));
+        }
+    }
+
+    private void seedPreviousDayPassengerIfMissing(Workbook workbook, FormulaEvaluator evaluator) {
+        for (int year : REFERENCE_YEARS) {
+            Map<Integer, LocalDate> dayDates = dayDates(year, HolidayConstants.TYPE_NATIONAL_DAY);
+            LocalDate previousDate = previousDayDate(year, HolidayConstants.TYPE_NATIONAL_DAY, dayDates);
+            if (previousDate == null) continue;
+            for (Map.Entry<String, String> entry : PASSENGER_SHEET_MODE.entrySet()) {
+                if (!HolidayConstants.MODE_RAIL.equals(entry.getValue())
+                        && !HolidayConstants.MODE_CIVIL_AVIATION.equals(entry.getValue())) {
+                    continue;
+                }
+                if (passengerFlowMapper.selectCount(new LambdaQueryWrapper<HolidayPassengerFlow>()
+                        .eq(HolidayPassengerFlow::getYear, year)
+                        .eq(HolidayPassengerFlow::getFlowDate, previousDate)
+                        .eq(HolidayPassengerFlow::getTransportMode, entry.getValue())) > 0) {
+                    continue;
+                }
+                Sheet sheet = workbook.getSheet(entry.getKey());
+                if (sheet == null) continue;
+                Integer yearColumn = findYearColumn(sheet, evaluator, year, 2, 7);
+                if (yearColumn == null) continue;
+                Row row = findPreviousDayRow(sheet, evaluator);
+                if (row == null) continue;
+                BigDecimal value = numberValue(row.getCell(yearColumn), evaluator);
+                if (value != null) upsertPassenger(year, previousDate, entry.getValue(), value);
+            }
+        }
+    }
+
+    private void seedRoad2019IfMissing(Workbook workbook, FormulaEvaluator evaluator) {
+        if (passengerFlowMapper.selectCount(new LambdaQueryWrapper<HolidayPassengerFlow>()
+                .eq(HolidayPassengerFlow::getYear, 2019)
+                .eq(HolidayPassengerFlow::getTransportMode, HolidayConstants.MODE_ROAD)) > 0) {
+            return;
+        }
+        Sheet sheet = workbook.getSheet("閬撹矾");
+        if (sheet == null) return;
+        Integer yearColumn = findYearColumn(sheet, evaluator, 2019, 2, 20);
+        if (yearColumn == null) return;
+        for (int rowIndex = 0; rowIndex <= Math.min(sheet.getLastRowNum(), DAY_ROW_SCAN_LIMIT); rowIndex++) {
+            Row row = sheet.getRow(rowIndex);
+            if (row == null) continue;
+            Integer dayIndex = parseDayIndex(row.getCell(0), evaluator);
+            if (dayIndex == null) continue;
+            BigDecimal value = numberValue(row.getCell(yearColumn), evaluator);
+            if (value != null) {
+                upsertPassenger(2019, LocalDate.of(2019, 10, dayIndex), HolidayConstants.MODE_ROAD, value);
+            }
         }
     }
 
@@ -591,11 +723,22 @@
             Integer yearColumn = findYearColumn(sheet, evaluator, year, 2, 7);
             if (yearColumn == null) continue;
             for (Map.Entry<Integer, LocalDate> day : dayDates.entrySet()) {
-                Row row = sheet.getRow(FIRST_DATA_ROW_INDEX + day.getKey() - 1);
+                Row row = findDayRow(sheet, evaluator, day.getKey());
                 if (row == null) continue;
                 BigDecimal value = numberValue(row.getCell(yearColumn), evaluator);
                 if (value != null) {
                     upsertPassenger(year, day.getValue(), entry.getValue(), value);
+                }
+            }
+            if (HolidayConstants.MODE_RAIL.equals(entry.getValue())
+                    || HolidayConstants.MODE_CIVIL_AVIATION.equals(entry.getValue())) {
+                Row previousRow = findPreviousDayRow(sheet, evaluator);
+                LocalDate previousDate = previousDayDate(year, HolidayConstants.TYPE_NATIONAL_DAY, dayDates);
+                if (previousRow != null && previousDate != null) {
+                    BigDecimal value = numberValue(previousRow.getCell(yearColumn), evaluator);
+                    if (value != null) {
+                        upsertPassenger(year, previousDate, entry.getValue(), value);
+                    }
                 }
             }
         }
@@ -618,7 +761,7 @@
         Integer yearColumn = findYearColumn(sheet, evaluator, year, startColumn, endColumn);
         if (yearColumn == null) return;
         for (Map.Entry<Integer, LocalDate> day : dayDates.entrySet()) {
-            Row row = sheet.getRow(FIRST_DATA_ROW_INDEX + day.getKey() - 1);
+            Row row = findDayRow(sheet, evaluator, day.getKey());
             if (row == null) continue;
             BigDecimal value = numberValue(row.getCell(yearColumn), evaluator);
             if (value != null) {
@@ -659,6 +802,46 @@
         }
     }
 
+    private LocalDate previousDayDate(int year, String holidayType, Map<Integer, LocalDate> dateByDay) {
+        HolidayCalendar configured = configService.findPreviousDay(year, holidayType);
+        if (configured != null && configured.getHolidayDate() != null) {
+            return configured.getHolidayDate();
+        }
+        LocalDate firstDate = firstDate(dateByDay);
+        return firstDate == null ? null : firstDate.minusDays(1);
+    }
+
+    private LocalDate firstDate(Map<Integer, LocalDate> dateByDay) {
+        LocalDate result = null;
+        for (LocalDate date : dateByDay.values()) {
+            if (date != null && (result == null || date.isBefore(result))) result = date;
+        }
+        return result;
+    }
+
+    private Row findDayRow(Sheet sheet, FormulaEvaluator evaluator, int dayIndex) {
+        int lastRow = Math.min(sheet.getLastRowNum(), DAY_ROW_SCAN_LIMIT);
+        for (int rowIndex = 0; rowIndex <= lastRow; rowIndex++) {
+            Row row = sheet.getRow(rowIndex);
+            if (row == null) continue;
+            Integer rowDay = parseDayIndex(row.getCell(0), evaluator);
+            if (rowDay != null && rowDay.intValue() == dayIndex) return row;
+        }
+        return null;
+    }
+
+    private Row findPreviousDayRow(Sheet sheet, FormulaEvaluator evaluator) {
+        int lastRow = Math.min(sheet.getLastRowNum(), DAY_ROW_SCAN_LIMIT);
+        DataFormatter formatter = new DataFormatter();
+        for (int rowIndex = 0; rowIndex <= lastRow; rowIndex++) {
+            Row row = sheet.getRow(rowIndex);
+            if (row == null || row.getCell(0) == null) continue;
+            String text = formatter.formatCellValue(row.getCell(0), evaluator).trim();
+            if (text.contains("鍓嶄竴鏃�")) return row;
+        }
+        return null;
+    }
+
     private Map<Integer, LocalDate> dayDates(int year, String holidayType) {
         Map<Integer, LocalDate> result = new LinkedHashMap<>();
         for (HolidayCalendar row : configService.findHolidayDays(year, holidayType)) {
diff --git a/traffic-audit-web/src/views/SystemConfig.vue b/traffic-audit-web/src/views/SystemConfig.vue
index f9df604..5b97212 100644
--- a/traffic-audit-web/src/views/SystemConfig.vue
+++ b/traffic-audit-web/src/views/SystemConfig.vue
@@ -40,7 +40,9 @@
                   <template slot-scope="scope">{{ labelOf(holidayTypeOptions, scope.row.holidayType) }}</template>
                 </el-table-column>
                 <el-table-column prop="holidayDate" label="鏃ユ湡" width="150" align="center"></el-table-column>
-                <el-table-column prop="dayIndex" label="绗嚑鏃�" width="100" align="center"></el-table-column>
+                <el-table-column label="鏃ユ湡绫诲瀷" width="120" align="center">
+                  <template slot-scope="scope">{{ dayIndexLabel(scope.row.dayIndex) }}</template>
+                </el-table-column>
                 <el-table-column label="鎿嶄綔" width="150" align="center">
                   <template slot-scope="scope">
                     <el-button type="text" size="mini" @click="openHolidayDialog(scope.row)">缂栬緫</el-button>
@@ -93,8 +95,11 @@
               <el-date-picker v-model="holidayForm.holidayDate" type="date" value-format="yyyy-MM-dd"
                               style="width:100%" placeholder="閫夋嫨鏃ユ湡"></el-date-picker>
             </el-form-item>
-            <el-form-item label="绗嚑鏃�" prop="dayIndex">
-              <el-input-number v-model="holidayForm.dayIndex" :min="1" :max="31" style="width:100%"></el-input-number>
+            <el-form-item label="鏃ユ湡绫诲瀷" prop="dayIndex">
+              <el-select v-model="holidayForm.dayIndex" style="width:100%">
+                <el-option label="鍓嶄竴鏃�" :value="0"></el-option>
+                <el-option v-for="day in 31" :key="day" :label="'绗�' + day + '鏃�'" :value="day"></el-option>
+              </el-select>
             </el-form-item>
           </el-form>
           <span slot="footer">
@@ -157,7 +162,7 @@
         year: [{ required: true, message: '璇烽�夋嫨骞翠唤', trigger: 'change' }],
         holidayType: [{ required: true, message: '璇烽�夋嫨鑺傚亣鏃ュ垎绫�', trigger: 'change' }],
         holidayDate: [{ required: true, message: '璇烽�夋嫨鏃ユ湡', trigger: 'change' }],
-        dayIndex: [{ required: true, message: '璇疯緭鍏ョ鍑犳棩', trigger: 'change' }]
+        dayIndex: [{ required: true, message: '璇烽�夋嫨鏃ユ湡绫诲瀷', trigger: 'change' }]
       },
       coefficientRules: {
         year: [{ required: true, message: '璇烽�夋嫨骞翠唤', trigger: 'change' }],
@@ -172,6 +177,10 @@
     this.loadCoefficients()
   },
   methods: {
+    dayIndexLabel(value) {
+      if (Number(value) === 0) return '鍓嶄竴鏃�'
+      return value === null || value === undefined || value === '' ? '鈥�' : '绗�' + value + '鏃�'
+    },
     loadOptions() {
       api.get('/holiday/config/options').then(res => {
         const data = res.data || {}

--
Gitblit v1.9.1