xyc
4 天以前 cdccc9840978adb989f173b8d4763b7b5677f9b5
feat(holiday): expose 2019 holiday configuration
8个文件已修改
43 ■■■■■ 已修改文件
HANDOFF.md 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
deploy-templates/db/sql_holiday_previous_day_migration.sql 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/database.md 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docs/sql_holiday_previous_day_migration.sql 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traffic-audit-server/src/main/java/com/trafficaudit/holiday/HolidayConstants.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayWorkbookService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traffic-audit-web/src/views/HolidayStat.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traffic-audit-web/src/views/SystemConfig.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HANDOFF.md
@@ -12,6 +12,7 @@
- **正常导入口径**:只读取所选年份的当年列(2026 年铁路/民航/道路/水路为 C 列、高速为 C 列、普通国省道为 D 列);同时只额外读取当前年份铁路/民航的“前一日”行。2019/2024/2025 历史列不参与导入。
- **快报口径**:同比只使用 2025、2024;假期第 1 日的铁路、民航环比使用“前一日”数据,公路、水路、总计及其他口径第 1 日仍显示“—”;第 2 日起正常计算环比。
- **迁移脚本**:`docs/sql_holiday_previous_day_migration.sql`,部署包同步为 `deploy-templates/db/sql_holiday_previous_day_migration.sql`,脚本可重复执行。
- **2019 显示补齐(10-03 晚追加)**:`holiday_calendar` 增加 2019-10-01 至 2019-10-08 配置;系统配置-节假日管理和专项统计-节假日均增加 2019 年份,历史库执行幂等迁移后即可查看 2019 年 8 天道路数据。
- **验证(本机 3305 库 + 真实模板)**:接口导入结果 `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(重启后已加载新代码)、前端 8080 均在运行;访问 `http://localhost:8080`。
deploy-templates/db/sql_holiday_previous_day_migration.sql
@@ -1,8 +1,16 @@
-- 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.
-- Backfill the 2019 National Day calendar and previous-day rows used by rail and civil-aviation ring-ratio calculations.
-- day_index = 0 identifies the configured previous day; 2019 uses normal days 1..8.
INSERT IGNORE INTO holiday_calendar
  (year, holiday_type, holiday_date, day_index, created_at, updated_at)
VALUES
  (2019, 'NATIONAL_DAY', '2019-10-01', 1, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-02', 2, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-03', 3, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-04', 4, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-05', 5, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-06', 6, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-07', 7, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-08', 8, NOW(), NOW()),
  (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());
docs/database.md
@@ -548,7 +548,7 @@
  - 公路人员流动量 = 道路营业性客运量 + 非营业性人员流动量。
- 总人员流动量 = 公路 + 铁路 + 民航 + 水路。
- 导入按“年份 + 节假日分类”读取 `holiday_calendar` 中 `day_index>=1` 的日期,将工作簿“第N日”行覆盖写入当年客流/车流;同时读取当前年份铁路、民航的“前一日”行,写入 `day_index=0` 对应的日期。
- 日常导入只读取所选年份的当年列(道路表的 2019/2024/2025 列均不读取);2019 年道路数据和 2024/2025/2026 年前一日铁路、民航数据由启动初始化直接写入数据库。
- 日常导入只读取所选年份的当年列(道路表的 2019/2024/2025 列均不读取);2019 年道路数据和 2024/2025/2026 年前一日铁路、民航数据由启动初始化直接写入数据库。2019 年 10 月 1-8 日的 `holiday_calendar` 配置用于在系统配置和节假日统计页查看该历史基线。
- 导入前检查比本次最新导入日更早的历史日期是否发生变化;如有变化先不写库,返回差异清单,用户确认后才允许覆盖。
- 记录“前一日”的铁路、民航数据后,假期第 1 日的铁路、民航环比按该数据计算;公路、水路、总人员流动量在第 1 日仍不计算环比。
- 导出以源工作簿为底稿,回填库内数据与客运系数;快报按日期生成 Word,同比固定使用 2025、2024 两年,不使用 2019 数据。
docs/sql_holiday_previous_day_migration.sql
@@ -1,8 +1,16 @@
-- 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.
-- Backfill the 2019 National Day calendar and previous-day rows used by rail and civil-aviation ring-ratio calculations.
-- day_index = 0 identifies the configured previous day; 2019 uses normal days 1..8.
INSERT IGNORE INTO holiday_calendar
  (year, holiday_type, holiday_date, day_index, created_at, updated_at)
VALUES
  (2019, 'NATIONAL_DAY', '2019-10-01', 1, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-02', 2, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-03', 3, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-04', 4, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-05', 5, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-06', 6, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-07', 7, NOW(), NOW()),
  (2019, 'NATIONAL_DAY', '2019-10-08', 8, NOW(), NOW()),
  (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());
traffic-audit-server/src/main/java/com/trafficaudit/holiday/HolidayConstants.java
@@ -110,7 +110,7 @@
        options.put("transportModes", TRANSPORT_MODE_LABELS);
        options.put("roadCategories", ROAD_CATEGORY_LABELS);
        options.put("vehicleTypes", VEHICLE_TYPE_LABELS);
        options.put("years", Arrays.asList(2024, 2025, 2026));
        options.put("years", Arrays.asList(2019, 2024, 2025, 2026, 2027, 2028, 2029, 2030));
        return options;
    }
}
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayWorkbookService.java
@@ -614,9 +614,10 @@
        if (!configService.listHolidays(null, null).isEmpty()) {
            return;
        }
        int[] lengths = {7, 8, 8};
        for (int i = 0; i < REFERENCE_YEARS.length; i++) {
            int year = REFERENCE_YEARS[i];
        int[] calendarYears = {2019, 2024, 2025, 2026};
        int[] lengths = {8, 7, 8, 8};
        for (int i = 0; i < calendarYears.length; i++) {
            int year = calendarYears[i];
            List<HolidayCalendar> existing = configService.findHolidayDays(year, HolidayConstants.TYPE_NATIONAL_DAY);
            Map<Integer, HolidayCalendar> byDay = new LinkedHashMap<>();
            for (HolidayCalendar row : existing) {
@@ -633,6 +634,9 @@
                calendar.setUpdatedAt(LocalDateTime.now());
                configService.saveHoliday(toMap(calendar));
            }
            if (year == 2019) {
                continue;
            }
            HolidayCalendar previousDay = new HolidayCalendar();
            previousDay.setYear(year);
            previousDay.setHolidayType(HolidayConstants.TYPE_NATIONAL_DAY);
traffic-audit-web/src/views/HolidayStat.vue
@@ -92,7 +92,7 @@
  name: 'HolidayStat',
  data() {
    return {
      years: [2024, 2025, 2026, 2027, 2028, 2029, 2030],
      years: [2019, 2024, 2025, 2026, 2027, 2028, 2029, 2030],
      year: 2026,
      holidayType: 'NATIONAL_DAY',
      holidayTypeOptions: [],
traffic-audit-web/src/views/SystemConfig.vue
@@ -144,7 +144,7 @@
  data() {
    return {
      activeTab: 'holidays',
      years: [2024, 2025, 2026, 2027, 2028, 2029, 2030],
      years: [2019, 2024, 2025, 2026, 2027, 2028, 2029, 2030],
      holidayTypeOptions: [],
      dateCategoryOptions: [],
      holidayQuery: { year: 2026, holidayType: 'NATIONAL_DAY' },