From 0f7b7d11bad2521acdb8089b1ede4697efd1a05c Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期五, 04 九月 2026 13:22:37 +0800
Subject: [PATCH] feat: 城市客运导入新增网约车总数/网约车订单及全省总量两母版导入 + 09-04 测试报告

---
 docs/城市客运/模板_网约车总数.xlsx                                                                             |    0 
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycOrderMonthlyMapper.java    |    6 
 traffic-audit-web/src/views/DataImport.vue                                                          |   20 ++
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java       |  159 ++++++++++++++++++++++
 docs/sql_wyc.sql                                                                                    |   45 ++++++
 docs/功能测试报告/功能测试报告_城市客运网约车导入下拉_2026-09-04.md                                                        |   35 +++++
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataImportController.java |   27 +++
 docs/城市客运/模板_网约车订单及全省总量.xlsx                                                                        |    0 
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycOrderMonthly.java          |   47 ++++++
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycTotalMonthly.java          |   30 ++++
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycTotalMonthlyMapper.java    |    6 
 11 files changed, 370 insertions(+), 5 deletions(-)

diff --git a/docs/sql_wyc.sql b/docs/sql_wyc.sql
new file mode 100644
index 0000000..2a1ee6b
--- /dev/null
+++ b/docs/sql_wyc.sql
@@ -0,0 +1,45 @@
+-- 鍩庡競瀹㈣繍缃戠害杞︽湀搴﹁緭鍏ュ缓琛紙2026-09-04锛�
+-- 鏁版嵁婧�1锛氭ā鏉縚缃戠害杞︽�绘暟.xlsx锛堟湀搴﹀叏鐪� pin锛氬杩愰噺/鍏朵腑鍩庡競鍐�/鍛ㄨ浆閲�/鍏朵腑鍩庡競鍐呭懆杞噺锛�
+-- 鏁版嵁婧�2锛氭ā鏉縚缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx锛堟湀搴﹁緭鍏ラ〉锛欱-E 鍏ㄧ渷 pin + F 璁㈠崟鍚堣 + G-W 17甯傚窞璁㈠崟锛�
+
+CREATE TABLE IF NOT EXISTS wyc_total_monthly (
+  id BIGINT NOT NULL AUTO_INCREMENT,
+  report_period VARCHAR(20) NOT NULL COMMENT '鎶ヨ〃鏈� yyyy-MM',
+  pin_k DOUBLE DEFAULT NULL COMMENT '鍏ㄧ渷缃戠害杞﹀杩愰噺(涓囦汉娆�)',
+  pin_ck DOUBLE DEFAULT NULL COMMENT '鍏朵腑鍩庡競鍐呭杩愰噺',
+  pin_z DOUBLE DEFAULT NULL COMMENT '鍏ㄧ渷瀹㈣繍鍛ㄨ浆閲�(涓囦汉鍏噷)',
+  pin_cz DOUBLE DEFAULT NULL COMMENT '鍏朵腑鍩庡競鍐呭懆杞噺',
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  PRIMARY KEY (id),
+  UNIQUE KEY uk_wyc_total_period (report_period)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缃戠害杞︽湀搴﹀叏鐪� pin 杈撳叆';
+
+CREATE TABLE IF NOT EXISTS wyc_order_monthly (
+  id BIGINT NOT NULL AUTO_INCREMENT,
+  report_period VARCHAR(20) NOT NULL COMMENT '鎶ヨ〃鏈� yyyy-MM',
+  pin_k DOUBLE DEFAULT NULL,
+  pin_ck DOUBLE DEFAULT NULL,
+  pin_z DOUBLE DEFAULT NULL,
+  pin_cz DOUBLE DEFAULT NULL,
+  order_sum DOUBLE DEFAULT NULL COMMENT '璁㈠崟鍚堣锛堝崟锛�',
+  order_wuhan DOUBLE DEFAULT NULL,
+  order_huangshi DOUBLE DEFAULT NULL,
+  order_shiyan DOUBLE DEFAULT NULL,
+  order_yichang DOUBLE DEFAULT NULL,
+  order_xiangyang DOUBLE DEFAULT NULL,
+  order_ezhou DOUBLE DEFAULT NULL,
+  order_jingmen DOUBLE DEFAULT NULL,
+  order_xiaogan DOUBLE DEFAULT NULL,
+  order_jingzhou DOUBLE DEFAULT NULL,
+  order_huanggang DOUBLE DEFAULT NULL,
+  order_xianning DOUBLE DEFAULT NULL,
+  order_suizhou DOUBLE DEFAULT NULL,
+  order_enshi DOUBLE DEFAULT NULL,
+  order_xiantao DOUBLE DEFAULT NULL,
+  order_qianjiang DOUBLE DEFAULT NULL,
+  order_tianmen DOUBLE DEFAULT NULL,
+  order_shennong DOUBLE DEFAULT NULL,
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  PRIMARY KEY (id),
+  UNIQUE KEY uk_wyc_order_period (report_period)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺鏈堝害杈撳叆';
diff --git "a/docs/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212_\345\237\216\345\270\202\345\256\242\350\277\220\347\275\221\347\272\246\350\275\246\345\257\274\345\205\245\344\270\213\346\213\211_2026-09-04.md" "b/docs/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212_\345\237\216\345\270\202\345\256\242\350\277\220\347\275\221\347\272\246\350\275\246\345\257\274\345\205\245\344\270\213\346\213\211_2026-09-04.md"
new file mode 100644
index 0000000..b84d1bf
--- /dev/null
+++ "b/docs/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212/\345\212\237\350\203\275\346\265\213\350\257\225\346\212\245\345\221\212_\345\237\216\345\270\202\345\256\242\350\277\220\347\275\221\347\272\246\350\275\246\345\257\274\345\205\245\344\270\213\346\213\211_2026-09-04.md"
@@ -0,0 +1,35 @@
+# 鍔熻兘娴嬭瘯鎶ュ憡锛氬煄甯傚杩愬鍏ヤ笅鎷夋柊澧炵綉绾﹁溅瀵煎叆锛�2026-09-04锛�
+
+## 鍔熻兘璇存槑
+2026-09-04 鐢ㄦ埛鎷嶆澘锛氭暟鎹鍏モ�斺�斿煄甯傚杩愭ā鍧椾笅鎷夊鍔犮�婄綉绾﹁溅鎬绘暟銆嬩笌銆婄綉绾﹁溅璁㈠崟鍙婂叏鐪佹�婚噺銆嬩袱椤癸紝姣嶇増鏀句簬 docs/鍩庡競瀹㈣繍/銆傛湰娆″疄鐜帮細
+- 鍚庣鏂板瀵煎叆鎺ュ彛锛歅OST /api/import/wycTotal銆丳OST /api/import/wycOrder锛�
+- 鏂板琛� wyc_total_monthly锛堝叏鐪� pin锛変笌 wyc_order_monthly锛坧in + 璁㈠崟鍚堣 + 17甯傚窞璁㈠崟锛夛紝鎸夋姤琛ㄦ湡鍏堝垹鍚庢彃銆佸箓绛� upsert锛屽悓鏃惰褰曟壒娆★紙WYC_TOTAL / WYC_ORDER锛変緵瀵煎叆杩涘害涓庡巻鍙叉樉绀猴紱
+- 鍓嶇 DataImport.vue锛氬煄甯傚杩愪笅鎷夋柊澧炰袱椤广�乀YPE_LABELS / BATCH_TYPE_MAP銆佹ā鏉垮悕/涓嬭浇 URL锛堝搴旀瘝鐗堬級銆乪ndpoint 鏄犲皠鍏ㄩ儴琛ラ綈銆�
+
+浠g爜鏀瑰姩锛堝緟鎺ㄩ�侊級锛�
+- traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycTotalMonthly.java銆乄ycOrderMonthly.java锛堟柊澧烇紝@TableField 鍥哄畾 pin_ck/pin_cz 鍒楀悕锛�
+- traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycTotalMonthlyMapper.java銆乄ycOrderMonthlyMapper.java锛堟柊澧烇級
+- traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java锛堟柊澧� importWycTotal/importWycOrder/upsertWyc/upsertWycTotal/periodOfCell/dbl/dblN 鍙婂垎鍙� case锛�
+- traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataImportController.java锛堟柊澧炰袱涓鐐癸級
+- traffic-audit-web/src/views/DataImport.vue锛堜笅鎷�/鏍囩/妯℃澘/绔偣锛�
+- docs/sql_wyc.sql锛堝缓琛� DDL 娌夋穩锛�
+
+## 娴嬭瘯鐜
+- 鍚庣 8090锛堥噸鍚悗灏辩华锛夛紱鍓嶇 dev server 8080锛圖ataImport.vue 鏀瑰姩鍚庣儹缂栬瘧 Compiled successfully锛夛紱MySQL 127.0.0.1:3308 traffic_audit锛涙瘝鐗堜负 docs/鍩庡競瀹㈣繍/妯℃澘_缃戠害杞︽�绘暟.xlsx銆佹ā鏉縚缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx锛堝疄闄呯紪杈戠増锛屽惈 2026-01~07锛夈��
+- 鏂规硶锛欻TTP 瀹為檯瀵煎叆锛屼笌婧愭枃浠堕�愰」瀵归綈銆佸箓绛夐噸瀵笺�佹ā鏉夸笅杞� URL銆佺┖鏁版嵁璐熷悜鐢ㄤ緥銆�
+
+## 鐢ㄤ緥涓庣粨鏋�
+1. 缃戠害杞︽�绘暟瀵煎叆锛堟鍚戯級锛氫笂浼犳ā鏉縚缃戠害杞︽�绘暟.xlsx锛屾帴鍙h繑鍥炩�滃鍏ユ垚鍔燂紝鍏� 7 鏈熲�濓紱DB 涓� 2026-01~07 鍏ㄧ渷 pin B-E 涓庢瘝鐗堥�愭湡涓�鑷达紙濡� 2026-07 = 4852.3/4430.84/28348.02/22705.61锛夈�傜粨璁� PASS銆�
+2. 缃戠害杞﹁鍗曞鍏ワ紙姝e悜锛夛細涓婁紶妯℃澘_缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx锛屽叡 7 鏈燂紱2026-07 F=璁㈠崟鍚堣 29730791銆丟-W 17甯傚窞涓庢瘝鐗堜竴鑷达紙姝︽眽 11183267鈥︾鍐滄灦 3534锛夛紱2026-01~06 璁㈠崟鍒椾负 NULL锛堟瘝鐗堟棤鏁版嵁锛屾纭級銆傜粨璁� PASS銆�
+3. 骞傜瓑閲嶅瀵煎叆锛堟鍚戯級锛氬悓鏂囦欢閲嶅涓婁紶锛屼袱琛ㄦ暟鎹粛鍚� 7 琛屼笖鍊间笉鍙橈紙鍏堝垹鍚庢彃锛夛紱鎵规琛ㄦ瘡娆″鍏ュ潎璁板綍銆傜粨璁� PASS銆�
+4. 妯℃澘涓嬭浇锛堟鍚戯級锛欸ET /api/templates/鍩庡競瀹㈣繍/妯℃澘_缃戠害杞︽�绘暟.xlsx 涓� 璁㈠崟鐗堝潎 200銆傜粨璁� PASS銆�
+5. 绌烘暟鎹枃浠讹紙璐熷悜锛夛細涓婁紶鍙惈琛ㄥご鐨� xlsx锛岃繑鍥� code 500銆佹彁绀衡�滄湭璇嗗埆鍒版湁鏁堟湀浠借锛欰 鍒楀簲涓烘棩鏈燂紙濡� 2026-07锛夆�︹�濓紝閿欒鏂囨娓呮櫚銆傜粨璁� PASS锛堥鏈熷け璐ワ級銆�
+6. 缂栬瘧涓庡惎鍔細鍚庣 mvn compile EXIT=0锛涘墠绔剼鏈� node --check 閫氳繃涓� dev server 鐑紪璇戞垚鍔熴�傜粨璁� PASS銆�
+
+## 鍙戠幇鐨勯棶棰樹笌澶勭疆
+1. 鏂板 Mapper 鎺ュ彛灏鹃儴娈嬬暀鈥渰{}}鈥濓紙鎶借薄鏂规硶浣擄級瀵艰嚧缂栬瘧澶辫触锛氬凡淇负鈥渰}鈥濄��
+2. DataImportService.periodOfCell 姝e垯 \d 鏈浆涔変负 \\d锛圝ava 瀛楃涓测�滈潪娉曡浆涔夆�濈紪璇戝け璐ワ級锛氬凡淇銆�
+3. 棣栨瀵煎叆杩斿洖鈥滃叡 0 鏈熲�濓細鍘熷洜涓哄疄浣撳瓧娈� pinCK/pinCZ 涓嬪垝绾跨瓥鐣ユ槧灏勪负 pin_c_k/pin_c_z锛屼笌琛ㄥ垪 pin_ck/pin_cz 涓嶅尮閰嶏紝insert 鎶� Unknown column锛涘鐞嗭細瀹炰綋澧炲姞 @TableField("pin_ck")/@TableField("pin_cz")锛屽娴嬪悗 7 鏈熷叏閮ㄥ叆搴撱��
+
+## 缁撹
+鍩庡競瀹㈣繍瀵煎叆涓嬫媺鏂板涓ら」缃戠害杞﹀鍏ュ姛鑳藉凡瀹炵幇骞堕�氳繃娴嬭瘯锛氭鍚戯紙瀹為檯姣嶇増 1-7 鏈堬級銆佸箓绛夐噸瀵笺�佹ā鏉夸笅杞姐�佺┖鏁版嵁璐熷悜鍧囩鍚堥鏈燂紱鍏ュ簱鏁版嵁涓庢簮鏂囦欢閫愰」涓�鑷淬�傚墠绔笅鎷夐」杩橀渶鐢ㄦ埛鍦ㄩ〉闈㈢偣鍑讳汉宸ヨ繃涓�鐪笺��
\ No newline at end of file
diff --git "a/docs/\345\237\216\345\270\202\345\256\242\350\277\220/\346\250\241\346\235\277_\347\275\221\347\272\246\350\275\246\346\200\273\346\225\260.xlsx" "b/docs/\345\237\216\345\270\202\345\256\242\350\277\220/\346\250\241\346\235\277_\347\275\221\347\272\246\350\275\246\346\200\273\346\225\260.xlsx"
new file mode 100644
index 0000000..c7703ce
--- /dev/null
+++ "b/docs/\345\237\216\345\270\202\345\256\242\350\277\220/\346\250\241\346\235\277_\347\275\221\347\272\246\350\275\246\346\200\273\346\225\260.xlsx"
Binary files differ
diff --git "a/docs/\345\237\216\345\270\202\345\256\242\350\277\220/\347\275\221\347\272\246\350\275\246\350\256\242\345\215\225\345\217\212\345\205\250\347\234\201\346\200\273\351\207\217.xlsx" "b/docs/\345\237\216\345\270\202\345\256\242\350\277\220/\346\250\241\346\235\277_\347\275\221\347\272\246\350\275\246\350\256\242\345\215\225\345\217\212\345\205\250\347\234\201\346\200\273\351\207\217.xlsx"
similarity index 100%
rename from "docs/\345\237\216\345\270\202\345\256\242\350\277\220/\347\275\221\347\272\246\350\275\246\350\256\242\345\215\225\345\217\212\345\205\250\347\234\201\346\200\273\351\207\217.xlsx"
rename to "docs/\345\237\216\345\270\202\345\256\242\350\277\220/\346\250\241\346\235\277_\347\275\221\347\272\246\350\275\246\350\256\242\345\215\225\345\217\212\345\205\250\347\234\201\346\200\273\351\207\217.xlsx"
Binary files differ
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataImportController.java b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataImportController.java
index 18e657b..bc7e1de 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataImportController.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataImportController.java
@@ -242,6 +242,33 @@
         }
     }
 
