From 791a12762b4b3ab8b781e85d99c4316089f2a3f0 Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期一, 21 九月 2026 10:20:46 +0800
Subject: [PATCH] docs(工作日结): 补记 2026-09-21 全库数据备份与同事交付包

---
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java |  117 ++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 92 insertions(+), 25 deletions(-)

diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java
index 19191bd..c694e75 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java
@@ -2465,10 +2465,10 @@
             }
             if (name == null || name.trim().isEmpty()) continue;
             String nt = name.trim().replaceAll("[\r\n]+", "");
-            if (nt.contains("鍚堣") || nt.contains("鎬昏")) continue;
+            String ntFlat = nt.replaceAll("\\s+", "");
+            if (ntFlat.contains("鍚堣") || ntFlat.contains("鎬昏") || ntFlat.contains("灏忚")) continue;
             if (nt.matches("^[涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+銆�.*")) continue;
             if (nt.matches("^锛圼涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+锛�.*")) continue;
-            if (nt.replace(" ", "").matches(".*灏廫\s*璁�.*")) continue;
             if (nt.startsWith("濉姤") || nt.startsWith("鍗曚綅璐熻矗浜�") || nt.matches("^\\d+銆�.*")) continue;
             if (hasSeq) {
                 if (seq == null || seq.trim().isEmpty()) {
@@ -2489,6 +2489,8 @@
             project.setProjectName(nt);
             project.setCategory(category);
             project.setCity(currentCity);
+            String countyCell = cellStr(row, col.get("county"));
+            if (countyCell != null && !countyCell.trim().isEmpty()) project.setCounty(countyCell.trim());
             project.setBuilderName(cellStr(row, col.get("builder")));
             project.setConstructNature(cellStr(row, col.get("nature")));
             project.setStartTime(investTime(cellStr(row, col.get("start"))));
@@ -2524,13 +2526,22 @@
             Row row = sh.getRow(r);
             if (row == null) continue;
             boolean hasName = false;
+            int headerCells = 0;
             for (int c = 0; c <= row.getLastCellNum(); c++) {
                 String v = cellStr(row, c);
-                if (v != null && v.contains("椤圭洰鍚嶇О")) { hasName = true; break; }
+                if (v == null) continue;
+                String t = v.trim();
+                if (t.isEmpty() || t.length() > 20) continue;   // 璇存槑鎬ч暱鍙ヤ笉绠楄〃澶村瓧娈�
+                String k = investHeaderKey(t);
+                if (k == null) continue;
+                headerCells++;
+                if ("name".equals(k)) hasName = true;
             }
-            if (!hasName) continue;
+            // 鐪熻〃澶磋鑷冲皯鏈� 2 涓煭琛ㄥご瀛楁锛涘彧鏈変竴鏍奸暱鍙ュ惈銆岄」鐩悕绉般�嶇殑璇存槑椤典細琚帓闄�
+            if (!hasName || headerCells < 2) continue;
             Map<Integer, String> colTexts = new HashMap<>();
-            for (int rr = r; rr <= Math.min(r + 3, sh.getLastRowNum()); rr++) {
+            int scanEnd = investHeaderScanEnd(sh, r, row);
+            for (int rr = r; rr <= scanEnd; rr++) {
                 Row rr2 = sh.getRow(rr);
                 if (rr2 == null) continue;
                 for (int c = 0; c <= rr2.getLastCellNum(); c++) {
@@ -2541,23 +2552,8 @@
             }
             Map<String, Integer> col = new HashMap<>();
             for (Map.Entry<Integer, String> e : colTexts.entrySet()) {
-                int c = e.getKey();
-                String v = e.getValue();
-                if (v.contains("椤圭洰鍚嶇О")) col.putIfAbsent("name", c);
-                else if (v.contains("鎶曡祫寤鸿") || v.contains("寤鸿鍗曚綅") || v.contains("椤圭洰涓氫富")) col.putIfAbsent("builder", c);
-                else if (v.contains("寤鸿鎬ц川")) col.putIfAbsent("nature", c);
-                else if (v.contains("寮�宸�")) col.putIfAbsent("start", c);
-                else if (v.contains("绔e伐") || v.contains("寤烘垚")) col.putIfAbsent("end", c);
-                else if ((v.contains("璁″垝鎬绘姇璧�") || v.contains("鎬绘姇璧�")) && !v.contains("绱")) col.putIfAbsent("total", c);
-                else if (v.contains("鑷紑濮嬪缓璁�")) col.putIfAbsent("startcum", c);
-                else if (v.contains("鏈勾璁″垝")) col.putIfAbsent("yearplan", c);
-                else if (v.contains("鑷勾鍒濈疮璁�")) col.putIfAbsent("yearcum", c);
-                else if (v.contains("鏈湀瀹屾垚")) col.putIfAbsent("monthdone", c);
-                else if (v.contains("寤鸿闃舵")) col.putIfAbsent("stage", c);
-                else if (v.contains("褰㈣薄杩涘害")) col.putIfAbsent("desc", c);
-                else if (v.contains("宸ュ彲") && !v.contains("椤圭洰鍚嶇О")) col.putIfAbsent("gk", c);
-                else if (v.contains("鍒濊") && !v.contains("椤圭洰鍚嶇О")) col.putIfAbsent("cs", c);
-                else if (v.contains("寤虹瓚闈㈢Н") && !v.contains("鏂板")) col.putIfAbsent("area", c);
+                String k = investHeaderKey(e.getValue());
+                if (k != null) col.putIfAbsent(k, e.getKey());
             }
             if (!col.containsKey("name")) continue;
             for (int c = 0; c <= row.getLastCellNum(); c++) {
@@ -2574,14 +2570,85 @@
                 int md = col.get("yearcum") + 1;
                 if (md <= row.getLastCellNum()) col.put("monthdone", md);
             }
+            // desc 缂哄け鏃舵寜 stage+1 鍏滃簳锛氱渷鏍囥�岄」鐩缓璁鹃樁娈点�佽繘搴︽儏鍐点�嶆槸 L/M 鍚堝苟琛ㄥご锛�
+            // 瀛濇劅/鎭╂柦/鏋楀尯/闅忓窞绛夊競宸炲彧鍦� L 鍐欍�屽缓璁鹃樁娈点�嶃�丮 鐩存帴鍐欒繘搴︽枃瀛楄�屼笉鍐欐爣棰�
+            if (!col.containsKey("desc") && col.containsKey("stage") && col.get("stage") >= 0) {
+                int dc = col.get("stage") + 1;
+                if (dc <= row.getLastCellNum()) col.put("desc", dc);
+            }
             for (String k : new String[]{"builder", "nature", "start", "end", "total", "startcum",
-                "yearplan", "yearcum", "monthdone", "stage", "desc", "gk", "cs", "area"}) {
+                "yearplan", "yearcum", "monthdone", "stage", "desc", "gk", "cs", "area", "county"}) {
                 col.putIfAbsent(k, -1);
             }
             col.put("headerRow", r);
             return col;
         }
         return null;
+    }
+
+    /** 鍗曚釜琛ㄥご鍗曞厓鏍� -> 瀛楁閿紙null 琛ㄧず涓嶆槸琛ㄥご瀛楁锛夛紱渚涜〃澶磋鍒ゅ畾涓庡垪鏄犲皠鍏辩敤 */
+    private String investHeaderKey(String v) {
+        if (v == null) return null;
+        String flat = v.replace(" ", "");
+        if (v.contains("椤圭洰鍚嶇О")) return "name";
+        // 銆屽幙锛堝競銆佸尯锛夈�嶇殑鍚勭鍐欐硶锛氬崐/鍏ㄨ鎷彿銆侀】鍙�/閫楀彿銆佹湁鏃犳嫭鍙凤紝缁熶竴褰掍竴鍖栧悗鍐嶅垽瀹�
+        String flatCounty = flat.replace("锛�", "(").replace("锛�", ")").replace("銆�", "").replace("锛�", "").replace(",", "");
+        if (flatCounty.contains("鍘�(甯傚尯)") || flatCounty.contains("鍘垮競鍖�") || flatCounty.contains("鍖哄幙")) return "county";
+        if (v.contains("鎶曡祫寤鸿") || v.contains("寤鸿鍗曚綅") || v.contains("椤圭洰涓氫富")) return "builder";
+        if (v.contains("寤鸿鎬ц川")) return "nature";
+        if (v.contains("寮�宸�")) return "start";
+        if (v.contains("绔e伐") || v.contains("寤烘垚")) return "end";
+        if ((v.contains("璁″垝鎬绘姇璧�") || v.contains("鎬绘姇璧�")) && !v.contains("绱")) return "total";
+        if (v.contains("鑷紑濮嬪缓璁�")) return "startcum";
+        if (v.contains("鏈勾璁″垝")) return "yearplan";
+        if (v.contains("鑷勾鍒濈疮璁�")) return "yearcum";
+        if (v.contains("鏈湀瀹屾垚")) return "monthdone";
+        if (v.contains("寤鸿闃舵")) return "stage";
+        if (v.contains("褰㈣薄杩涘害") || v.contains("寤鸿杩涘睍")) return "desc";
+        if (v.contains("宸ュ彲") && !v.contains("椤圭洰鍚嶇О")) return "gk";
+        if (v.contains("鍒濊") && !v.contains("椤圭洰鍚嶇О")) return "cs";
+        if (v.contains("寤虹瓚闈㈢Н") && !v.contains("鏂板")) return "area";
+        return null;
+    }
+
+    /** 琛ㄥご鏂囨湰鎵弿涓嬬晫锛氶粯璁よ〃澶磋 +3锛涜嫢銆岄」鐩悕绉般�嶅垪棣栦釜鏁版嵁琛屾洿闈犱笅锛屽垯鎵╁睍鍒版暟鎹鍓嶄竴琛岋紙涓婇檺 +12锛夈��
+     *  鑳屾櫙锛氬捀瀹�/鍗佸牥绛夊競宸炴妸銆屽缓璁鹃樁娈�/褰㈣薄杩涘害銆嶆爣绛惧啓鍦ㄨ〃澶翠笅绗� 4~8 琛岋紝鍥哄畾 +3 浼氭紡鍒楋紙褰㈣薄杩涘害璇讳笉鍒帮級銆� */
+    private int investHeaderScanEnd(Sheet sh, int headerRow, Row headerRowObj) {
+        int hardEnd = Math.min(headerRow + 12, sh.getLastRowNum());
+        int nameCol = -1;
+        if (headerRowObj != null) {
+            for (int c = 0; c <= headerRowObj.getLastCellNum(); c++) {
+                String v = cellStr(headerRowObj, c);
+                if (v != null && v.contains("椤圭洰鍚嶇О")) { nameCol = c; break; }
+            }
+        }
+        int firstData = findFirstInvestDataRow(sh, headerRow, nameCol);
+        int scanEnd = (firstData > headerRow)
+            ? Math.min(hardEnd, firstData - 1)
+            : Math.min(headerRow + 3, sh.getLastRowNum());
+        if (scanEnd < headerRow) scanEnd = headerRow;
+        return scanEnd;
+    }
+
+    /** 銆岄」鐩悕绉般�嶅垪棣栦釜鏁版嵁琛屼笅鏍囷紙璺宠繃琛ㄥご缁涓庣┖琛岋級锛涙壘涓嶅埌杩斿洖 -1 */
+    private int findFirstInvestDataRow(Sheet sh, int headerRow, int nameCol) {
+        if (nameCol < 0) return -1;
+        for (int r = headerRow + 1; r <= sh.getLastRowNum(); r++) {
+            Row row = sh.getRow(r);
+            if (row == null) continue;
+            String name = cellStr(row, nameCol);
+            if (name == null || name.trim().isEmpty()) continue;
+            String nt = name.trim().replaceAll("[\r\n]+", "");
+            if (nt.contains("椤圭洰鍚嶇О")) continue;
+            String flat = nt.replaceAll("\\s+", "");
+            if (flat.contains("鍚堣") || flat.contains("鎬昏") || flat.contains("灏忚")) continue;
+            if (nt.matches("^[涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+銆�.*")) continue;
+            if (nt.matches("^锛圼涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+锛�.*")) continue;
+            if (nt.startsWith("濉姤") || nt.startsWith("鍗曚綅璐熻矗浜�") || nt.matches("^\\d+銆�.*")) continue;
+            if (investmentCity(nt) != null) continue;
+            return r;
+        }
+        return -1;
     }
 
     /** 缁熻 sheet 鍐呴」鐩暟鎹鏁帮紙鐢ㄤ簬澶� sheet 鍘嗗彶鏂囦欢閫夊綋鏈� sheet锛� */
@@ -2596,9 +2663,9 @@
             String name = cellStr(row, nameCol);
             if (name == null || name.trim().isEmpty()) continue;
             String nt = name.trim().replaceAll("[\r\n]+", "");
-            if (nt.contains("鍚堣") || nt.contains("鎬昏")) continue;
+            String ntFlat = nt.replaceAll("\\s+", "");
+            if (ntFlat.contains("鍚堣") || ntFlat.contains("鎬昏") || ntFlat.contains("灏忚")) continue;
             if (nt.matches("^[涓�浜屼笁鍥涗簲鍏竷鍏節鍗乚+銆�.*")) continue;
-            if (nt.replace(" ", "").matches(".*灏廫\s*璁�.*")) continue;
             if (nt.startsWith("濉姤") || nt.startsWith("鍗曚綅璐熻矗浜�") || nt.matches("^\\d+銆�.*")) continue;
             if (!hasSeq) {
                 if (nt.length() > 4) count++;

--
Gitblit v1.9.1