From 89a0e7cd7ec202e57e6971e27559b85c3c971aaf Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期一, 12 十月 2026 16:00:43 +0800
Subject: [PATCH] docs(交接): 记录 9 月导入核验与出表抽查结果、仍缺数据清单

---
 traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java |   62 +++++++++++++++++++++++++++----
 1 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
index a93160b..ee4203f 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/reportexport/service/ReportExportService.java
@@ -35,6 +35,7 @@
 import com.trafficaudit.reportexport.calc.PaxCalc;
 import com.trafficaudit.reportexport.calc.SummaryWorkbookFiller;
 import com.trafficaudit.reportexport.calc.FreightReadinessCheck;
+import com.trafficaudit.reportexport.calc.SummaryMissingDataCheck;
 import com.trafficaudit.reportexport.layout.SummaryLayoutExpander;
 import com.trafficaudit.reportexport.calc.WycSplitCalc;
 import lombok.extern.slf4j.Slf4j;
@@ -107,6 +108,8 @@
     private SummaryLayoutExpander summaryLayoutExpander;
     @Resource
     private FreightReadinessCheck freightReadinessCheck;
+    @Resource
+    private SummaryMissingDataCheck missingDataCheck;
     @Resource
     private WycSplitCalc wycSplitCalc;
     @Resource
@@ -3641,14 +3644,54 @@
         if (month >= 12) {
             throw new RuntimeException("鎵╁垪锛�12 鏈堜箣鍚庨渶鏂板紑涓�鏈紝璺ㄥ勾瑙勫垯鍙﹁澶勭悊");
         }