+
+    /** 缃戠害杞︽�绘暟锛堟湀搴﹀叏鐪� pin锛氭ā鏉縚缃戠害杞︽�绘暟.xlsx锛� */
+    @PostMapping("/wycTotal")
+    public Result<String> importWycTotal(@RequestParam("file") MultipartFile file,
+                                         @RequestParam("period") String period) {
+        try {
+            int count = importService.importWycTotal(file, period);
+            return Result.ok("缃戠害杞︽�绘暟瀵煎叆鎴愬姛, 鍏� " + count + " 鏈�");
+        } catch (Exception e) {
+            log.error("wycTotal import error", e);
+            return Result.error("瀵煎叆澶辫触: " + e.getMessage());
+        }
+    }
+
+    /** 缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺锛堟ā鏉縚缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx锛� */
+    @PostMapping("/wycOrder")
+    public Result<String> importWycOrder(@RequestParam("file") MultipartFile file,
+                                         @RequestParam("period") String period) {
+        try {
+            int count = importService.importWycOrder(file, period);
+            return Result.ok("缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺瀵煎叆鎴愬姛, 鍏� " + count + " 鏈�");
+        } catch (Exception e) {
+            log.error("wycOrder import error", e);
+            return Result.error("瀵煎叆澶辫触: " + e.getMessage());
+        }
+    }
+
     /** 鎶曡祫鏈堟姤锛堝叏鐪佹眹鎬诲ぇ琛級锛歝ategory=瀹㈣繍绔欏満/鐗╂祦鍥尯 */
     @PostMapping("/investment")
     public Result<String> importInvestment(@RequestParam("file") MultipartFile file,
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycOrderMonthly.java b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycOrderMonthly.java
new file mode 100644
index 0000000..db5e2c2
--- /dev/null
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycOrderMonthly.java
@@ -0,0 +1,47 @@
+package com.trafficaudit.dataimport.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/** 缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺鏈堝害杈撳叆锛堟簮锛氭ā鏉縚缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx 鏈堝害杈撳叆椤碉級 */
+@Data
+@TableName("wyc_order_monthly")
+public class WycOrderMonthly {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /** 鎶ヨ〃鏈� yyyy-MM */
+    private String reportPeriod;
+    /** B-E 鍏ㄧ渷 pin */
+    private Double pinK;
+    @TableField("pin_ck")
+    private Double pinCK;
+    private Double pinZ;
+    @TableField("pin_cz")
+    private Double pinCZ;
+    /** F 璁㈠崟鍚堣锛堝崟锛� */
+    private Double orderSum;
+    /** G-W 17 甯傚窞璁㈠崟锛屾寜 RegionUtil.cityList 椤哄簭 */
+    private Double orderWuhan;
+    private Double orderHuangshi;
+    private Double orderShiyan;
+    private Double orderYichang;
+    private Double orderXiangyang;
+    private Double orderEzhou;
+    private Double orderJingmen;
+    private Double orderXiaogan;
+    private Double orderJingzhou;
+    private Double orderHuanggang;
+    private Double orderXianning;
+    private Double orderSuizhou;
+    private Double orderEnshi;
+    private Double orderXiantao;
+    private Double orderQianjiang;
+    private Double orderTianmen;
+    private Double orderShennong;
+    private LocalDateTime createdAt;
+}
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycTotalMonthly.java b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycTotalMonthly.java
new file mode 100644
index 0000000..ff65cfb
--- /dev/null
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/entity/WycTotalMonthly.java
@@ -0,0 +1,30 @@
+package com.trafficaudit.dataimport.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/** 缃戠害杞︽�绘暟鏈堝害杈撳叆锛堟簮锛氭ā鏉縚缃戠害杞︽�绘暟.xlsx锛孊-E 涓哄叏鐪� pin锛� */
+@Data
+@TableName("wyc_total_monthly")
+public class WycTotalMonthly {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /** 鎶ヨ〃鏈� yyyy-MM */
+    private String reportPeriod;
+    /** 鍏ㄧ渷缃戠害杞﹀杩愰噺锛堜竾浜烘锛� */
+    private Double pinK;
+    /** 鍏朵腑鍩庡競鍐呭杩愰噺锛堜竾浜烘锛� */
+    @TableField("pin_ck")
+    private Double pinCK;
+    /** 鍏ㄧ渷缃戠害杞﹀懆杞噺锛堜竾浜哄叕閲岋級 */
+    private Double pinZ;
+    /** 鍏朵腑鍩庡競鍐呭懆杞噺锛堜竾浜哄叕閲岋級 */
+    @TableField("pin_cz")
+    private Double pinCZ;
+    private LocalDateTime createdAt;
+}
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycOrderMonthlyMapper.java b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycOrderMonthlyMapper.java
new file mode 100644
index 0000000..531dd82
--- /dev/null
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycOrderMonthlyMapper.java
@@ -0,0 +1,6 @@
+package com.trafficaudit.dataimport.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.trafficaudit.dataimport.entity.WycOrderMonthly;
+import org.apache.ibatis.annotations.Mapper;
+@Mapper
+public interface WycOrderMonthlyMapper extends BaseMapper<WycOrderMonthly> {}
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycTotalMonthlyMapper.java b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycTotalMonthlyMapper.java
new file mode 100644
index 0000000..4f52637
--- /dev/null
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/mapper/WycTotalMonthlyMapper.java
@@ -0,0 +1,6 @@
+package com.trafficaudit.dataimport.mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.trafficaudit.dataimport.entity.WycTotalMonthly;
+import org.apache.ibatis.annotations.Mapper;
+@Mapper
+public interface WycTotalMonthlyMapper extends BaseMapper<WycTotalMonthly> {}
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 50b64f8..4af3f35 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
@@ -18,6 +18,8 @@
 import com.trafficaudit.dataimport.entity.CityBusMonthly;
 import com.trafficaudit.dataimport.entity.CityTaxiMonthly;
 import com.trafficaudit.dataimport.entity.CityTaxiAuth;
+import com.trafficaudit.dataimport.entity.WycOrderMonthly;
+import com.trafficaudit.dataimport.entity.WycTotalMonthly;
 import com.trafficaudit.dataimport.entity.ScaleSplitTransport;
 import com.trafficaudit.dataimport.entity.TransportAuthVehicle;
 import com.trafficaudit.dataimport.entity.VehicleTrackMileage;
@@ -36,6 +38,8 @@
 import com.trafficaudit.dataimport.mapper.CityBusMonthlyMapper;
 import com.trafficaudit.dataimport.mapper.CityTaxiMonthlyMapper;
 import com.trafficaudit.dataimport.mapper.CityTaxiAuthMapper;
+import com.trafficaudit.dataimport.mapper.WycOrderMonthlyMapper;
+import com.trafficaudit.dataimport.mapper.WycTotalMonthlyMapper;
 import com.trafficaudit.dataimport.mapper.ScaleSplitTransportMapper;
 import com.trafficaudit.dataimport.mapper.TransportAuthVehicleMapper;
 import com.trafficaudit.dataimport.mapper.VehicleTrackMileageMapper;
@@ -162,6 +166,10 @@
     private CityTaxiMonthlyMapper cityTaxiMapper;
     @Resource
     private CityTaxiAuthMapper cityTaxiAuthMapper;
+    @Resource
+    private WycTotalMonthlyMapper wycTotalMapper;
+    @Resource
+    private WycOrderMonthlyMapper wycOrderMapper;
     @Resource
     private SqlSessionFactory sqlSessionFactory;
 
@@ -2704,6 +2712,155 @@
         return success;
     }
 
