From ade4387f72c876f779b0956295922003464434f0 Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期六, 19 九月 2026 23:26:59 +0800
Subject: [PATCH] fix(汇总表): 中口径排名周转量口径统一为「总量-城市内」差额法

---
 traffic-audit-server/src/main/java/com/trafficaudit/reportexport/calc/SummaryWorkbookFiller.java |   56 ++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/calc/SummaryWorkbookFiller.java b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/calc/SummaryWorkbookFiller.java
index 5cf99d7..f40a596 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/calc/SummaryWorkbookFiller.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/calc/SummaryWorkbookFiller.java
@@ -7,6 +7,8 @@
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -33,6 +35,8 @@
  */
 @Service
 public class SummaryWorkbookFiller {
+
+    private static final Logger log = LoggerFactory.getLogger(SummaryWorkbookFiller.class);
 
     @Resource
     private MidCalc midCalc;
@@ -429,9 +433,11 @@
         if (wb == null || month <= 1) return 0;
         int targetCol = FIRST_MONTH_COL + 2 * (month - 1);
         int written = 0;
+        int carried = 0;
         for (int i = 0; i < wb.getNumberOfSheets(); i++) {
             Sheet sh = wb.getSheetAt(i);
-            if (sh == null || !isFilledLedgerSheet(sh.getSheetName())) continue;
+            if (sh == null || !isMonthLedgerSheet(sh.getSheetName())) continue;
+            boolean derivedSheet = isDerivedFormulaSheet(sh.getSheetName());
             for (int r = sh.getFirstRowNum(); r <= sh.getLastRowNum(); r++) {
                 Row row = sh.getRow(r);
                 if (row == null) continue;
@@ -446,7 +452,21 @@
                         break;
                     }
                 }
-                if (srcCell == null) continue;
+                if (srcCell == null) {
+                    if (!derivedSheet) continue;
+                    // 娲剧敓椤碉紙鍩庡競瀹㈣繍/涓彛寰勬槑缁�/鍏矾鎬诲杩愶級閲屻�屽悇鏈堥兘鏄悓涓�涓父閲忋�嶇殑缁撴瀯鎬у父閲忚
+                    // 锛堝涓彛寰勬槑缁� 姝︽眽 鍩庨檯鍩庝埂宸℃父鍑虹=0锛夛紝鎸夋湀娌跨敤璇ュ父閲忥紝閬垮厤褰撴湀鍊煎垪绌虹潃瀵艰嚧绱缂洪」
+                    double struct = structuralConstant(row, month);
+                    if (Double.isNaN(struct)) continue;
+                    Cell target = row.getCell(targetCol);
+                    if (target == null) target = row.createCell(targetCol);
+                    Cell prev = row.getCell(FIRST_MONTH_COL + 2 * (month - 2));
+                    if (prev != null && prev.getCellStyle() != null) target.setCellStyle(prev.getCellStyle());
+                    target.setCellValue(struct);
+                    carried++;
+                    written++;
+                    continue;
+                }
                 String f = srcCell.getCellFormula();
                 if (f == null || f.isEmpty()) continue;
                 Cell target = row.getCell(targetCol);
@@ -456,7 +476,31 @@
                 written++;
             }
         }
+        if (carried > 0 && log != null) {
+            log.info("姹囨�诲伐浣滅翱锛氭淳鐢熼〉缁撴瀯鎬у父閲忚鎸夋湀娌跨敤 {} 鏍硷紙绗� {} 鏈堬級", carried, month);
+        }
         return written;
+    }
+
+    /** 璇ヨ 1..month-1 鏈堢殑褰撴湀鍊煎垪鏄惁鍏ㄤ负鍚屼竴涓暟鍊煎父閲忥紙缁撴瀯鎬у父閲忚锛屽鍚勬湀鎭掍负 0锛� */
+    private double structuralConstant(Row row, int month) {
+        if (row == null || month <= 2) return Double.NaN;
+        Double v = null;
+        for (int s = 1; s < month; s++) {
+            Cell c = row.getCell(FIRST_MONTH_COL + 2 * (s - 1));
+            if (c == null || c.getCellType() != org.apache.poi.ss.usermodel.CellType.NUMERIC) return Double.NaN;
+            double d = c.getNumericCellValue();
+            if (v == null) v = d;
+            else if (Math.abs(d - v) > 1e-9) return Double.NaN;
+        }
+        return v == null ? Double.NaN : v;
+    }
+
+    /** 娲剧敓椤碉紙褰撴湀鍊煎叏閮ㄦ潵鑷叾浠栭〉/甯搁噺锛岀函鍏紡椹卞姩锛夛細鍩庡競瀹㈣繍 / 涓彛寰勬槑缁� / 鍏矾鎬诲杩� / 涓彛寰勫杩愰噺 */
+    private boolean isDerivedFormulaSheet(String name) {
+        if (name == null) return false;
+        String n = name.trim();
+        return "鍩庡競瀹㈣繍".equals(n) || "涓彛寰勬槑缁�".equals(n) || "鍏矾鎬诲杩�".equals(n) || "涓彛寰勫杩愰噺".equals(n);
     }
 
     /** 璇ユ牸鏄惁宸叉湁鍐呭锛堟暟鍊�/鏂囨湰/鍏紡锛夛紱浠呭甫鏍峰紡鐨勭┖澹筹紙濡傛瘝鐗堥噷缁ф壙琛ㄥご鏃ユ湡鏍煎紡鐨勬牸瀛愶級瑙嗕负绌� */
@@ -467,14 +511,6 @@
             case STRING: return c.getStringCellValue() != null && !c.getStringCellValue().trim().isEmpty();
             default: return true;
         }
-    }
-
-    /** 鍙備笌閫愭湀鏁版嵁鍥炲~鐨勫彴璐﹂〉锛堣揣杩�/鐝嚎鍖呰溅/鍏氦/鍑虹/缃戠害杞�/杞ㄩ亾杞浮锛� */
-    private boolean isFilledLedgerSheet(String name) {
-        if (name == null) return false;
-        String n = name.trim();
-        return "璐ц繍".equals(n) || "鐝嚎鍖呰溅".equals(n) || "鍏氦".equals(n)
-                || "鍑虹".equals(n) || "缃戠害杞�".equals(n) || "杞ㄩ亾銆佽疆娓�".equals(n);
     }
 
     /** 0 鍩哄垪鍙� + 1 鍩鸿鍙� -> "Q5" */

--
Gitblit v1.9.1