From 95a1f46104dadf824586498aa139a1acaf5fc77c Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期四, 10 九月 2026 08:58:55 +0800
Subject: [PATCH] feat: 数据导入页清空增强——支持按数据类型清空(后端 types 参数 + 弹窗多选),清空按钮移出“刷新”行改独立危险操作区防误触(含功能测试报告与工作日结)

---
 traffic-audit-web/src/views/DataImport.vue                                                          |  100 ++++++++++---
 docs/功能测试报告/功能测试报告_导入清空按类型与按钮防误触_2026-09-10.md                                                      |   42 ++++++
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/service/DataImportService.java       |  223 ++++++++++++++++++++++++++++++-
 docs/工作日结/工作日结_2026-09-10.md                                                                        |   22 +++
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataImportController.java |   19 ++
 5 files changed, 369 insertions(+), 37 deletions(-)

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\257\274\345\205\245\346\270\205\347\251\272\346\214\211\347\261\273\345\236\213\344\270\216\346\214\211\351\222\256\351\230\262\350\257\257\350\247\246_2026-09-10.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\257\274\345\205\245\346\270\205\347\251\272\346\214\211\347\261\273\345\236\213\344\270\216\346\214\211\351\222\256\351\230\262\350\257\257\350\247\246_2026-09-10.md"
new file mode 100644
index 0000000..149f7da
--- /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\257\274\345\205\245\346\270\205\347\251\272\346\214\211\347\261\273\345\236\213\344\270\216\346\214\211\351\222\256\351\230\262\350\257\257\350\247\246_2026-09-10.md"
@@ -0,0 +1,42 @@
+# 鍔熻兘娴嬭瘯鎶ュ憡锛氭暟鎹鍏ラ〉鈥滄竻绌烘暟鎹�濆寮猴紙鎸夌被鍨嬫竻绌� + 鎸夐挳绉诲嚭鍒锋柊琛岄槻璇Е锛� 2026-09-10
+
+## 鍔熻兘璇存槑
+- 鏁版嵁瀵煎叆椤靛彸渚р�滃鍏ヨ繘搴︹�濅晶鏍忓湪鍘熲�滃埛鏂扳�濇梺鍘绘帀鈥滄竻绌衡�濓紝鏀逛负鍦ㄤ晶鏍忔爣棰樿涓嬫柟鏂板鐙珛鍗遍櫓鎿嶄綔鍖猴紙娴呯孩搴� + 杈规锛夛紝鍐呭惈 `el-button type="danger" plain` 鐨勨�滄竻绌烘暟鎹�︹�濇寜閽笌璇存槑鈥滄寜鎶ヨ〃鏈熸竻搴擄紝鐢ㄤ簬鏁存湀閲嶅鈥濓紝涓庘�滃埛鏂扳�濈墿鐞嗗垎寮�锛岄檷浣庤瑙︺��
+- 鏂板娓呯┖寮圭獥锛氭樉绀哄綋鍓嶆姤琛ㄦ湡锛岄�夋嫨鈥滄竻绌鸿鎶ヨ〃鏈熷叏閮ㄥ凡瀵煎叆鏁版嵁鈥濇垨鈥滃彧娓呯┖鎸囧畾绫诲瀷鈥濓紱閫夌被鍨嬫椂鐢� `el-select multiple filterable`锛屾寜鍒嗙粍鍒楀嚭鍙�夌被鍨嬪苟鏍囨敞鈥滐紙宸插鍏� N 琛�/鏈鍏ワ級鈥濓紱搴曢儴绾㈣壊璀︾ず璇鏄庝細鍚屾鍒犻櫎瀹℃牳缁撴灉銆佸凡瀹℃牳鏍囪涓庡鍏ユ壒娆★紙鎶曡祫椤圭洰涓绘。淇濈暀锛変笖涓嶅彲鎾ら攢銆�
+- 鍚庣 `POST /api/import/clear` 澧炲姞鍙�夊弬鏁� `types`锛堥�楀彿鍒嗛殧锛夛細涓虹┖ = 娓呯┖璇ユ姤琛ㄦ湡鍏ㄩ儴绫诲瀷锛堝師琛屼负涓嶅彉锛夛紱闈炵┖ = 鍙竻绌烘寚瀹氭暟鎹被鍨嬶紝骞跺悓姝ユ竻鐞嗗叾鍏宠仈鐨� audit_result / audit_run / import_batch銆�
+
+## 娑夊強鏀瑰姩
+- 鍚庣 `DataImportService`锛歚clearPeriod(period, types)` 閲嶈浇锛涙柊澧為潤鎬佹槧灏� `CLEAR_TYPE_TO_OP`锛堢被鍨嬧啋鏁版嵁琛ㄦ搷浣滈敭锛屽悓琛ㄥ綊骞跺幓閲嶏級銆乣CLEAR_TYPE_TO_AUDIT`锛堢被鍨嬧啋瀹℃牳瑙勫垯绫诲瀷锛夈�乣CLEAR_TYPE_TO_BATCH`锛堢被鍨嬧啋importType锛夛紱鏂板 `clearTypeData(op, period)` 鍒嗘淳涓� `deleteInvestmentMonthly(period, category)`锛堟姇璧勬湀搴︽寜椤圭洰绫诲埆杩囨护锛屼粎鍒犳湰鏈熸槑缁嗭紝鎶曡祫涓绘。淇濈暀锛夈�傝繑鍥炲�兼柊澧� `scope` 涓� `types`锛屼究浜庡墠绔彁绀烘竻绌鸿寖鍥淬��
+- 鍚庣 `DataImportController`锛歚clearData` 澧炲姞 `types` 鍙傛暟瑙f瀽锛堢┖涓�/绌洪」蹇界暐锛夈��
+- 鍓嶇 `DataImport.vue`锛氱Щ闄� `.side-head-btns` 涓庢棫 `clearPeriodData()`锛涙柊澧� `.side-danger` 鍗遍櫓鎿嶄綔鍖恒�佹竻绌哄脊绐椼�乣openClearDialog()/clearableGroups()/confirmClear()` 涓� `clearDialog/clearScope/clearTypes` 鐘舵�侊紱纭鍚庡啀璧颁竴娆� `$confirm` 浜屾纭锛屾垚鍔熸彁绀哄甫鍒犻櫎琛屾暟銆�
+
+## 娴嬭瘯鐜
+- 鍚庣锛歵raffic-audit-server 8090锛堝惈鏈鏀瑰姩锛沗start-dev.ps1` 鍚姩锛孭ID 21884锛屽惎鍔ㄦ椂闂� 2026-09-10 08:54:02锛屽姞杞� `target/classes` 鏈�鏂扮紪璇戜骇鐗╋級銆�
+- 鍓嶇锛歵raffic-audit-web 8080 dev锛宍frontend.log` 鏈�杩戜竴娆� `Compiled successfully in 347ms`锛�08:53:29锛夛紝鐑洿鏂板凡鐢熸晥銆�
+- 鏁版嵁搴擄細鏈満 MySQL `localhost:3308/traffic_audit`锛宮ysql CLI 鐩存煡鏍稿锛涚櫥褰曡处鍙� `admin/123456`銆�
+- 娴嬭瘯鏁版嵁锛氫竴娆℃�ф祴璇曟湡 `2099-01 / 2099-02`锛屼娇鐢� `docs/璐ц繍闇�瀵煎叆鐨勬暟鎹�/璐ц繍/2026骞�1-7鏈堟姤/閬撹矾璐х墿杩愯緭鏈堝害鐢熶骇鎯呭喌锛�2026骞�6鏈堬級.xls`锛�636 琛岋級涓� 2026-07 鍩庡競鍏氦鏍锋湰锛涚湡瀹炴湀浠戒粎鍋氬洖褰掑姣旓紝涓嶈鍐欏叆鎴栧垹闄ゃ��
+
+## 鐢ㄤ緥琛�
+| # | 鐢ㄤ緥 | 杈撳叆 | 棰勬湡 | 瀹為檯 | 缁撹 |
+|---|---|---|---|---|---|
+| 1 | 缂栬瘧 | `mvn -o -q compile` | 閫氳繃 | 鏃犳姤閿� | 閫氳繃 |
+| 2 | 姝e悜-鎸夌被鍨嬫竻绌� | `POST /import/clear?period=2099-01&types=h2032` | 鍙垹 h2032 鍙婂叾 H2032 瀹℃牳缁撴灉/鎵规 | dataRows=636銆乤uditRows=31銆乤uditRunRows=1銆乥atchRows=1锛汥B 鏍稿 h2032=0銆丠2032 瑙勫垯瀹℃牳缁撴灉=0銆乤udit_run(H2032)=0銆佹壒娆�(H2032)=0 | 閫氳繃 |
+| 3 | 闅旂鎬�-鍏跺畠绫诲瀷涓嶅彈褰卞搷 | 鍚屼笂锛屾竻 h2032 鍚庢煡 cityBus | cityBus 鏁版嵁涓庡鏍�/鎵规淇濈暀 | cityBus 涓氬姟 142 琛屻�丆ITY_BUS 瀹℃牳 53 琛屻�乤udit_run(CITY_BUS)=1銆佹壒娆�(CITY_BUS)=1 鍧囦繚鐣� | 閫氳繃 |
+| 4 | 闅旂鎬�-鍏跺畠鎶ヨ〃鏈熶笉鍙楀奖鍝� | 鍚屼笂锛屾煡 2099-02 | 2099-02 鏁版嵁涓嶅彈褰卞搷 | 2099-02 鏁版嵁瀹屽ソ | 閫氳繃 |
+| 5 | 璐熷悜-闈炴硶绫诲瀷 | `types=notAType` | 鎷掔粷骞舵彁绀� | HTTP 500锛宍娓呯┖澶辫触: 鏈寚瀹氭湁鏁堢殑鏁版嵁绫诲瀷` | 閫氳繃 |
+| 6 | 杈圭晫-鏈夋晥+鏈煡娣峰悎 | `types=cityBus,notAType` | 蹇界暐鏈煡銆佹寜鏈夋晥绫诲瀷鎵ц | 鎴愬姛锛岃繑鍥� `scope=types, types=[cityBus,notAType]`锛屽垹闄� 0 琛岋紙璇ユ湡鏃犳暟鎹級 | 閫氳繃 |
+| 7 | 杈圭晫-绌虹被鍨嬪垪琛� | 涓嶄紶 `types` | 鎸夊叏閮ㄧ被鍨嬫竻绌猴紙鍘熻涓猴級 | 鎴愬姛锛宍scope=all` | 閫氳繃 |
+| 8 | 鎶曡祫鎸夌被鍒� | 鎻掑叆 2099-01 瀹㈣繍绔欏満/鐗╂祦鍥尯娴嬭瘯琛屽悗鍒嗗埆娓呯┖ | 鍙垹瀵瑰簲绫诲埆锛屾姇璧勪富妗d繚鐣� | `types=investment` 鍙垹瀹㈣繍绔欏満銆乣types=investmentLogistics` 鍙垹鐗╂祦鍥尯锛宍investment_project` 涓绘。淇濈暀 | 閫氳繃 |
+| 9 | UI-鎸夐挳浣嶇疆 | 鎵撳紑鏁版嵁瀵煎叆椤碉紝灞曞紑鈥滃鍏ヨ繘搴︹�� | 鈥滃埛鏂扳�濇梺鏃犳竻绌猴紱娓呯┖鎸夐挳鍦ㄧ嫭绔嬬孩鑹插嵄闄╁尯 | 涓庨鏈熶竴鑷达紙鍙闂�ф爲鍙鍒扳�滄竻绌烘暟鎹�︹�濇寜閽笌鎻愮ず鏂囨锛� | 閫氳繃 |
+| 10 | UI-寮圭獥閫夐」 | 鐐光�滄竻绌烘暟鎹�︹�� | 寮圭獥鍚姤琛ㄦ湡銆佸叏閮�/鎸囧畾绫诲瀷鍗曢�夈�佺被鍨嬩笅鎷夊甫瀵煎叆鐘舵�� | 閫変腑鈥滈亾璺揣鐗╄繍杈撴湀搴︾敓浜ф儏鍐碉紙宸插鍏� 636 琛岋級鈥濓紝閫夐」鏍囩涓庣姸鎬佷竴鑷� | 閫氳繃 |
+| 11 | UI-纭娓呯┖ | 閫変腑 h2032 鍚庣偣鈥滅‘璁ゆ竻绌衡�� | 浜屾纭 鈫� 鎴愬姛鎻愮ず鍚鏁般�佽繘搴﹀洖鈥滄湭瀵煎叆鈥� | 鎻愮ず鈥滃凡娓呯┖ 2099-01 鏁版嵁锛氫笟鍔℃暟鎹� 636 琛屻�佸鏍哥粨鏋� 0 琛屻�佸鍏ユ壒娆� 1 鏉★紝鍙互閲嶆柊瀵煎叆鈥濓紝杩涘害鍥炩�滄湭瀵煎叆鈥� | 閫氳繃 |
+| 12 | 鍥炲綊-鐪熷疄鏈堜唤 | 娓呯┖鍓嶅悗瀵规瘮 | 鏃犲彉鍖� | 2099-01 娈嬬暀=0锛�2026-09=636銆�2026-07=636銆�2025-07=664 鏈彉锛涚湡瀹炴壒娆℃�绘暟 239 鏈彉 | 閫氳繃 |
+
+## 鍙戠幇鐨勯棶棰樹笌澶勭疆
+- 鏃犲姛鑳芥�х己闄枫�傛祴璇曟湡鏁版嵁鍦ㄩ獙璇佺粨鏉熷悗宸插叏閮ㄦ竻闄わ紝鏈畫鐣欍��
+- 璇存槑锛堜繚鐣欑壒鎬э級锛氫竴娆℃竻绌轰細鍒犻櫎璇ユ姤琛ㄦ湡鈥滃叏閮ㄧ被鍨嬧�濈殑涓氬姟鏁版嵁鍙婂鏍哥粨鏋�/宸插鏍告爣璁�/瀵煎叆鎵规锛屽脊绐楀凡鐢ㄧ孩鑹叉枃妗堟彁绀轰笉鍙挙閿�锛涘彧鎯虫竻鍗曚竴绫诲瀷鏃朵娇鐢ㄢ�滃彧娓呯┖鎸囧畾绫诲瀷鈥濓紝鏈鍏ョ殑绫诲瀷浠嶅彲鍕鹃�変絾涓嶄骇鐢熷垹闄ゃ��
+- 鐜澶囨敞锛氭湰鏈哄簱 `admin` 瀵嗙爜涓� `123456`锛坄admin123` 鍦ㄦ湰鏈轰笉鍖归厤锛夈��
+
+## 缁撹
+- 閫氳繃銆傗�滄竻绌烘暟鎹�︹�濆凡浠庘�滃埛鏂扳�濇梺绉诲嚭骞跺仛瑙嗚闅旂锛屽脊绐楁敮鎸佹寜鏁存湡鎴栨寜绫诲瀷娓呯┖锛屾帴鍙f寜鑼冨洿绮剧‘鍒犻櫎涓氬姟鏁版嵁銆佸鏍哥粨鏋溿�佸凡瀹℃牳鏍囪涓庡鍏ユ壒娆★紝涓斿鍏跺畠绫诲瀷銆佸叾瀹冩姤琛ㄦ湡涓庣湡瀹炴湀浠介浂褰卞搷銆�
+- 寰呯敤鎴峰湪鑷繁娴忚鍣ㄩ獙鏀朵竴娆℃寜閽綅缃笌寮圭獥鏂囨銆�
diff --git "a/docs/\345\267\245\344\275\234\346\227\245\347\273\223/\345\267\245\344\275\234\346\227\245\347\273\223_2026-09-10.md" "b/docs/\345\267\245\344\275\234\346\227\245\347\273\223/\345\267\245\344\275\234\346\227\245\347\273\223_2026-09-10.md"
index 8f3b282..9937a3c 100644
--- "a/docs/\345\267\245\344\275\234\346\227\245\347\273\223/\345\267\245\344\275\234\346\227\245\347\273\223_2026-09-10.md"
+++ "b/docs/\345\267\245\344\275\234\346\227\245\347\273\223/\345\267\245\344\275\234\346\227\245\347\273\223_2026-09-10.md"
@@ -19,5 +19,25 @@
 - 寰呯敤鎴峰疄闄呮祻瑙堝櫒楠屾敹鈥滄竻绌衡�濇寜閽紙寤鸿鍏堢‘璁ゆ墍閫夋姤琛ㄦ湡涓庡浠斤級锛涘闇�鍙竻鏌愪竴鏁版嵁绫诲瀷锛屽彲鍚庣画鍋氣�滄寜绫诲瀷娓呯┖鈥濄��
 - 娌跨敤鏄ㄦ棩鏈姩寰呭姙锛氭眹鎬诲ぇ琛� M3锛堢綉绾﹁溅鍙拌处鍙栨暟銆佽揣杩愰〉 FreightCalc 瑙勪笂/瑙勪笅銆佸煄甯傚杩�/涓彛寰勫悎鎴愰〉锛変笌鈥�9 鏈�+鏃犳瘝鐗堣嚜鍔ㄦ墿鍒椻�濓紱8 鏈堜粛缂� 4 绫绘簮鏁版嵁琛ㄨ锛坒reight_turnover_import銆乻cale_split_transport銆乸assenger_individual_monthly銆佺綉绾﹁溅鎷嗗垎杈撳叆锛夈��
 