+
+    // ========== 缃戠害杞︽湀搴﹁緭鍏ュ鍏ワ紙鍏ㄧ渷 pin / 璁㈠崟锛� ==========
+
+    /** 缃戠害杞︽�绘暟鏈堝害杈撳叆锛氭ā鏉縚缃戠害杞︽�绘暟.xlsx锛坰heet1锛汚 鍒�=鏈堜唤鏃ユ湡锛汢=鍏ㄧ渷瀹㈣繍閲� C=鍏朵腑鍩庡競鍐� D=鍛ㄨ浆閲� E=鍏朵腑鍩庡競鍐呭懆杞噺锛夈�傛暣琛ㄦ寜鎶ヨ〃鏈熻鐩栥�� */
+    public synchronized int importWycTotal(MultipartFile file, String period) throws Exception {
+        Map<String, WycTotalMonthly> rows = new LinkedHashMap<>();
+        try (Workbook wb = WorkbookFactory.create(file.getInputStream())) {
+            Sheet sheet = wb.getSheetAt(0);
+            for (int r = 2; r <= sheet.getLastRowNum(); r++) {
+                Row row = sheet.getRow(r);
+                if (row == null) continue;
+                String rp = periodOfCell(row.getCell(0));
+                if (rp == null) continue;
+                double pk = dbl(row, 1), pck = dbl(row, 2), pz = dbl(row, 3), pcz = dbl(row, 4);
+                if (pk <= 0 && pck <= 0 && pz <= 0 && pcz <= 0) continue;
+                WycTotalMonthly item = new WycTotalMonthly();
+                item.setReportPeriod(rp);
+                item.setPinK(pk > 0 ? pk : null);
+                item.setPinCK(pck > 0 ? pck : null);
+                item.setPinZ(pz > 0 ? pz : null);
+                item.setPinCZ(pcz > 0 ? pcz : null);
+                rows.put(rp, item);
+            }
+        }
+        if (rows.isEmpty()) throw new RuntimeException("鏈瘑鍒埌鏈夋晥鏈堜唤琛岋細A 鍒楀簲涓烘棩鏈燂紙濡� 2026-07锛夛紝B-E 涓哄叏鐪佸杩愰噺/鍩庡競鍐�/鍛ㄨ浆閲�/鍩庡競鍐呭懆杞噺");
+        int ok = upsertWycTotal(rows);
+        log.info("WycTotal imported: {} periods ok={}", rows.size(), ok);
+        return ok;
+    }
+
+    /** 缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺锛氭ā鏉縚缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx 棣栦釜鏁版嵁 sheet锛圓=鏈堜唤锛汢-E=鍏ㄧ渷 pin锛汧=璁㈠崟鍚堣锛汫-W=17 甯傚窞璁㈠崟锛� */
+    public synchronized int importWycOrder(MultipartFile file, String period) throws Exception {
+        Map<String, WycOrderMonthly> rows = new LinkedHashMap<>();
+        try (Workbook wb = WorkbookFactory.create(file.getInputStream())) {
+            Sheet sheet = wb.getSheetAt(0);
+            int head = -1;
+            for (int r = 0; r <= Math.min(sheet.getLastRowNum(), 4); r++) {
+                Row row = sheet.getRow(r);
+                if (row == null) continue;
+                String a = getString(row, 0);
+                if (a != null && a.contains("鏈堜唤")) { head = r; break; }
+            }
+            if (head < 0) throw new RuntimeException("鏈壘鍒拌〃澶达細A 鍒楅渶鍚�滄湀浠解��");
+            for (int r = head + 1; r <= sheet.getLastRowNum(); r++) {
+                Row row = sheet.getRow(r);
+                if (row == null) continue;
+                String rp = periodOfCell(row.getCell(0));
+                if (rp == null) continue;
+                double pk = dbl(row, 1), pck = dbl(row, 2), pz = dbl(row, 3), pcz = dbl(row, 4), sum = dbl(row, 5);
+                double citySum = 0;
+                for (int k = 0; k < 17; k++) citySum += dbl(row, 6 + k);
+                if (pk <= 0 && pck <= 0 && pz <= 0 && pcz <= 0 && sum <= 0 && citySum <= 0) continue;
+                WycOrderMonthly it = new WycOrderMonthly();
+                it.setReportPeriod(rp);
+                it.setPinK(pk > 0 ? pk : null);
+                it.setPinCK(pck > 0 ? pck : null);
+                it.setPinZ(pz > 0 ? pz : null);
+                it.setPinCZ(pcz > 0 ? pcz : null);
+                if (sum <= 0 && citySum > 0) sum = citySum;
+                it.setOrderSum(sum > 0 ? sum : null);
+                it.setOrderWuhan(dblN(row, 6));
+                it.setOrderHuangshi(dblN(row, 7));
+                it.setOrderShiyan(dblN(row, 8));
+                it.setOrderYichang(dblN(row, 9));
+                it.setOrderXiangyang(dblN(row, 10));
+                it.setOrderEzhou(dblN(row, 11));
+                it.setOrderJingmen(dblN(row, 12));
+                it.setOrderXiaogan(dblN(row, 13));
+                it.setOrderJingzhou(dblN(row, 14));
+                it.setOrderHuanggang(dblN(row, 15));
+                it.setOrderXianning(dblN(row, 16));
+                it.setOrderSuizhou(dblN(row, 17));
+                it.setOrderEnshi(dblN(row, 18));
+                it.setOrderXiantao(dblN(row, 19));
+                it.setOrderQianjiang(dblN(row, 20));
+                it.setOrderTianmen(dblN(row, 21));
+                it.setOrderShennong(dblN(row, 22));
+                rows.put(rp, it);
+            }
+        }
+        if (rows.isEmpty()) throw new RuntimeException("鏈瘑鍒埌鏈夋晥鏈堜唤琛岋細A 鍒楀簲涓� yyyy-MM锛孊-E 鍏ㄧ渷 pin / F 鍚堣 / G-W 17 甯傚窞璁㈠崟");
+        int ok = upsertWyc(rows);
+        log.info("WycOrder imported: {} periods ok={}", rows.size(), ok);
+        return ok;
+    }
+
+    private int upsertWyc(Map<String, WycOrderMonthly> rows) {
+        int ok = 0, fail = 0;
+        for (WycOrderMonthly item : rows.values()) {
+            try {
+                wycOrderMapper.delete(new LambdaQueryWrapper<WycOrderMonthly>().eq(WycOrderMonthly::getReportPeriod, item.getReportPeriod()));
+                wycOrderMapper.insert(item);
+                recordBatch("缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺", "WYC_ORDER", item.getReportPeriod(), 1, 1, 0, null);
+                ok++;
+            } catch (Exception e) {
+                fail++;
+                log.error("WycOrder insert error period={}", item.getReportPeriod(), e);
+            }
+        }
+        return ok;
+    }
+
+    private int upsertWycTotal(Map<String, WycTotalMonthly> rows) {
+        int ok = 0, fail = 0;
+        for (WycTotalMonthly item : rows.values()) {
+            try {
+                wycTotalMapper.delete(new LambdaQueryWrapper<WycTotalMonthly>().eq(WycTotalMonthly::getReportPeriod, item.getReportPeriod()));
+                wycTotalMapper.insert(item);
+                recordBatch("缃戠害杞︽�绘暟", "WYC_TOTAL", item.getReportPeriod(), 1, 1, 0, null);
+                ok++;
+            } catch (Exception e) {
+                fail++;
+                log.error("WycTotal insert error period={}", item.getReportPeriod(), e);
+            }
+        }
+        return ok;
+    }
+
+    private String periodOfCell(Cell c) {
+        if (c == null) return null;
+        if (c.getCellType() == CellType.NUMERIC) {
+            try {
+                double v = c.getNumericCellValue();
+                if (v >= 40000 && v <= 60000) {
+                    java.util.Date d = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(v);
+                    java.text.SimpleDateFormat f = new java.text.SimpleDateFormat("yyyy-MM");
+                    return f.format(d);
+                }
+            } catch (Exception ignore) { }
+        }
+        String s = null;
+        try { s = c.getStringCellValue(); } catch (Exception ignore) { }
+        if (s != null) {
+            java.util.regex.Matcher m = java.util.regex.Pattern.compile("(\\d{4})[-/.骞碷(\\d{1,2})").matcher(s.trim());
+            if (m.find()) return String.format("%04d-%02d", Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)));
+        }
+        return null;
+    }
+
+    private double dbl(Row row, int idx) {
+        Double v = getDecimal(row, idx);
+        return v == null ? 0.0 : v;
+    }
+
+    private Double dblN(Row row, int idx) {
+        Double v = getDecimal(row, idx);
+        return (v == null || v <= 0) ? null : v;
+    }
+
     /** 杩愭斂鍑虹杞﹀競宸炴彁鍙栵細閬撹矾杩愯緭璇佸瓧鍙封啋妗f鍙封啋缁忚惀鏉冨彿鈫掍笟鎴峰湴鍧�锛屽彇 6 浣嶅尯鍒掍唬鐮� */
     private static final java.util.regex.Pattern TAXI_REGION_PAT =
         java.util.regex.Pattern.compile("(4290\\d{2}|42(?:0[1-9]|1[0-3]|28)\\d{2})");