-        File mother = resolveSummaryMother(period, "month");
-        if (mother == null) {
-            throw new RuntimeException("鏈壘鍒版眹鎬昏〃姣嶇増锛坉ocs/鐢熸垚姹囨�诲ぇ琛級锛�" + year + "骞�" + month + "鏈堥亾璺繍杈撻噺姹囨�昏〃.xlsx");
+        // 2026-10-12锛氭墿鍒椾互銆屽綋鏈熶骇鐗┿�嶄负搴曪紙浜х墿鍚綋鏈熷垪鐨勫�间笌鍏紡锛涙瘝鐗堢殑褰撴湡鍒楁槸绌虹殑锛�
+        // 鐩存帴鎷挎瘝鐗堟墿鍒椾細鎶婂綋鏈熸暟鎹涪鎴愮┖娲烇紝瀵艰嚧绱婕忔湀锛夈�備骇鐗╁彇鑷鍑鸿惤鐩樼紦瀛橈紱缂轰骇鐗╂椂鍥為��姣嶇増骞跺憡璀︺��
+        File source = resolveLatestProduct(period);
+        boolean fromProduct = source != null;
+        if (source == null) {
+            source = resolveSummaryMother(period, "month");
+            if (source != null) {
+                log.warn("姹囨�诲ぇ琛ㄦ墿鍒楋細鏈壘鍒� {} 鐨勪骇鐗╃紦瀛橈紝鍥為��鐢ㄦ瘝鐗堟墿鍒椻�斺�斿巻鍙插垪閲岀己灏戝綋鏈熸暟鎹紝绱鍙兘婕忔湀", period);
+            }
         }
-        try (InputStream in = new FileInputStream(mother)) {
+        if (source == null) {
+            throw new RuntimeException("鏈壘鍒版眹鎬昏〃姣嶇増鎴栦骇鐗╋紙docs/鐢熸垚姹囨�诲ぇ琛級锛�" + year + "骞�" + month + "鏈堥亾璺繍杈撻噺姹囨�昏〃.xlsx");
+        }
+        try (InputStream in = new FileInputStream(source)) {
             byte[] out = summaryLayoutExpander.expand(org.apache.poi.util.IOUtils.toByteArray(in), year, month + 1);
-            log.info("姹囨�诲ぇ琛ㄦ墿鍒楀畬鎴愶細{}骞磠}鏈堟瘝鐗� -> {}骞磠}鏈堢増寮忥紙鍙仛鐗堝紡銆佹暟鎹暀绌猴級", year, month, year, month + 1);
+            log.info("姹囨�诲ぇ琛ㄦ墿鍒楀畬鎴愶細{}{} -> {}骞磠}鏈堢増寮忥紙鍙仛鐗堝紡銆佸綋鏈熷垪鐣欑┖锛�",
+                    fromProduct ? "浜х墿" : "姣嶇増", source.getName(), year, month + 1);
             return out;
+        }
+    }
+
+    /** 鍙栬鏈熴�屾渶鏂颁骇鐗┿�嶏細瀵煎嚭钀界洏缂撳瓨 _cache/summaryWorkbook_<period>_month_v*.xlsx锛堟寜淇敼鏃堕棿鍙栨渶鏂帮級 */
+    private File resolveLatestProduct(String period) {
+        try {
+            String rel = summaryTemplateDir;
+            while (rel != null && rel.startsWith("./")) rel = rel.substring(2);
+            String[] roots = {
+                summaryTemplateDir,
+                System.getProperty("user.dir") + "/" + rel,
+                System.getProperty("user.dir") + "/../" + rel
+            };
+            String prefix = "summaryWorkbook_" + period + "_month_";
+            for (String root : roots) {
+                if (root == null || root.trim().isEmpty()) continue;
+                File dir = new File(root, "_cache");
+                if (!dir.isDirectory()) continue;
+                File[] files = dir.listFiles((d, name) -> name.startsWith(prefix) && name.endsWith(".xlsx"));
+                if (files == null || files.length == 0) continue;
+                File latest = files[0];
+                for (File f : files) {
+                    if (f.lastModified() > latest.lastModified()) latest = f;
+                }
+                return latest;
+            }
+            return null;
+        } catch (Exception e) {
+            log.warn("姹囨�诲ぇ琛ㄦ墿鍒楋細鏌ユ壘浜х墿缂撳瓨澶辫触锛堝拷鐣ワ級锛歿}", e.getMessage());
+            return null;
         }
     }
 
@@ -3711,6 +3754,7 @@
             List<String> dbProblems = new ArrayList<>();
             String effPeriod = String.format("%04d-%02d", year, effMonth);
             dbProblems.addAll(freightReadinessCheck.check(effPeriod));   // B4锛氳揣杩愬彛寰勫鍑哄墠浣撴锛�6 鏉¤鍒欙級
+            dbProblems.addAll(missingDataCheck.check(effPeriod));        // 缂烘暟娓呭崟锛堣鏈夌殑鏁版病鏈夛級
             reportProgress(progress, 22, "鍥炲~褰撴湀鏁版嵁");
             int dbFilled = summaryWorkbookFiller.fillMonthlyLedger(wb, effPeriod, year, effMonth, dbProblems);
             int yoyFilled = summaryWorkbookFiller.ensureMonthYoyFormulas(wb, year, effMonth);
@@ -3720,7 +3764,9 @@
             reportProgress(progress, 45, "鍒锋柊鎺掑悕椤典笌璺ㄩ〉鍚堟垚椤�");
             int rankRefreshed = refreshSummaryRankSheets(wb, effPeriod, "month");
             int cumulativeRefreshed = refreshSummaryCumulativeSheets(wb, year, effMonth); // 鍥涘紶璺ㄩ〉鍚堟垚椤甸殢鎶ヨ〃鏈熷埛鏂�
-            int widthApplied = applySummaryReferenceLayout(wb);
+            // 2026-10-12锛氬仠鐢ㄣ�屽鐢ㄥ閮ㄥ弬鐓т欢銆婄敓鎴恄閬撹矾杩愯緭閲忔眹鎬昏〃.xlsx銆嬪垪瀹姐�嶁�斺�旂増寮忎竴寰嬩互褰撴湡姣嶇増涓哄噯锛�
+            // 閬垮厤姣嶇増涓庡弬鐓т欢涓ゅ缁存姢锛堟瘝鐗堝凡骞跺叆鍙傜収浠剁殑鍒楀/闅愯棌锛夈��
+            int widthApplied = 0;
             log.info("姹囨�诲伐浣滅翱鏁版嵁椹卞姩鍥炲~瀹屾垚锛氬啓鍏ュ綋鏈堝�兼牸鏁�={}锛岃ˉ鍐欏綋鏈堝悓姣斿叕寮忔牸鏁�={}锛岃ˉ鍐欏綋鏈堝悎璁″叕寮忔牸鏁�={}锛�"
                     + "淇绱鍚屾瘮鍒嗘瘝鏍兼暟={}锛屽埛鏂版帓鍚嶉〉鏁板�兼牸鏁�={}锛屽埛鏂板洓椤碉紙鍩庡競姹囨��/鍩庡競鍒嗗競宸�/涓彛寰勫垎鏋�/閬撹矾杩愯緭鍛ㄨ浆閲忥級鏁板�兼牸鏁�={}锛�"
                     + "鎸夈�婄敓鎴恄閬撹矾杩愯緭閲忔眹鎬昏〃銆嬪榻愬垪瀹藉垪鏁�={}锛岀己鏁版彁绀�={}",
@@ -4517,8 +4563,8 @@
         if (sh == null) return 0;
         smSetTitle(sh, 0, 0, "鍩庡競瀹㈣繍瀹㈣繍閲忓垎甯傚窞1-" + month + "鏈堢疮璁℃儏鍐�");
         smSetTitle(sh, 22, 0, "鍩庡競瀹㈣繍瀹㈣繍鍛ㄨ浆閲忓垎甯傚窞1-" + month + "鏈堢疮璁℃儏鍐�");
-        smSetTitle(sh, 45, 0, "鍩庡競瀹㈣繍瀹㈣繍閲忓垎甯傚窞" + month + "鏈堟儏鍐�");
-        smSetTitle(sh, 67, 0, "鍩庡競瀹㈣繍瀹㈣繍鍛ㄨ浆閲忓垎甯傚窞" + month + "鏈堟儏鍐�");
+        smSetTitle(sh, 44, 0, "鍩庡競瀹㈣繍瀹㈣繍閲忓垎甯傚窞" + month + "鏈堟儏鍐�");   // 0鍩�44 = Excel 绗�45琛岋紙姣嶇増閲屾爣棰樺湪 A45锛孉46 鏄�"鍗曚綅"琛岋級
+        smSetTitle(sh, 66, 0, "鍩庡競瀹㈣繍瀹㈣繍鍛ㄨ浆閲忓垎甯傚窞" + month + "鏈堟儏鍐�");   // 0鍩�66 = Excel 绗�67琛岋紙鍚屼笂锛�
         int n = 0;
         n += smWriteCityByRegionBlock(sh, 4, true, curCum, lastCum);
         n += smWriteCityByRegionBlock(sh, 26, false, curCum, lastCum);

--
Gitblit v1.9.1