From 73e810fc9569597be99accd08d63aab6e7c0daac Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期二, 06 十月 2026 09:36:41 +0800
Subject: [PATCH] fix(holiday): 提高平均拥挤度走势图标签精度

---
 traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayWorkbookService.java |   38 +++++++++++++++++++++++++++++---------
 1 files changed, 29 insertions(+), 9 deletions(-)

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 5775f22..cdf5e8a 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
@@ -568,6 +568,9 @@
                 setNumeric(sheet, row.getRowNum(), yearColumn, values.get(day.getValue()));
             }
             if (comparisonBaseColumn != null && HolidayConstants.supportsComparisonBase(year)) {
+                // Column C (comparison base) is written as an operator backup value only. The ring
+                // ratio in column E always compares the current day with the previous day row of
+                // the same year, so the base never changes the calculated percentage.
                 Map<LocalDate, BigDecimal> bases = loadComparisonBaseValues(year);
                 for (Map.Entry<Integer, LocalDate> day : dayDates.entrySet()) {
                     if (!bases.containsKey(day.getValue())) continue;
@@ -575,16 +578,27 @@
                     if (row == null) continue;
                     setNumeric(sheet, row.getRowNum(), comparisonBaseColumn, bases.get(day.getValue()));
                 }
+                Integer previousRowIndex = null;
                 for (Map.Entry<Integer, LocalDate> day : dayDates.entrySet()) {
-                    if (!bases.containsKey(day.getValue())) continue;
                     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);
+                    if (row == null) {
+                        previousRowIndex = null;
+                        continue;
+                    }
+                    if (previousRowIndex != null) {
+                        setFormula(sheet, row.getRowNum(), 4,
+                                ringRatioFormula(row.getRowNum() + 1, previousRowIndex + 1));
+                    }
+                    previousRowIndex = row.getRowNum();
                 }
             }
         }
+    }
+
+    // Ring ratio = (current day value - previous day value) / previous day value, always taken
+    // from the active year column (D). This intentionally ignores the comparison base column.
+    static String ringRatioFormula(int excelRow, int previousExcelRow) {
+        return "=(D" + excelRow + "-D" + previousExcelRow + ")/D" + previousExcelRow;
     }
 
     private void fillCoefficients(XSSFWorkbook workbook, FormulaEvaluator evaluator, int selectedYear, String holidayType) {
@@ -614,9 +628,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) {
@@ -632,6 +647,9 @@
                 calendar.setCreatedAt(LocalDateTime.now());
                 calendar.setUpdatedAt(LocalDateTime.now());
                 configService.saveHoliday(toMap(calendar));
+            }
+            if (year == 2019) {
+                continue;
             }
             HolidayCalendar previousDay = new HolidayCalendar();
             previousDay.setYear(year);
@@ -1009,7 +1027,9 @@
         if (row == null) row = sheet.createRow(rowIndex);
         Cell cell = row.getCell(columnIndex);
         if (cell == null) cell = row.createCell(columnIndex);
-        cell.setCellFormula(formula);
+        // POI's setCellFormula rejects a leading '='; the helper accepts either form.
+        String normalized = formula.startsWith("=") ? formula.substring(1) : formula;
+        cell.setCellFormula(normalized);
     }
 
     private Map<String, Object> toMap(HolidayCalendar calendar) {

--
Gitblit v1.9.1