@@ -3040,6 +3197,8 @@
             case "trackMileage": return new ImportResult(importTrackMileage(file, period), 0, new ArrayList<>());
             case "freightTurnover": return new ImportResult(importFreightTurnover(file, period), 0, new ArrayList<>());
             case "scaleSplit": return new ImportResult(importScaleSplit(file, period), 0, new ArrayList<>());
+            case "wycTotal": return new ImportResult(importWycTotal(file, period), 0, new ArrayList<>());
+            case "wycOrder": return new ImportResult(importWycOrder(file, period), 0, new ArrayList<>());
             default: throw new RuntimeException("涓嶆敮鎸佺殑瀵煎叆绫诲瀷锛�" + type);
         }
     }
diff --git a/traffic-audit-web/src/views/DataImport.vue b/traffic-audit-web/src/views/DataImport.vue
index f3e8b91..a36ee76 100644
--- a/traffic-audit-web/src/views/DataImport.vue
+++ b/traffic-audit-web/src/views/DataImport.vue
@@ -1,4 +1,4 @@
-<template>
+SKIP/CHECK (0): TYPE_LABELS upper <template>
   <el-container direction="vertical">
     <app-header title="浜ら�氱粺璁℃姤琛ㄥ鏍哥郴缁� - 鏁版嵁瀵煎叆"></app-header>
     <el-container>
