From d7c697139d3dc8407ef6782e23e5963a87c2eec4 Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期日, 20 九月 2026 14:57:22 +0800
Subject: [PATCH] fix(投资): 清除十堰汇总表带出的非十堰残留 + 预安排汇总小计补计 + 导入弹窗可拖动
---
traffic-audit-web/src/views/DataImport.vue | 250 +++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 227 insertions(+), 23 deletions(-)
diff --git a/traffic-audit-web/src/views/DataImport.vue b/traffic-audit-web/src/views/DataImport.vue
index f3e8b91..deb64c6 100644
--- a/traffic-audit-web/src/views/DataImport.vue
+++ b/traffic-audit-web/src/views/DataImport.vue
@@ -37,7 +37,7 @@
<div class="module-sel-row">
<el-select v-model="moduleSel[g.key]" placeholder="閫夋嫨鏁版嵁绫诲瀷" style="width:260px"
@change="onModuleChange(g.key)" clearable>
- <el-option v-for="t in g.types" :key="t.value" :label="t.label" :value="t.value"></el-option>
+ <el-option v-for="t in typeList(g)" :key="t.value" :label="t.label" :value="t.value"></el-option>
</el-select>
<div v-if="importType" class="tpl-box">
<span class="tpl-name">妯℃澘锛歿{ templateName }}</span>
@@ -54,7 +54,7 @@
<div v-else-if="moduleSel[g.key] && !isDirOnlyType(moduleSel[g.key])" class="module-file">
<div class="file-name" :title="fileNamesText(moduleSel[g.key])">{{ fileNamesText(moduleSel[g.key]) || '鏈�夋嫨鏂囦欢' }}</div>
<div class="file-btns">
- <el-upload action="#" :auto-upload="false" :show-file-list="false" multiple accept=".xlsx,.xls,.et"
+ <el-upload action="#" :auto-upload="false" :show-file-list="false" multiple :accept="acceptOf(moduleSel[g.key])"
:ref="'up' + g.key" :on-change="f => onFilePicked(g.key, f)" style="display:inline-block">
<el-button size="mini" type="primary" plain icon="el-icon-folder-opened" :disabled="importing">閫夋嫨鏂囦欢</el-button>
</el-upload>
@@ -105,11 +105,16 @@
<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">
<div class="ov-group">{{ g.name }}</div>
- <div class="ov-item" v-for="t in g.types" :key="t.value" :class="overviewState(t.value).cls">
+ <div class="ov-item" v-for="t in typeList(g)" :key="t.value" :class="overviewState(t.value).cls">
<div class="ov-name">{{ t.label }}</div>
<div class="ov-status">{{ overviewState(t.value).text }}</div>
</div>
@@ -119,6 +124,45 @@
</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 typeList(g)" :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>
+ <!-- 瀵煎叆缁撴灉寮圭獥锛氬彲鎷栧姩銆佸唴瀹瑰尯婊氬姩銆佸簳閮ㄦ寜閽浐瀹氬彲瑙侊紙鍘� $alert 鍐呭闀挎椂搴曢儴鎸夐挳浼氳鎸ゅ嚭灞忓箷锛� -->
+ <el-dialog :title="resultDialog.title" :visible.sync="resultDialog.visible" width="860px" top="5vh"
+ append-to-body :close-on-click-modal="false" custom-class="import-result-dialog" v-dialog-drag>
+ <div v-if="resultDialog.level" class="ird-level" :class="'ird-' + resultDialog.level">
+ {{ resultDialog.level === 'error' ? '瀵煎叆澶辫触' : (resultDialog.level === 'warning' ? '瀛樺湪闇�瑕佺‘璁ょ殑鍐呭' : '瀵煎叆鎴愬姛') }}
+ </div>
+ <div class="ird-body" v-html="resultDialog.html"></div>
+ <span slot="footer">
+ <el-button v-if="resultDialog.rows.length" size="small" icon="el-icon-download"
+ @click="exportResultDialog">瀵煎嚭鏄庣粏</el-button>
+ <el-button type="primary" @click="resultDialog.visible = false">纭</el-button>
+ </span>
+ </el-dialog>
</el-main>
</el-container>
</el-container>
@@ -134,10 +178,11 @@
investCityPassenger: '甯傚窞鍗曡〃锛堝杩愮珯鍦猴級', investCityLogistics: '甯傚窞鍗曡〃锛堢墿娴佸洯鍖猴級',
'INVEST_瀹㈣繍绔欏満_CITY': '甯傚窞鍗曡〃锛堝杩愮珯鍦猴級', 'INVEST_鐗╂祦鍥尯_CITY': '甯傚窞鍗曡〃锛堢墿娴佸洯鍖猴級',
cityBus: '鍩庡競鍏氦鏈堟姤', cityTaxi: '宸℃父鍑虹鏈堟姤', cityTaxiAuth: '鍑虹杞﹁繍鏀胯溅杈�',
+ wycTotal: '缃戠害杞︽�绘暟', wycOrder: '缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺', wycOrderReport: '缃戠害杞﹁鍗曟姤鍛�',
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: '缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺', WYC_ORDER_REPORT: '缃戠害杞﹁鍗曟姤鍛�'
}
const BATCH_TYPE_MAP = {
H2032: 'h2032', TRANSPORT_AUTH: 'transportAuth', TRACK_MILEAGE: 'trackMileage',
@@ -145,6 +190,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', WYC_ORDER_REPORT: 'wycOrderReport',
INVEST_SYSTEM: 'investmentSystem'
}
export default {
@@ -156,6 +202,11 @@
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: [],
+ resultDialog: { visible: false, title: '', html: '', rows: [], columns: [], fileName: '', level: '' },
sideOpen: false,
result: '',
error: '',
@@ -187,7 +238,10 @@
key: 'city', name: '鍩庡競瀹㈣繍', types: [
{ value: 'cityBus', label: '鍩庡競鍏叡浜ら�氭湀搴﹁繍钀ユ儏鍐�' },
{ value: 'cityTaxi', label: '宸℃父鍑虹姹借溅杩愯惀鏈嶅姟鎯呭喌鏈堟姤' },
- { value: 'cityTaxiAuth', label: '鍑虹杞﹁繍鏀胯溅杈�' }
+ { value: 'cityTaxiAuth', label: '鍑虹杞﹁繍鏀胯溅杈�' },
+ { value: 'wycTotal', label: '缃戠害杞︽�绘暟' },
+ { value: 'wycOrder', label: '缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺', hidden: true },
+ { value: 'wycOrderReport', label: '缃戠害杞﹁鍗曟姤鍛�' }
]
},
{
@@ -247,7 +301,7 @@
scaleSplit: '妯℃澘_瑙勪笂瑙勪笅鎷嗗垎杩愯緭閲�.xlsx',
freightTurnover: '妯℃澘_璐ц繍閲忓懆杞噺.xlsx',
passengerMonthly: '鍏矾鏃呭杩愯緭鏈堝害鐢熶骇鎯呭喌.xlsx锛堝惈杩愭斂杞﹁締鏁皊heet锛�',
- passengerAuth: '妯℃澘_鍏矾鏃呭杩愭斂杞﹁締鏁�.xlsx锛堝垪锛氫紒涓氫唬鐮�/浼佷笟鍚嶇О/杞﹁締鏁�/杞藉浣嶆暟锛�',
+ passengerAuth: '妯℃澘_鍏矾鏃呭杩愭斂杞﹁締鏁�.xls锛堟敮鎸� 浼佷笟浠g爜/浼佷笟鍚嶇О/杞﹁締鏁�/杞藉浣嶆暟 涓� 杩愭斂搴撳鍑� OWNERNAME/鎬昏溅杈嗘暟/瀹綅鏁帮級',
passengerIndividual: '涓綋瀹㈣繍閲忔眹鎬�.xlsx锛堝垪锛氭墍灞炲湴鍖�/浼佷笟浠g爜/浼佷笟鍚嶇О/涓綋瀹㈣繍閲�/涓綋鏃呭鍛ㄨ浆閲忥級',
energyMonthly: '閬撹矾璐ц繍杞﹁締鑳芥簮娑堣�楁儏鍐碉紙2026骞达級.xlsx锛堣兘鑰楁槑缁�+杩愭斂杞﹁締淇℃伅涓heet锛�',
energyAuth: '妯℃澘_鑳借�楄溅杈嗚繍鏀夸俊鎭�.xlsx锛堝垪锛氳溅鐗屽彿/杞﹁締绫诲瀷/鐕冩枡绫诲瀷/鏍囪鍚ㄤ綅/鍑嗙壍寮曡川閲忥級',
@@ -258,7 +312,10 @@
investCityLogistics: '鈥旓紙鎵归噺鎵弿鐩綍锛屾棤闇�妯℃澘锛�',
cityBus: '瀵煎叆_鍩庡競鍏叡浜ら�氭湀搴﹁繍钀ユ儏鍐碉紙YYYY骞碝鏈堬級.xls/.xlsx锛堜紒涓氱骇鏄庣粏锛屽彇鍏叡姹界數杞﹀瓧娈碉級',
cityTaxi: '瀵煎叆_宸℃父鍑虹姹借溅杩愯惀鏈嶅姟鎯呭喌鏈堟姤锛圷YYY骞碝鏈堬級.xls锛堝競宸炵骇17琛岋級',
- cityTaxiAuth: '瀵煎叆妯℃澘_鍑虹杞︿俊鎭�(杩愭斂杞﹁締淇℃伅).xlsx锛堣溅杈嗙骇鏄庣粏锛岀敤浜庤繍钀ヨ溅鏁板姣旓級'
+ cityTaxiAuth: '瀵煎叆妯℃澘_鍑虹杞︿俊鎭�(杩愭斂杞﹁締淇℃伅).xlsx锛堣溅杈嗙骇鏄庣粏锛岀敤浜庤繍钀ヨ溅鏁板姣旓級',
+ wycTotal: '妯℃澘_缃戠害杞︽�绘暟.xlsx锛圓鍒�=鏈堜唤锛孊-E=鍏ㄧ渷瀹㈣繍閲�/鍩庡競鍐�/鍛ㄨ浆閲�/鍩庡競鍐呭懆杞噺锛�',
+ wycOrder: '妯℃澘_缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx锛圓鍒�=鏈堜唤锛孊-E=鍏ㄧ渷pin锛孎=璁㈠崟鍚堣锛孏-W=17甯傚窞璁㈠崟锛�',
+ wycOrderReport: '妯℃澘_缃戠害杞﹁鍗�.docx锛堛�婄綉绾﹁溅琛屼笟YYYY骞碝鏈堣繍琛岀洃娴嬫儏鍐靛垎鏋愭姤鍛娿�嬶紝鑷姩瑙f瀽闄勪欢琛ㄣ�屽湴甯傚悕绉扳�﹁鍗曟暟鎬绘暟銆嶇殑 17 甯傚窞璁㈠崟锛�'
}
return map[this.importType] || ''
},
@@ -270,13 +327,16 @@
scaleSplit: '璐ц繍/妯℃澘_瑙勪笂瑙勪笅鎷嗗垎杩愯緭閲�.xlsx',
freightTurnover: '璐ц繍/妯℃澘_璐ц繍閲忓懆杞噺.xlsx',
passengerMonthly: '鍏矾鏃呭/妯℃澘_浜や紒缁烪203-1琛╛鍏矾鏃呭杩愯緭鏈堝害鐢熶骇鎯呭喌.xlsx',
- passengerAuth: '鍏矾鏃呭/妯℃澘_鍏矾鏃呭杩愭斂杞﹁締鏁�.xlsx',
+ passengerAuth: '鍏矾鏃呭/妯℃澘_鍏矾鏃呭杩愭斂杞﹁締鏁�.xls',
passengerIndividual: '鍏矾鏃呭/涓綋瀹㈣繍閲忔眹鎬�.xlsx',
energyMonthly: '鑳借��/妯℃澘_閬撹矾璐ц繍杞﹁締鑳芥簮娑堣�楁儏鍐碉紙2026锛�.xlsx',
energyAuth: '鑳借��/妯℃澘_鑳借�楄溅杈嗚繍鏀夸俊鎭�.xlsx',
cityBus: '鍩庡競瀹㈣繍/鐢熸垚_鍩庡競鍏氦瀹㈣繍閲忓垎甯傚窞鏄庣粏.xlsx',
cityTaxi: '鍩庡競瀹㈣繍/鐢熸垚_宸℃父鍑虹瀹㈣繍閲忓垎甯傚窞鏄庣粏.xlsx',
cityTaxiAuth: '鍩庡競瀹㈣繍/瀵煎叆妯℃澘_鍑虹杞︿俊鎭�(杩愭斂杞﹁締淇℃伅).xlsx',
+ wycTotal: '鍩庡競瀹㈣繍/妯℃澘_缃戠害杞︽�绘暟.xlsx',
+ wycOrder: '鍩庡競瀹㈣繍/妯℃澘_缃戠害杞﹁鍗曞強鍏ㄧ渷鎬婚噺.xlsx',
+ wycOrderReport: '鍩庡競瀹㈣繍/妯℃澘_缃戠害杞﹁鍗�.docx',
investment: '鎶曡祫/杈撳叆/瀹㈣繍锛堝杩愮珯锛�/鏇存柊_7鏈堝杩愮珯鎶曡祫鏄庣粏琛紙甯傚窞姹囨�诲ぇ琛紝缁欓瀵硷級.xlsx',
investmentLogistics: '鎶曡祫/杈撳叆/鐗╂祦锛堢墿娴佸洯鍖猴級/鏇存柊_7鏈堢墿娴佺珯鍦烘姇璧勬槑缁�.xls',
investmentSystem: '鎶曡祫/妯℃澘_鏌ヨ缁撴灉(鎶曡祫绯荤粺-瀹㈣繍+鐗╂祦 2026.7).xls'
@@ -288,7 +348,20 @@
typeLabel(t) { return TYPE_LABELS[t] || t },
downloadTemplate() {
if (!this.templateUrl) return
- window.open('/api/templates/' + this.templateUrl)
+ const name = this.templateUrl.split('/').pop()
+ api.get('/templates/' + this.templateUrl, { responseType: 'blob' })
+ .then(res => {
+ const blob = res instanceof Blob ? res : new Blob([res])
+ const url = window.URL.createObjectURL(blob)
+ const a = document.createElement('a')
+ a.href = url
+ a.download = name
+ document.body.appendChild(a)
+ a.click()
+ window.URL.revokeObjectURL(url)
+ document.body.removeChild(a)
+ })
+ .catch(() => this.$message.error('妯℃澘涓嬭浇澶辫触锛岃绋嶅悗閲嶈瘯'))
},
onModuleChange(key) {
this.importType = this.moduleSel[key] || ''
@@ -314,7 +387,10 @@
investmentSystem: '/import/investmentSystem',
cityBus: '/import/cityBus',
cityTaxi: '/import/cityTaxi',
- cityTaxiAuth: '/import/cityTaxiAuth'
+ cityTaxiAuth: '/import/cityTaxiAuth',
+ wycTotal: '/import/wycTotal',
+ wycOrder: '/import/wycOrder',
+ wycOrderReport: '/import/wycOrderReport'
}
return map[t] || ''
},
@@ -362,6 +438,7 @@
message: ''
}
this.importOne(row).then(() => {
+ this.showImportResult(row)
if ((row.type === 'investment' || row.type === 'investmentLogistics') && row.status === 'success') {
this.checkInvest(this.period)
}
@@ -400,11 +477,15 @@
(f.city ? '锛�' + f.city + '锛�' : '') + '锛氳В鏋� ' + (f.success || 0) + ' 鏉�' +
(f.error ? ' <span style="color:#F56C6C">' + f.error + '</span>' : '') + '</div>'
).join('')
- this.$alert(html, (label || type) + ' 鎵归噺瀵煎叆瀹屾垚锛氬叡 ' + d.total + ' 涓枃浠�' +
- (d.fail > 0 ? '锛屽け璐� ' + d.fail + ' 鏉�' : '') + '锛堟垚鍔� ' + d.success + ' 鏉★級', {
- dangerouslyUseHTMLString: true,
- type: errCount > 0 ? 'warning' : 'success',
- confirmButtonText: '鐭ラ亾浜�'
+ this.showResultDialog({
+ title: (label || type) + ' 鎵归噺瀵煎叆瀹屾垚锛氬叡 ' + d.total + ' 涓枃浠�' +
+ (d.fail > 0 ? '锛屽け璐� ' + d.fail + ' 鏉�' : '') + '锛堟垚鍔� ' + d.success + ' 鏉★級',
+ html: html,
+ level: errCount > 0 ? 'warning' : 'success',
+ columns: [{ key: 'fileName', label: '鏂囦欢鍚�' }, { key: 'city', label: '甯傚窞' },
+ { key: 'success', label: '瑙f瀽鏉℃暟' }, { key: 'error', label: '閿欒' }],
+ rows: files.map(f => ({ fileName: f.fileName || '', city: f.city || '', success: f.success || 0, error: f.error || '' })),
+ fileName: (label || '鎵归噺瀵煎叆') + '_' + this.period + '_瀵煎叆缁撴灉'
})
if (type === 'investment' || type === 'investmentLogistics') {
this.checkInvest(this.period)
@@ -418,6 +499,7 @@
this.$message.error((e.response && e.response.data && e.response.data.message) || '鎵归噺瀵煎叆澶辫触')
})
},
+ acceptOf(type) { return type === 'wycOrderReport' ? '.docx,.doc' : '.xlsx,.xls,.et' },
isCityDirType(t) { return t === 'investCityPassenger' || t === 'investCityLogistics' },
isDirOnlyType(t) { return t === 'investCityPassenger' || t === 'investCityLogistics' },
importCityDir(type) {
@@ -441,12 +523,16 @@
(f.city ? '锛�' + f.city + '锛�' : '') + '锛氳В鏋� ' + (f.success || 0) + ' 涓」鐩�' +
(f.error ? ' <span style="color:#F56C6C">' + f.error + '</span>' : '') + '</div>'
).join('')
- this.$alert(html, '甯傚窞鍗曡〃鎵归噺瀵煎叆瀹屾垚锛氬叡 ' + d.total + ' 鏉★紝鎴愬姛 ' + d.success + ' 鏉�' +
- (d.fail > 0 ? '锛屽け璐� ' + d.fail + ' 鏉�' : '') +
- '锛堝崄浜斾簲椤圭洰鍖归厤 ' + d.fiveYearMatched + '/' + d.fiveYearTemplateProjects + '锛�', {
- dangerouslyUseHTMLString: true,
- type: errCount > 0 ? 'warning' : 'success',
- confirmButtonText: '鐭ラ亾浜�'
+ this.showResultDialog({
+ title: '甯傚窞鍗曡〃鎵归噺瀵煎叆瀹屾垚锛氬叡 ' + d.total + ' 鏉★紝鎴愬姛 ' + d.success + ' 鏉�' +
+ (d.fail > 0 ? '锛屽け璐� ' + d.fail + ' 鏉�' : '') +
+ '锛堝崄浜斾簲椤圭洰鍖归厤 ' + d.fiveYearMatched + '/' + d.fiveYearTemplateProjects + '锛�',
+ html: html,
+ level: errCount > 0 ? 'warning' : 'success',
+ columns: [{ key: 'fileName', label: '鏂囦欢鍚�' }, { key: 'city', label: '甯傚窞' },
+ { key: 'success', label: '瑙f瀽椤圭洰鏁�' }, { key: 'error', label: '閿欒' }],
+ rows: files.map(f => ({ fileName: f.fileName || '', city: f.city || '', success: f.success || 0, error: f.error || '' })),
+ fileName: '甯傚窞鍗曡〃瀵煎叆缁撴灉_' + this.period
})
this.afterImport()
})
@@ -455,6 +541,20 @@
this.$message.error((e.response && e.response.data && e.response.data.message) || '鎵归噺瀵煎叆澶辫触')
})
.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.showResultDialog({
+ title: '鏁版嵁瀵煎叆澶辫触',
+ html: (msg || '鏁版嵁瀵煎叆澶辫触锛岃瑙佷笅鏂瑰け璐ヨ褰�').replace(/\n/g, '<br>'),
+ level: 'error'
+ })
+ }
},
importOne(row) {
if (!this.period) { this.$message.warning('璇峰厛閫夋嫨鎶ヨ〃鏈�'); return Promise.resolve() }
@@ -490,10 +590,53 @@
map[key] = { totalRows: r.totalRows, successRows: r.successRows, failRows: r.failRows, latestId: r.id }
}
})
+ if (map.wycOrderReport && !map.wycOrder) map.wycOrder = map.wycOrderReport
this.overview = map
})
.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)
+ },
+ // 鍗曚釜鏁版嵁绫诲瀷涔熷彲闅愯棌锛坔idden: true锛夛細鍏ュ彛銆佹瑙堛�佹竻绌轰笅鎷夌粺涓�杩囨护
+ typeList(g) {
+ return (g && g.types ? g.types : []).filter(t => !t.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]
@@ -525,14 +668,55 @@
'<br/>瀹為檯锛�' + (x.actualValue || '') + '銆�鍩哄噯锛�' + (x.thresholdValue || '') +
'<br/>宸紓锛�' + (x.deviation || '') + '</div>'
}).join('')
- this.$alert(html, '鎶曡祫鏁版嵁涓庢姇璧勭郴缁熶笉涓�鑷达紙' + pending.length + ' 鏉★級', {
- dangerouslyUseHTMLString: true, type: 'warning', confirmButtonText: '鐭ラ亾浜�'
+ this.showResultDialog({
+ title: '鎶曡祫鏁版嵁涓庢姇璧勭郴缁熶笉涓�鑷达紙' + pending.length + ' 鏉★級',
+ html: html,
+ level: 'warning',
+ columns: [{ key: 'rule', label: '瑙勫垯' }, { key: 'name', label: '椤圭洰/浼佷笟' },
+ { key: 'actual', label: '瀹為檯鍊�' }, { key: 'base', label: '鍩哄噯鍊�' }, { key: 'dev', label: '宸紓' }],
+ rows: pending.map(x => ({
+ rule: x.ruleName || '',
+ name: x.enterpriseName || x.actualValue || '',
+ actual: x.actualValue || '',
+ base: x.thresholdValue || '',
+ dev: x.deviation || ''
+ })),
+ fileName: '鎶曡祫鏁版嵁涓庢姇璧勭郴缁熶笉涓�鑷確' + this.period
})
} else {
this.$message.success('宸蹭笌鎶曡祫绯荤粺鏍稿锛屾湰鏈堟暟鎹竴鑷�')
}
})
.catch(() => {})
+ },
+ showResultDialog(opts) {
+ const o = opts || {}
+ this.resultDialog = {
+ visible: true,
+ title: o.title || '瀵煎叆缁撴灉',
+ html: o.html || '',
+ level: o.level || '',
+ rows: o.rows || [],
+ columns: o.columns || [],
+ fileName: o.fileName || ('瀵煎叆缁撴灉_' + (this.period || ''))
+ }
+ },
+ exportResultDialog() {
+ const cols = this.resultDialog.columns || []
+ const rows = this.resultDialog.rows || []
+ if (!cols.length || !rows.length) { this.$message.warning('娌℃湁鍙鍑虹殑鏄庣粏'); return }
+ const esc = v => '"' + String(v === null || v === undefined ? '' : v).replace(/"/g, '""') + '"'
+ const lines = [cols.map(c => esc(c.label)).join(',')]
+ rows.forEach(r => lines.push(cols.map(c => esc(r[c.key])).join(',')))
+ const blob = new Blob(['\ufeff' + lines.join('\r\n')], { type: 'text/csv;charset=utf-8' })
+ const url = URL.createObjectURL(blob)
+ const a = document.createElement('a')
+ a.href = url
+ a.download = this.resultDialog.fileName + '.csv'
+ document.body.appendChild(a)
+ a.click()
+ document.body.removeChild(a)
+ URL.revokeObjectURL(url)
},
parseFailDetails(row) {
if (!row || !row.errorDetail) return []
@@ -566,6 +750,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; }
@@ -596,3 +786,17 @@
.module-tabs-head { margin-bottom: 10px; }
.module-tab-pane { min-height: 120px; }
</style>
+
+<style>
+/* 瀵煎叆缁撴灉寮圭獥锛歟l-dialog 榛樿 append-to-body锛孌OM 鎸傚湪 body 涓婏紝scoped 閫夋嫨鍣ㄥ尮閰嶄笉鍒帮紝蹇呴』鍐欏叏灞� */
+.import-result-dialog { border-radius: 10px; overflow: hidden; }
+.import-result-dialog .el-dialog__header { cursor: move; user-select: none; -webkit-user-select: none; }
+.import-result-dialog .el-dialog__headerbtn { cursor: pointer; }
+.import-result-dialog .el-dialog__body { max-height: calc(100vh - 210px); overflow-y: auto; overscroll-behavior: contain; padding: 12px 20px; }
+.import-result-dialog .el-dialog__footer { border-top: 1px solid #EBEEF5; padding: 10px 20px; }
+.import-result-dialog .ird-body { line-height: 1.7; font-size: 13px; color: #303133; }
+.import-result-dialog .ird-level { margin-bottom: 8px; font-weight: 600; }
+.import-result-dialog .ird-success { color: #67C23A; }
+.import-result-dialog .ird-warning { color: #E6A23C; }
+.import-result-dialog .ird-error { color: #F56C6C; }
+</style>
--
Gitblit v1.9.1