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 | 98 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 96 insertions(+), 2 deletions(-)
diff --git a/traffic-audit-web/src/views/DataImport.vue b/traffic-audit-web/src/views/DataImport.vue
index a36ee76..7ed598b 100644
--- a/traffic-audit-web/src/views/DataImport.vue
+++ b/traffic-audit-web/src/views/DataImport.vue
@@ -105,6 +105,11 @@
<span>鏈湀瀵煎叆杩涘害锛坽{ period || '鏈�夋嫨鎶ヨ〃鏈�' }}锛�</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">
<div class="ov-row" v-for="g in visibleGroups" :key="g.key">
@@ -119,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>
@@ -158,6 +189,10 @@
period: (() => { const d = new Date(); return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') })(),
cityDirLoading: false,
importing: false,
+ clearing: false,
+ clearDialog: false,
+ clearScope: 'all',
+ clearTypes: [],
sideOpen: false,
result: '',
error: '',
@@ -251,7 +286,7 @@
scaleSplit: '妯℃澘_瑙勪笂瑙勪笅鎷嗗垎杩愯緭閲�.xlsx',
freightTurnover: '妯℃澘_璐ц繍閲忓懆杞噺.xlsx',
passengerMonthly: '鍏矾鏃呭杩愯緭鏈堝害鐢熶骇鎯呭喌.xlsx锛堝惈杩愭斂杞﹁締鏁皊heet锛�',
- passengerAuth: '妯℃澘_鍏矾鏃呭杩愭斂杞﹁締鏁�.xlsx锛堝垪锛氫紒涓氫唬鐮�/浼佷笟鍚嶇О/杞﹁締鏁�/杞藉浣嶆暟锛�',
+ passengerAuth: '妯℃澘_鍏矾鏃呭杩愭斂杞﹁締鏁�.xls锛堟敮鎸� 浼佷笟浠g爜/浼佷笟鍚嶇О/杞﹁締鏁�/杞藉浣嶆暟 涓� 杩愭斂搴撳鍑� OWNERNAME/鎬昏溅杈嗘暟/瀹綅鏁帮級',
passengerIndividual: '涓綋瀹㈣繍閲忔眹鎬�.xlsx锛堝垪锛氭墍灞炲湴鍖�/浼佷笟浠g爜/浼佷笟鍚嶇О/涓綋瀹㈣繍閲�/涓綋鏃呭鍛ㄨ浆閲忥級',
energyMonthly: '閬撹矾璐ц繍杞﹁締鑳芥簮娑堣�楁儏鍐碉紙2026骞达級.xlsx锛堣兘鑰楁槑缁�+杩愭斂杞﹁締淇℃伅涓heet锛�',
energyAuth: '妯℃澘_鑳借�楄溅杈嗚繍鏀夸俊鎭�.xlsx锛堝垪锛氳溅鐗屽彿/杞﹁締绫诲瀷/鐕冩枡绫诲瀷/鏍囪鍚ㄤ綅/鍑嗙壍寮曡川閲忥級',
@@ -276,7 +311,7 @@
scaleSplit: '璐ц繍/妯℃澘_瑙勪笂瑙勪笅鎷嗗垎杩愯緭閲�.xlsx',
freightTurnover: '璐ц繍/妯℃澘_璐ц繍閲忓懆杞噺.xlsx',
passengerMonthly: '鍏矾鏃呭/妯℃澘_浜や紒缁烪203-1琛╛鍏矾鏃呭杩愯緭鏈堝害鐢熶骇鎯呭喌.xlsx',
- passengerAuth: '鍏矾鏃呭/妯℃澘_鍏矾鏃呭杩愭斂杞﹁締鏁�.xlsx',
+ passengerAuth: '鍏矾鏃呭/妯℃澘_鍏矾鏃呭杩愭斂杞﹁締鏁�.xls',
passengerIndividual: '鍏矾鏃呭/涓綋瀹㈣繍閲忔眹鎬�.xlsx',
energyMonthly: '鑳借��/妯℃澘_閬撹矾璐ц繍杞﹁締鑳芥簮娑堣�楁儏鍐碉紙2026锛�.xlsx',
energyAuth: '鑳借��/妯℃澘_鑳借�楄溅杈嗚繍鏀夸俊鎭�.xlsx',
@@ -372,6 +407,7 @@
message: ''
}
this.importOne(row).then(() => {
+ this.showImportResult(row)
if ((row.type === 'investment' || row.type === 'investmentLogistics') && row.status === 'success') {
this.checkInvest(this.period)
}
@@ -466,6 +502,20 @@
})
.finally(() => { this.cityDirLoading = false })
},
+ showImportResult(row) {
+ if (!row || !row.status) return
+ const msg = (row.message || '').toString()
+ if (row.status === 'success') {
+ const text = (msg && msg.indexOf('瀵煎叆') !== -1) ? msg : '鏁版嵁瀵煎叆鎴愬姛'
+ this.$message({ message: text, type: 'success', duration: 5000 })
+ } else {
+ this.$alert((msg || '鏁版嵁瀵煎叆澶辫触锛岃瑙佷笅鏂瑰け璐ヨ褰�').replace(/\n/g, '<br>'), '鏁版嵁瀵煎叆澶辫触', {
+ dangerouslyUseHTMLString: true,
+ type: 'error',
+ confirmButtonText: '鐭ラ亾浜�'
+ })
+ }
+ },
importOne(row) {
if (!this.period) { this.$message.warning('璇峰厛閫夋嫨鎶ヨ〃鏈�'); return Promise.resolve() }
row.status = 'uploading'
@@ -504,6 +554,44 @@
})
.catch(e => { if (!e || !e._toast) this.$message.error('瀵煎叆璁板綍鍔犺浇澶辫触锛岃鍒锋柊閲嶈瘯') })
.finally(() => { this.batchLoading = false })
+ },
+ 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
+ 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]
@@ -576,6 +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-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