@@ -134,10 +134,11 @@
   investCityPassenger: '甯傚窞鍗曡〃锛堝杩愮珯鍦猴級', investCityLogistics: '甯傚窞鍗曡〃锛堢墿娴佸洯鍖猴級',
   'INVEST_瀹㈣繍绔欏満_CITY': '甯傚窞鍗曡〃锛堝杩愮珯鍦猴級', 'INVEST_鐗╂祦鍥尯_CITY': '甯傚窞鍗曡〃锛堢墿娴佸洯鍖猴級',
   cityBus: '鍩庡競鍏氦鏈堟姤', cityTaxi: '宸℃父鍑虹鏈堟姤', cityTaxiAuth: '鍑虹杞﹁繍鏀胯溅杈�',
+  wycTotal: '缃戠害杞︽�绘暟', wycOrder: '缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺',
   H2032: 'H203-2鏈堟姤', H2031: 'H203-1鏃呭鏈堟姤', H204: 'H204鑳借�楀鎶�', PASSENGER_AUTH: '鏃呭杩愭斂杞﹁締鏁�',
   PASSENGER_INDIVIDUAL: '涓綋瀹㈣繍閲�/鍛ㄨ浆閲�', ENERGY_AUTH: '鑳借�楄溅杈嗚繍鏀夸俊鎭�', TRANSPORT_AUTH: '杩愭斂杞﹁締',
   TRACK_MILEAGE: '杞ㄨ抗閲岀▼', SCALE_SPLIT: '瑙勪笂瑙勪笅鎷嗗垎', FREIGHT_TURNOVER: '璐ц繍閲忓懆杞噺',