+## 涓嬪崍锛�2026-09-10锛夋竻绌哄姛鑳藉寮猴細鏀寔鎸夌被鍨嬫竻绌� + 娓呯┖鎸夐挳绉诲嚭鈥滃埛鏂扳�濋槻璇Е
+
+### 瀹屾垚鍐呭
+- 鐢ㄦ埛鍙嶉鈥滄竻绌烘斁鍦ㄥ埛鏂版梺杈规�曡瑙︹�濓紝涓旈渶瑕佽兘鍙竻鏌愪竴鏁版嵁绫诲瀷锛氭妸娓呯┖浠庝晶鏍忔爣棰樿锛堝埛鏂版梺锛夌Щ闄わ紝鏀瑰埌鏍囬琛屼笅鏂圭嫭绔嬬孩鑹插嵄闄╂搷浣滃尯锛堟祬绾㈠簳 + 杈规锛屸�滄竻绌烘暟鎹�︹�濇寜閽� + 鎻愮ず鈥滄寜鎶ヨ〃鏈熸竻搴擄紝鐢ㄤ簬鏁存湀閲嶅鈥濓級锛屼笌鍒锋柊鐗╃悊闅斿紑銆�
+- 鏂板娓呯┖寮圭獥锛氬崟閫夆�滄竻绌哄叏閮� / 鍙竻绌烘寚瀹氱被鍨嬧�濓紝鎸囧畾绫诲瀷鐢ㄥ閫変笅鎷夊苟鎸夊垎缁勫垪鍑恒�佹爣绛惧甫鈥滐紙宸插鍏� N 琛�/鏈鍏ワ級鈥濓紱搴曢儴绾㈣壊璀︾ず璇存槑浼氬悓姝ュ垹瀹℃牳缁撴灉銆佸凡瀹℃牳鏍囪銆佸鍏ユ壒娆★紙鎶曡祫椤圭洰涓绘。淇濈暀锛変笖涓嶅彲鎾ら攢锛涚‘璁ゅ墠鍐嶈蛋涓�娆′簩娆$‘璁ゃ��
+- 鍚庣 `POST /api/import/clear` 澧炲姞鍙�� `types`锛堥�楀彿鍒嗛殧锛夛細绌�=鏁存湡鍏ㄦ竻锛堝師琛屼负涓嶅彉锛夛紝闈炵┖=鍙竻鎸囧畾绫诲瀷锛屽苟鍚屾娓呯悊鍏宠仈 audit_result/audit_run/import_batch锛涜繑鍥炲�煎鍔� `scope` 涓� `types`銆傛柊澧炵被鍨嬧啋琛�/瀹℃牳绫诲瀷/鎵规绫诲瀷涓夊紶闈欐�佹槧灏勪笌 `clearTypeData` 鍒嗘淳锛屾姇璧勬湀搴︽寜椤圭洰绫诲埆杩囨护锛堜富妗d繚鐣欙級銆�
+
+### 娴嬭瘯缁撴灉鎽樿
+- 鐢ㄤ竴娆℃�ф祴璇曟湡 2099-01/2099-02 楠岃瘉锛氭竻 h2032 鈫� dataRows=636銆乤uditRows=31銆乤uditRunRows=1銆乥atchRows=1锛孌B 鏍稿鍥涜〃瀵瑰簲璁板綍鍏� 0锛涘悓鏈熺殑 cityBus 涓氬姟 142 琛屻�丆ITY_BUS 瀹℃牳 53 琛屻�乤udit_run 涓庢壒娆″潎淇濈暀锛�2099-02 鏁版嵁涓嶅彈褰卞搷銆�
+- 璐熷悜锛歚types=notAType` 鈫� 500鈥滄湭鎸囧畾鏈夋晥鐨勬暟鎹被鍨嬧�濓紱鏈夋晥+鏈煡娣峰悎 鈫� 蹇界暐鏈煡鎸夋湁鏁堟墽琛岋紱涓嶄紶 types 鈫� 鏁存湡鍏ㄦ竻銆�
+- 鎶曡祫绫诲埆锛歚types=investment` 鍙垹瀹㈣繍绔欏満銆乣types=investmentLogistics` 鍙垹鐗╂祦鍥尯锛屾姇璧勪富妗d繚鐣欍��
+- UI 瀹炴祴锛堝簲鐢ㄥ唴娴忚鍣紝admin 鐧诲綍锛夛細鈥滃埛鏂扳�濇梺宸叉棤娓呯┖锛涙柊鍗遍櫓鍖烘寜閽笌寮圭獥鏂囨姝e父锛涢�変腑鈥滈亾璺揣鐗╄繍杈撴湀搴︾敓浜ф儏鍐碉紙宸插鍏� 636 琛岋級鈥濈‘璁ゅ悗鎻愮ず鈥滃凡娓呯┖ 2099-01 鏁版嵁锛氫笟鍔℃暟鎹� 636 琛屻�佸鏍哥粨鏋� 0 琛屻�佸鍏ユ壒娆� 1 鏉★紝鍙互閲嶆柊瀵煎叆鈥濓紝杩涘害鍥炩�滄湭瀵煎叆鈥濄��
+- 鍥炲綊锛氭祴璇曟湡鏃犳畫鐣欙紝鐪熷疄鏈堜唤 2026-09=636銆�2026-07=636銆�2025-07=664 涓庣湡瀹炴壒娆℃�绘暟 239 鍧囨湭鍙樸��
+- 鍚庣 `mvn -o -q compile` 閫氳繃锛屾湇鍔″凡閲嶅惎锛圥ID 21884锛�08:54 鍚姩锛夛紱鍓嶇 dev `Compiled successfully`銆�
+- 娴嬭瘯鎶ュ憡锛歞ocs/鍔熻兘娴嬭瘯鎶ュ憡/鍔熻兘娴嬭瘯鎶ュ憡_瀵煎叆娓呯┖鎸夌被鍨嬩笌鎸夐挳闃茶瑙2026-09-10.md銆�
+
+### 閬楃暀闂涓庡緟鍔�
+- 寰呯敤鎴峰湪鑷繁娴忚鍣ㄩ獙鏀舵柊鎸夐挳浣嶇疆涓庡脊绐楁枃妗堬紱濡備粛瑙夊緱鍗遍櫓鍖哄お鏄剧溂鍙啀鏀惰繘鈥滄洿澶氭搷浣溾�濇姌鍙犮��
+- 娌跨敤鏈姩寰呭姙锛氭眹鎬诲ぇ琛� M3锛堢綉绾﹁溅鍙拌处鍙栨暟銆佽揣杩愰〉 FreightCalc 瑙勪笂/瑙勪笅銆佸煄甯傚杩�/涓彛寰勫悎鎴愰〉锛変笌鈥�9 鏈�+鏃犳瘝鐗堣嚜鍔ㄦ墿鍒椻�濓紱8 鏈堜粛缂� 4 绫绘簮鏁版嵁琛ㄨ锛坒reight_turnover_import銆乻cale_split_transport銆乸assenger_individual_monthly銆佺綉绾﹁溅鎷嗗垎杈撳叆锛夈��
+
 ## 闄勶細鎻愪氦
-- 鏈鏀瑰姩 3 涓唬鐮佹枃浠� + 鏈姤鍛婁笌鏃ョ粨锛屾寜瑙勮寖鍏� `git fetch gitea/origin` 瀵规瘮鍚堝苟锛屽啀 commit 骞跺弻绔帹閫侊紙gitea main銆佷釜浜� gitee master锛夈��
+- 鏈鏀瑰姩 3 涓唬鐮佹枃浠� + 鍔熻兘娴嬭瘯鎶ュ憡涓庢棩缁擄紝鎸夎鑼冨厛 `git fetch gitea/origin` 瀵规瘮鍚堝苟锛屽啀 commit 骞跺弻绔帹閫侊紙gitea main銆佷釜浜� gitee master锛夈��
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 d8217b5..54e09c2 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
@@ -443,14 +443,25 @@
         return Result.ok(result);
     }
 
-    /** 娓呯┖鎸囧畾鎶ヨ〃鏈熷叏閮ㄥ凡瀵煎叆鏁版嵁涓庡鏍哥粨鏋滐紙鏁版嵁瀵煎叆椤�"娓呯┖"鎸夐挳璋冪敤锛夛紝渚夸簬鏁存湀閲嶆柊瀵煎叆 */
+    /**
+     * 娓呯┖鎸囧畾鎶ヨ〃鏈熷凡瀵煎叆鏁版嵁涓庡鏍哥粨鏋滐紙鏁版嵁瀵煎叆椤�"娓呯┖鏁版嵁"鍏ュ彛璋冪敤锛夛紝渚夸簬鏁存湀閲嶆柊瀵煎叆銆�
+     * types 涓虹┖琛ㄧず娓呯┖璇ユ姤琛ㄦ湡鍏ㄩ儴绫诲瀷锛涘惁鍒欏彧娓呯┖鎸囧畾鏁版嵁绫诲瀷锛堥�楀彿鍒嗛殧锛屽 h2032,cityBus锛夈��
+     */
     @PostMapping("/clear")
-    public Result<Map<String, Object>> clearData(@RequestParam("period") String period) {
+    public Result<Map<String, Object>> clearData(@RequestParam("period") String period,
+                                                 @RequestParam(value = "types", required = false) String types) {
         try {
-            Map<String, Object> stats = importService.clearPeriod(period);
+            List<String> typeList = new java.util.ArrayList<>();
+            if (types != null) {
+                for (String t : types.split(",")) {
+                    String s = t.trim();
+                    if (!s.isEmpty()) typeList.add(s);
+                }
+            }
+            Map<String, Object> stats = importService.clearPeriod(period, typeList);
             return Result.ok(stats);
         } catch (Exception e) {
-            log.error("clear period {} error", period, e);
+            log.error("clear period {} types {} error", period, types, e);
             return Result.error("娓呯┖澶辫触: " + e.getMessage());
         }
     }
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 3aa4d32..e34a275 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
@@ -1317,13 +1317,100 @@
         }
     }
 
-    /** 娓呯┖鎸囧畾鎶ヨ〃鏈熷叏閮ㄥ凡瀵煎叆鏁版嵁涓庡鏍哥粨鏋滐紙鍚鍏ユ壒娆°�佸鏍搁�氳繃鏍囪锛夛紝鐢ㄤ簬鏁存湀閲嶅锛涙姇璧勯」鐩富妗d繚鐣� */
+    /** 鏀寔鈥滄寜绫诲瀷娓呯┖鈥濈殑鏁版嵁绫诲瀷 -> 鏁版嵁琛ㄦ搷浣滈敭锛堝悓琛ㄥ悓绫诲埆褰掑苟锛岄伩鍏嶉噸澶嶅垹闄わ級 */
+    private static final Map<String, String> CLEAR_TYPE_TO_OP = new LinkedHashMap<>();
+    /** 鏁版嵁绫诲瀷 -> 鍏宠仈瀹℃牳瑙勫垯绫诲瀷锛堝悓姝ユ竻闄ゅ鏍哥粨鏋滀笌宸插鏍告爣璁帮級 */
+    private static final Map<String, String[]> CLEAR_TYPE_TO_AUDIT = new HashMap<>();
+    /** 鏁版嵁绫诲瀷 -> 鍏宠仈瀵煎叆鎵规 importType锛堝悓姝ユ竻闄ゅ鍏ユ壒娆¤褰曪級 */
+    private static final Map<String, String[]> CLEAR_TYPE_TO_BATCH = new HashMap<>();
+
+    static {
+        CLEAR_TYPE_TO_OP.put("h2032", "H2032");
+        CLEAR_TYPE_TO_OP.put("transportAuth", "TRANSPORT_AUTH");
+        CLEAR_TYPE_TO_OP.put("trackMileage", "TRACK_MILEAGE");
+        CLEAR_TYPE_TO_OP.put("scaleSplit", "SCALE_SPLIT");
+        CLEAR_TYPE_TO_OP.put("freightTurnover", "FREIGHT_TURNOVER");
+        CLEAR_TYPE_TO_OP.put("passengerMonthly", "H2031");
+        CLEAR_TYPE_TO_OP.put("passengerAuth", "PASSENGER_AUTH");
+        CLEAR_TYPE_TO_OP.put("passengerIndividual", "PASSENGER_INDIVIDUAL");
+        CLEAR_TYPE_TO_OP.put("energyMonthly", "H204");
+        CLEAR_TYPE_TO_OP.put("energyAuth", "ENERGY_AUTH");
+        CLEAR_TYPE_TO_OP.put("investment", "INVEST_MONTHLY_PASSENGER");
+        CLEAR_TYPE_TO_OP.put("investCityPassenger", "INVEST_MONTHLY_PASSENGER");
+        CLEAR_TYPE_TO_OP.put("investmentLogistics", "INVEST_MONTHLY_LOGISTICS");
+        CLEAR_TYPE_TO_OP.put("investCityLogistics", "INVEST_MONTHLY_LOGISTICS");
+        CLEAR_TYPE_TO_OP.put("investmentSystem", "INVEST_SYSTEM");
+        CLEAR_TYPE_TO_OP.put("cityBus", "CITY_BUS");
+        CLEAR_TYPE_TO_OP.put("cityTaxi", "CITY_TAXI");
+        CLEAR_TYPE_TO_OP.put("cityTaxiAuth", "CITY_TAXI_AUTH");
+        CLEAR_TYPE_TO_OP.put("wycTotal", "WYC_TOTAL");
+        CLEAR_TYPE_TO_OP.put("wycOrder", "WYC_ORDER");
+
+        CLEAR_TYPE_TO_AUDIT.put("h2032", new String[]{"H2032"});
+        CLEAR_TYPE_TO_AUDIT.put("transportAuth", new String[]{"H2032"});
+        CLEAR_TYPE_TO_AUDIT.put("trackMileage", new String[]{"H2032"});
+        CLEAR_TYPE_TO_AUDIT.put("scaleSplit", new String[]{"H2032"});
+        CLEAR_TYPE_TO_AUDIT.put("freightTurnover", new String[]{"H2032"});
+        CLEAR_TYPE_TO_AUDIT.put("passengerMonthly", new String[]{"H2031"});
+        CLEAR_TYPE_TO_AUDIT.put("passengerAuth", new String[]{"H2031"});
+        CLEAR_TYPE_TO_AUDIT.put("passengerIndividual", new String[]{"H2031"});
+        CLEAR_TYPE_TO_AUDIT.put("energyMonthly", new String[]{"H204"});
+        CLEAR_TYPE_TO_AUDIT.put("energyAuth", new String[]{"H204"});
+        CLEAR_TYPE_TO_AUDIT.put("investment", new String[]{"INVEST"});
+        CLEAR_TYPE_TO_AUDIT.put("investmentLogistics", new String[]{"INVEST"});
+        CLEAR_TYPE_TO_AUDIT.put("investCityPassenger", new String[]{"INVEST"});
+        CLEAR_TYPE_TO_AUDIT.put("investCityLogistics", new String[]{"INVEST"});
+        CLEAR_TYPE_TO_AUDIT.put("investmentSystem", new String[]{"INVEST"});
+        CLEAR_TYPE_TO_AUDIT.put("cityBus", new String[]{"CITY_BUS"});
+        CLEAR_TYPE_TO_AUDIT.put("cityTaxi", new String[]{"CITY_TAXI"});
+        CLEAR_TYPE_TO_AUDIT.put("cityTaxiAuth", new String[]{"CITY_TAXI"});
+
+        String[] investPassengerBatch = {"INVEST_瀹㈣繍绔欏満", "INVEST_瀹㈣繍绔欏満_CITY"};
+        String[] investLogisticsBatch = {"INVEST_鐗╂祦鍥尯", "INVEST_鐗╂祦鍥尯_CITY"};
+        CLEAR_TYPE_TO_BATCH.put("h2032", new String[]{"H2032"});
+        CLEAR_TYPE_TO_BATCH.put("transportAuth", new String[]{"TRANSPORT_AUTH"});
+        CLEAR_TYPE_TO_BATCH.put("trackMileage", new String[]{"TRACK_MILEAGE"});
+        CLEAR_TYPE_TO_BATCH.put("scaleSplit", new String[]{"SCALE_SPLIT"});
+        CLEAR_TYPE_TO_BATCH.put("freightTurnover", new String[]{"FREIGHT_TURNOVER"});
+        CLEAR_TYPE_TO_BATCH.put("passengerMonthly", new String[]{"H2031"});
+        CLEAR_TYPE_TO_BATCH.put("passengerAuth", new String[]{"PASSENGER_AUTH"});
+        CLEAR_TYPE_TO_BATCH.put("passengerIndividual", new String[]{"PASSENGER_INDIVIDUAL"});
+        CLEAR_TYPE_TO_BATCH.put("energyMonthly", new String[]{"H204"});
+        CLEAR_TYPE_TO_BATCH.put("energyAuth", new String[]{"ENERGY_AUTH"});
+        CLEAR_TYPE_TO_BATCH.put("investment", investPassengerBatch);
+        CLEAR_TYPE_TO_BATCH.put("investCityPassenger", investPassengerBatch);
+        CLEAR_TYPE_TO_BATCH.put("investmentLogistics", investLogisticsBatch);
+        CLEAR_TYPE_TO_BATCH.put("investCityLogistics", investLogisticsBatch);
+        CLEAR_TYPE_TO_BATCH.put("investmentSystem", new String[]{"INVEST_SYSTEM"});
+        CLEAR_TYPE_TO_BATCH.put("cityBus", new String[]{"CITY_BUS"});
+        CLEAR_TYPE_TO_BATCH.put("cityTaxi", new String[]{"CITY_TAXI"});
+        CLEAR_TYPE_TO_BATCH.put("cityTaxiAuth", new String[]{"CITY_TAXI_AUTH"});
+        CLEAR_TYPE_TO_BATCH.put("wycTotal", new String[]{"WYC_TOTAL"});
+        CLEAR_TYPE_TO_BATCH.put("wycOrder", new String[]{"WYC_ORDER"});
+    }
+
+    /**
+     * 娓呯┖鎸囧畾鎶ヨ〃鏈熷凡瀵煎叆鏁版嵁涓庡鏍哥粨鏋滐紝鐢ㄤ簬鏁存湀閲嶅锛涙姇璧勯」鐩富妗d繚鐣欍��
+     *
+     * @param types 闇�娓呯┖鐨勬暟鎹被鍨嬶紙鍓嶇绫诲瀷閿紝濡� h2032/cityBus锛夛紱涓虹┖鍒欐竻绌鸿鎶ヨ〃鏈熷叏閮ㄧ被鍨�
+     */
     @Transactional(rollbackFor = Exception.class)
-    public Map<String, Object> clearPeriod(String period) {
+    public Map<String, Object> clearPeriod(String period, List<String> types) {
         if (period == null || !period.matches("\\d{4}-\\d{2}")) {
             throw new IllegalArgumentException("鎶ヨ〃鏈熸牸寮忎笉姝g‘锛屽簲涓� yyyy-MM");
         }
+        Set<String> selected = new LinkedHashSet<>();
+        if (types != null) {
+            for (String t : types) {
+                if (t != null && !t.trim().isEmpty()) selected.add(t.trim());
+            }
+        }
+        boolean clearAll = selected.isEmpty();
         int dataRows = 0;
+        int auditRows = 0;
+        int auditRunRows = 0;
+        int batchRows = 0;
+        if (clearAll) {
         dataRows += h2032Mapper.delete(new LambdaQueryWrapper<H2032EnterpriseMonthly>()
             .eq(H2032EnterpriseMonthly::getReportPeriod, period));
         dataRows += transportAuthMapper.delete(new LambdaQueryWrapper<TransportAuthVehicle>()
@@ -1358,23 +1445,145 @@
             .eq(WycTotalMonthly::getReportPeriod, period));
         dataRows += wycOrderMapper.delete(new LambdaQueryWrapper<WycOrderMonthly>()
             .eq(WycOrderMonthly::getReportPeriod, period));
-        int auditRows = auditResultMapper.delete(new LambdaQueryWrapper<AuditResult>()
+        auditRows = auditResultMapper.delete(new LambdaQueryWrapper<AuditResult>()
             .eq(AuditResult::getReportPeriod, period));
-        int auditRunRows = auditRunMapper.delete(new LambdaQueryWrapper<AuditRun>()
+        auditRunRows = auditRunMapper.delete(new LambdaQueryWrapper<AuditRun>()
             .eq(AuditRun::getReportPeriod, period));
-        int batchRows = importBatchMapper.delete(new LambdaQueryWrapper<ImportBatch>()
+        batchRows = importBatchMapper.delete(new LambdaQueryWrapper<ImportBatch>()
             .eq(ImportBatch::getReportPeriod, period));
+        } else {
+            Set<String> ops = new LinkedHashSet<>();
+            Set<String> auditTypes = new LinkedHashSet<>();
+            Set<String> batchTypes = new LinkedHashSet<>();
+            for (String t : selected) {
+                String op = CLEAR_TYPE_TO_OP.get(t);
+                if (op == null) {
+                    log.warn("娓呯┖鏁版嵁锛氭湭鐭ユ暟鎹被鍨� {}锛屽凡蹇界暐", t);
+                    continue;
+                }
+                ops.add(op);
+                String[] at = CLEAR_TYPE_TO_AUDIT.get(t);
+                if (at != null) java.util.Collections.addAll(auditTypes, at);
+                String[] bt = CLEAR_TYPE_TO_BATCH.get(t);
+                if (bt != null) java.util.Collections.addAll(batchTypes, bt);
+            }
+            if (ops.isEmpty()) {
+                throw new IllegalArgumentException("鏈寚瀹氭湁鏁堢殑鏁版嵁绫诲瀷");
+            }
+            for (String op : ops) {
+                dataRows += clearTypeData(op, period);
+            }
+            if (!auditTypes.isEmpty()) {
+                List<Long> ruleIds = new ArrayList<>();
+                for (com.trafficaudit.rulemanage.entity.AuditRule rule : ruleMapper.selectList(null)) {
+                    if (rule.getReportType() != null && auditTypes.contains(rule.getReportType())) {
+                        ruleIds.add(rule.getId());
+                    }
+                }
+                if (!ruleIds.isEmpty()) {
+                    auditRows = auditResultMapper.delete(new LambdaQueryWrapper<AuditResult>()
+                        .eq(AuditResult::getReportPeriod, period)
+                        .in(AuditResult::getRuleId, ruleIds));
+                }
+                for (String rt : auditTypes) {
+                    auditRunRows += auditRunMapper.delete(new LambdaQueryWrapper<AuditRun>()
+                        .eq(AuditRun::getReportPeriod, period)
+                        .eq(AuditRun::getReportType, rt));
+                }
+            }
+            if (!batchTypes.isEmpty()) {
+                batchRows = importBatchMapper.delete(new LambdaQueryWrapper<ImportBatch>()
+                    .eq(ImportBatch::getReportPeriod, period)
+                    .in(ImportBatch::getImportType, batchTypes));
+            }
+        }
         Map<String, Object> stats = new LinkedHashMap<>();
         stats.put("period", period);
+        stats.put("scope", clearAll ? "all" : "types");
+        if (!clearAll) stats.put("types", new ArrayList<>(selected));
         stats.put("dataRows", dataRows);
         stats.put("auditRows", auditRows);
         stats.put("auditRunRows", auditRunRows);
         stats.put("batchRows", batchRows);
-        log.info("娓呯┖鎶ヨ〃鏈� {} 瀹屾垚锛氫笟鍔℃暟鎹� {} 琛屻�佸鏍哥粨鏋� {} 琛屻�佸鏍告爣璁� {} 琛屻�佸鍏ユ壒娆� {} 琛�",
-            period, dataRows, auditRows, auditRunRows, batchRows);
+        log.info("娓呯┖鎶ヨ〃鏈� {}锛坽}锛夊畬鎴愶細涓氬姟鏁版嵁 {} 琛屻�佸鏍哥粨鏋� {} 琛屻�佸鏍告爣璁� {} 琛屻�佸鍏ユ壒娆� {} 琛�",
+            period, clearAll ? "鍏ㄩ儴绫诲瀷" : String.join(",", selected), dataRows, auditRows, auditRunRows, batchRows);
         return stats;
     }
 
+    /** 鎸夆�滄暟鎹〃鎿嶄綔閿�濇竻绌哄搴斾笟鍔¤〃锛堟姇璧勬湀搴︽寜椤圭洰绫诲埆杩囨护锛夛紝杩斿洖鍒犻櫎琛屾暟 */
+    private int clearTypeData(String op, String period) {
+        switch (op) {
+            case "H2032":
+                return h2032Mapper.delete(new LambdaQueryWrapper<H2032EnterpriseMonthly>()
+                    .eq(H2032EnterpriseMonthly::getReportPeriod, period));
+            case "TRANSPORT_AUTH":
+                return transportAuthMapper.delete(new LambdaQueryWrapper<TransportAuthVehicle>()
+                    .eq(TransportAuthVehicle::getReportPeriod, period));
+            case "TRACK_MILEAGE":
+                return trackMileageMapper.delete(new LambdaQueryWrapper<VehicleTrackMileage>()
+                    .eq(VehicleTrackMileage::getReportPeriod, period));
+            case "SCALE_SPLIT":
+                return scaleSplitMapper.delete(new LambdaQueryWrapper<ScaleSplitTransport>()
+                    .eq(ScaleSplitTransport::getReportPeriod, period));
+            case "FREIGHT_TURNOVER":
+                return freightTurnoverMapper.delete(new LambdaQueryWrapper<FreightTurnoverImport>()
+                    .eq(FreightTurnoverImport::getReportPeriod, period));
+            case "H2031":
+                return passengerMapper.delete(new LambdaQueryWrapper<PassengerEnterpriseMonthly>()
+                    .eq(PassengerEnterpriseMonthly::getReportPeriod, period));
+            case "PASSENGER_AUTH":
+                return passengerAuthMapper.delete(new LambdaQueryWrapper<PassengerAuthVehicle>()
+                    .eq(PassengerAuthVehicle::getReportPeriod, period));
+            case "PASSENGER_INDIVIDUAL":
+                return passengerIndividualMapper.delete(new LambdaQueryWrapper<PassengerIndividualMonthly>()
+                    .eq(PassengerIndividualMonthly::getReportPeriod, period));
+            case "H204":
+                return energyMapper.delete(new LambdaQueryWrapper<EnergyVehicleQuarterly>()
+                    .eq(EnergyVehicleQuarterly::getReportPeriod, period));
+            case "ENERGY_AUTH":
+                return energyAuthMapper.delete(new LambdaQueryWrapper<EnergyAuthVehicle>()
+                    .eq(EnergyAuthVehicle::getReportPeriod, period));
+            case "INVEST_MONTHLY_PASSENGER":
+                return deleteInvestmentMonthly(period, "瀹㈣繍绔欏満");
+            case "INVEST_MONTHLY_LOGISTICS":
+                return deleteInvestmentMonthly(period, "鐗╂祦鍥尯");
+            case "INVEST_SYSTEM":
+                return investSystemMapper.delete(new LambdaQueryWrapper<InvestmentSystem>()
+                    .eq(InvestmentSystem::getReportPeriod, period));
+            case "CITY_BUS":
+                return cityBusMapper.delete(new LambdaQueryWrapper<CityBusMonthly>()
+                    .eq(CityBusMonthly::getReportPeriod, period));
+            case "CITY_TAXI":
+                return cityTaxiMapper.delete(new LambdaQueryWrapper<CityTaxiMonthly>()
+                    .eq(CityTaxiMonthly::getReportPeriod, period));
+            case "CITY_TAXI_AUTH":
+                return cityTaxiAuthMapper.delete(new LambdaQueryWrapper<CityTaxiAuth>()
+                    .eq(CityTaxiAuth::getReportPeriod, period));
+            case "WYC_TOTAL":
+                return wycTotalMapper.delete(new LambdaQueryWrapper<WycTotalMonthly>()
+                    .eq(WycTotalMonthly::getReportPeriod, period));
+            case "WYC_ORDER":
+                return wycOrderMapper.delete(new LambdaQueryWrapper<WycOrderMonthly>()
+                    .eq(WycOrderMonthly::getReportPeriod, period));
+            default:
+                log.warn("娓呯┖鏁版嵁锛氭湭鐭ユ暟鎹〃鎿嶄綔 {}", op);
+                return 0;
+        }
+    }
+
+    /** 鎶曡祫鏈堝害鎸夐」鐩被鍒竻闄わ紙鎶曡祫椤圭洰涓绘。淇濈暀锛� */
+    private int deleteInvestmentMonthly(String period, String category) {
+        List<Long> projectIds = new ArrayList<>();
+        for (InvestmentProject p : investProjectMapper.selectList(new LambdaQueryWrapper<InvestmentProject>()
+                .eq(InvestmentProject::getCategory, category))) {
+            projectIds.add(p.getId());
+        }
+        if (projectIds.isEmpty()) return 0;
+        return investMonthlyMapper.delete(new LambdaQueryWrapper<InvestmentMonthly>()
+            .eq(InvestmentMonthly::getReportPeriod, period)
+            .in(InvestmentMonthly::getProjectId, projectIds));
+    }
+
     /** 鏁版嵁鍙樺寲鍚庡垹闄ゆ寚瀹氭姤琛ㄧ被鍨嬫寚瀹氭姤琛ㄦ湡鐨勫鏍哥粨鏋滐紙闇�閲嶆柊鎵ц瀹℃牳锛� */
     private void deleteRuleResults(String reportType, String period) {
         List<Long> ruleIds = new ArrayList<>();
diff --git a/traffic-audit-web/src/views/DataImport.vue b/traffic-audit-web/src/views/DataImport.vue
index e496ed4..7ed598b 100644
--- a/traffic-audit-web/src/views/DataImport.vue
+++ b/traffic-audit-web/src/views/DataImport.vue
@@ -103,11 +103,12 @@
               <div v-show="sideOpen" class="side-content">
                 <div class="side-head">
                   <span>鏈湀瀵煎叆杩涘害锛坽{ period || '鏈�夋嫨鎶ヨ〃鏈�' }}锛�</span>
-                  <span class="side-head-btns">
-                    <el-button type="text" icon="el-icon-refresh" @click="loadData">鍒锋柊</el-button>
-                    <el-button type="text" icon="el-icon-delete" style="color:#F56C6C" :loading="clearing"
-                               :disabled="!period || clearing || importing" @click="clearPeriodData">娓呯┖</el-button>
-                  </span>
+                  <el-button type="text" icon="el-icon-refresh" @click="loadData">鍒锋柊</el-button>
+                </div>
+                <div v-if="period" class="side-danger">
+                  <el-button size="mini" type="danger" plain icon="el-icon-delete"
+                             :disabled="clearing || importing" @click="openClearDialog">娓呯┖鏁版嵁鈥�</el-button>
+                  <span class="side-danger-tip">鎸夋姤琛ㄦ湡娓呭簱锛岀敤浜庢暣鏈堥噸瀵�</span>
                 </div>
                 <div v-if="!period" class="tip">璇峰厛鍦ㄤ笂鏂归�夋嫨鎶ヨ〃鏈�</div>
                 <div v-else class="overview-grid">
@@ -123,6 +124,32 @@
             </div>
           </div>
         </div>
+        <el-dialog title="娓呯┖鏁版嵁" :visible.sync="clearDialog" width="560px" append-to-body :close-on-click-modal="false">
+          <div class="clear-dlg">
+            <div class="clear-period">鎶ヨ〃鏈燂細<b>{{ period }}</b></div>
+            <el-radio-group v-model="clearScope">
+              <el-radio label="all">娓呯┖璇ユ姤琛ㄦ湡鍏ㄩ儴宸插鍏ユ暟鎹�</el-radio>
+              <el-radio label="types">鍙竻绌烘寚瀹氱被鍨�</el-radio>
+            </el-radio-group>
+            <div v-if="clearScope === 'types'" class="clear-types">
+              <el-select v-model="clearTypes" multiple filterable collapse-tags placeholder="閫夋嫨瑕佹竻绌虹殑鏁版嵁绫诲瀷" style="width:100%">
+                <el-option-group v-for="g in clearableGroups()" :key="g.key" :label="g.name">
+                  <el-option v-for="t in g.types" :key="t.value" :value="t.value"
+                             :label="t.label + '锛�' + overviewState(t.value).text + '锛�'"></el-option>
+                </el-option-group>
+              </el-select>
+              <div class="tip" style="margin-top:6px">鍙閫夛紱鏈鍏ョ殑绫诲瀷娌℃湁鏁版嵁鍙垹銆�</div>
+            </div>
+            <div class="clear-warn">
+              灏嗗垹闄ゆ墍閫夎寖鍥村唴璇ユ姤琛ㄦ湡鐨勬暟鎹簱鏁版嵁锛屽苟鍚屾鍒犻櫎瀵瑰簲瀹℃牳缁撴灉銆佸凡瀹℃牳鏍囪涓庡鍏ユ壒娆¤褰曪紙鎶曡祫椤圭洰涓绘。淇濈暀锛夈�傛鎿嶄綔涓嶅彲鎾ら攢锛岃纭宸叉湁澶囦唤鎴栧噯澶囬噸鏂板鍏ャ��
+            </div>
+          </div>
+          <span slot="footer">
+            <el-button @click="clearDialog = false">鍙栨秷</el-button>
+            <el-button type="danger" :loading="clearing"
+                       :disabled="clearScope === 'types' && !clearTypes.length" @click="confirmClear">纭娓呯┖</el-button>
+          </span>
+        </el-dialog>
       </el-main>
     </el-container>
   </el-container>
@@ -163,6 +190,9 @@
       cityDirLoading: false,
       importing: false,
       clearing: false,
+      clearDialog: false,
+      clearScope: 'all',
+      clearTypes: [],
       sideOpen: false,
       result: '',
       error: '',
@@ -525,27 +555,43 @@
         .catch(e => { if (!e || !e._toast) this.$message.error('瀵煎叆璁板綍鍔犺浇澶辫触锛岃鍒锋柊閲嶈瘯') })
         .finally(() => { this.batchLoading = false })
     },
-    clearPeriodData() {
+    openClearDialog() {
       if (!this.period) { this.$message.warning('璇峰厛閫夋嫨鎶ヨ〃鏈�'); return }
       if (this.importing) { this.$message.warning('姝e湪瀵煎叆鏁版嵁锛岃绛夊緟瀵煎叆瀹屾垚鍚庡啀娓呯┖'); return }
+      this.clearScope = 'all'
+      this.clearTypes = []
+      this.clearDialog = true
+    },
+    clearableGroups() {
+      return this.groups.filter(g => !g.hidden)
+    },
+    confirmClear() {
+      if (!this.period) { this.$message.warning('璇峰厛閫夋嫨鎶ヨ〃鏈�'); return }
       if (this.clearing) return
-      this.$confirm(
-        '灏嗘竻绌� ' + this.period + ' 鎶ヨ〃鏈熷湪鏁版嵁搴撲腑鐨勫叏閮ㄥ凡瀵煎叆鏁版嵁锛屽悓鏃跺垹闄よ鎶ヨ〃鏈熺殑瀹℃牳缁撴灉涓庡鍏ユ壒娆¤褰曪紙渚夸簬鏁存湀閲嶆柊瀵煎叆锛夈�俓n姝ゆ搷浣滀笉鍙挙閿�锛屾槸鍚︾户缁紵',
-        '娓呯┖ ' + this.period + ' 鏁版嵁',
-        { type: 'warning', confirmButtonText: '纭娓呯┖', cancelButtonText: '鍙栨秷' }
-      ).then(() => {
-        this.clearing = true
-        api.post('/import/clear', null, { params: { period: this.period }, timeout: 600000 })
-          .then(() => {
-            this.$message.success('宸叉竻绌� ' + this.period + ' 鎶ヨ〃鏈熺殑鏁版嵁锛屽彲浠ラ噸鏂板鍏�')
-            this.loadData()
-          })
-          .catch(e => {
-            if (e && e._toast) return
-            this.$message.error((e.response && e.response.data && e.response.data.message) || '娓呯┖澶辫触锛岃绋嶅悗閲嶈瘯')
-          })
-          .finally(() => { this.clearing = false })
-      }).catch(() => {})
+      if (this.clearScope === 'types' && !this.clearTypes.length) { this.$message.warning('璇烽�夋嫨瑕佹竻绌虹殑鏁版嵁绫诲瀷'); return }
+      const scopeText = this.clearScope === 'all'
+        ? '璇ユ姤琛ㄦ湡鍏ㄩ儴宸插鍏ユ暟鎹�'
+        : '浠ヤ笅 ' + this.clearTypes.length + ' 涓被鍨嬶細' + this.clearTypes.map(t => this.typeLabel(t)).join('銆�')
+      this.$confirm('灏嗘竻绌� ' + this.period + ' 鐨�' + scopeText + '锛屽苟鍚屾鍒犻櫎瀵瑰簲瀹℃牳缁撴灉銆佸凡瀹℃牳鏍囪涓庡鍏ユ壒娆¤褰曘�傛鎿嶄綔涓嶅彲鎾ら攢锛屾槸鍚︾户缁紵',
+        '娓呯┖纭', { type: 'warning', confirmButtonText: '纭娓呯┖', cancelButtonText: '鍙栨秷' })
+        .then(() => {
+          this.clearing = true
+          const params = { period: this.period }
+          if (this.clearScope === 'types') params.types = this.clearTypes.join(',')
+          return api.post('/import/clear', null, { params, timeout: 600000 })
+            .then(res => {
+              const d = (res && res.data) || {}
+              this.$message.success('宸叉竻绌� ' + this.period + ' 鏁版嵁锛氫笟鍔℃暟鎹� ' + (d.dataRows || 0) +
+                ' 琛屻�佸鏍哥粨鏋� ' + (d.auditRows || 0) + ' 琛屻�佸鍏ユ壒娆� ' + (d.batchRows || 0) + ' 鏉★紝鍙互閲嶆柊瀵煎叆')
+              this.clearDialog = false
+              this.loadData()
+            })
+            .catch(e => {
+              if (e && e._toast) return
+              this.$message.error((e.response && e.response.data && e.response.data.message) || '娓呯┖澶辫触锛岃绋嶅悗閲嶈瘯')
+            })
+            .finally(() => { this.clearing = false })
+        }).catch(() => {})
     },
     batchKeyToType(k) {
       if (BATCH_TYPE_MAP[k]) return BATCH_TYPE_MAP[k]
@@ -618,8 +664,12 @@
 .import-side.side-open .side-toggle-text { writing-mode: horizontal-tb; letter-spacing: normal; margin-top: 0; }
 .side-content { padding: 8px 12px 12px; max-height: calc(100vh - 220px); overflow-y: auto; overscroll-behavior: contain; }
 .side-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-weight: 600; margin-bottom: 6px; }
-.side-head-btns { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
-.side-head-btns .el-button + .el-button { margin-left: 0; }
+.side-danger { display: flex; align-items: center; gap: 8px; margin: 4px 0 10px; padding: 6px 8px; background: #FEF0F0; border: 1px solid #FDE2E2; border-radius: 4px; }
+.side-danger-tip { font-size: 12px; color: #F56C6C; line-height: 1.3; }
+.clear-dlg { line-height: 1.7; }
+.clear-period { margin-bottom: 6px; }
+.clear-types { margin-top: 10px; }
+.clear-warn { margin-top: 12px; padding: 8px 10px; background: #FEF0F0; border: 1px solid #FDE2E2; border-radius: 4px; color: #F56C6C; font-size: 12px; line-height: 1.6; }
 .import-side .overview-grid { display: block; }
 .import-side .ov-row { display: block; margin-bottom: 6px; }
 .import-side .ov-group { width: auto; }

--
Gitblit v1.9.1