-  INVEST_SYSTEM: '鎶曡祫绯荤粺瀵煎嚭', CITY_BUS: '鍩庡競鍏氦鏈堟姤', CITY_TAXI: '宸℃父鍑虹鏈堟姤', CITY_TAXI_AUTH: '鍑虹杞﹁繍鏀胯溅杈�'
+  INVEST_SYSTEM: '鎶曡祫绯荤粺瀵煎嚭', CITY_BUS: '鍩庡競鍏氦鏈堟姤', CITY_TAXI: '宸℃父鍑虹鏈堟姤', CITY_TAXI_AUTH: '鍑虹杞﹁繍鏀胯溅杈�', WYC_TOTAL: '缃戠害杞︽�绘暟', WYC_ORDER: '缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺'
 }
 const BATCH_TYPE_MAP = {
   H2032: 'h2032', TRANSPORT_AUTH: 'transportAuth', TRACK_MILEAGE: 'trackMileage',
@@ -145,6 +146,7 @@
   H2031: 'passengerMonthly', PASSENGER_AUTH: 'passengerAuth', PASSENGER_INDIVIDUAL: 'passengerIndividual',
   H204: 'energyMonthly', ENERGY_AUTH: 'energyAuth',
   CITY_BUS: 'cityBus', CITY_TAXI: 'cityTaxi', CITY_TAXI_AUTH: 'cityTaxiAuth',
+  WYC_TOTAL: 'wycTotal', WYC_ORDER: 'wycOrder',
   INVEST_SYSTEM: 'investmentSystem'
 }
 export default {
@@ -187,7 +189,9 @@
           key: 'city', name: '鍩庡競瀹㈣繍', types: [
             { value: 'cityBus', label: '鍩庡競鍏叡浜ら�氭湀搴﹁繍钀ユ儏鍐�' },
             { value: 'cityTaxi', label: '宸℃父鍑虹姹借溅杩愯惀鏈嶅姟鎯呭喌鏈堟姤' },
-            { value: 'cityTaxiAuth', label: '鍑虹杞﹁繍鏀胯溅杈�' }
+            { value: 'cityTaxiAuth', label: '鍑虹杞﹁繍鏀胯溅杈�' },
+            { value: 'wycTotal', label: '缃戠害杞︽�绘暟' },
+            { value: 'wycOrder', label: '缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺' }
           ]
         },
         {
@@ -258,7 +262,9 @@
         investCityLogistics: '鈥旓紙鎵归噺鎵弿鐩綍锛屾棤闇�妯℃澘锛�',
         cityBus: '瀵煎叆_鍩庡競鍏叡浜ら�氭湀搴﹁繍钀ユ儏鍐碉紙YYYY骞碝鏈堬級.xls/.xlsx锛堜紒涓氱骇鏄庣粏锛屽彇鍏叡姹界數杞﹀瓧娈碉級',
         cityTaxi: '瀵煎叆_宸℃父鍑虹姹借溅杩愯惀鏈嶅姟鎯呭喌鏈堟姤锛圷YYY骞碝鏈堬級.xls锛堝競宸炵骇17琛岋級',
-        cityTaxiAuth: '瀵煎叆妯℃澘_鍑虹杞︿俊鎭�(杩愭斂杞﹁締淇℃伅).xlsx锛堣溅杈嗙骇鏄庣粏锛岀敤浜庤繍钀ヨ溅鏁板姣旓級'
+        cityTaxiAuth: '瀵煎叆妯℃澘_鍑虹杞︿俊鎭�(杩愭斂杞﹁締淇℃伅).xlsx锛堣溅杈嗙骇鏄庣粏锛岀敤浜庤繍钀ヨ溅鏁板姣旓級',
+        wycTotal: '妯℃澘_缃戠害杞︽�绘暟.xlsx锛圓鍒�=鏈堜唤锛孊-E=鍏ㄧ渷瀹㈣繍閲�/鍩庡競鍐�/鍛ㄨ浆閲�/鍩庡競鍐呭懆杞噺锛�',
+        wycOrder: '妯℃澘_缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx锛圓鍒�=鏈堜唤锛孊-E=鍏ㄧ渷pin锛孎=璁㈠崟鍚堣锛孏-W=17甯傚窞璁㈠崟锛�'
       }
       return map[this.importType] || ''
     },
@@ -277,6 +283,8 @@
         cityBus: '鍩庡競瀹㈣繍/鐢熸垚_鍩庡競鍏氦瀹㈣繍閲忓垎甯傚窞鏄庣粏.xlsx',
         cityTaxi: '鍩庡競瀹㈣繍/鐢熸垚_宸℃父鍑虹瀹㈣繍閲忓垎甯傚窞鏄庣粏.xlsx',
         cityTaxiAuth: '鍩庡競瀹㈣繍/瀵煎叆妯℃澘_鍑虹杞︿俊鎭�(杩愭斂杞﹁締淇℃伅).xlsx',
+        wycTotal: '鍩庡競瀹㈣繍/妯℃澘_缃戠害杞︽�绘暟.xlsx',
+        wycOrder: '鍩庡競瀹㈣繍/妯℃澘_缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx',
         investment: '鎶曡祫/杈撳叆/瀹㈣繍锛堝杩愮珯锛�/鏇存柊_7鏈堝杩愮珯鎶曡祫鏄庣粏琛紙甯傚窞姹囨�诲ぇ琛紝缁欓瀵硷級.xlsx',
         investmentLogistics: '鎶曡祫/杈撳叆/鐗╂祦锛堢墿娴佸洯鍖猴級/鏇存柊_7鏈堢墿娴佺珯鍦烘姇璧勬槑缁�.xls',
         investmentSystem: '鎶曡祫/妯℃澘_鏌ヨ缁撴灉(鎶曡祫绯荤粺-瀹㈣繍+鐗╂祦 2026.7).xls'
@@ -314,7 +322,9 @@
         investmentSystem: '/import/investmentSystem',
         cityBus: '/import/cityBus',
         cityTaxi: '/import/cityTaxi',
-        cityTaxiAuth: '/import/cityTaxiAuth'
+        cityTaxiAuth: '/import/cityTaxiAuth',
+        wycTotal: '/import/wycTotal',
+        wycOrder: '/import/wycOrder'
       }
       return map[t] || ''
     },

--
Gitblit v1.9.1