From a08c70db67e49bf6cd125df04ebaf68c26f0d8dd Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期日, 20 九月 2026 16:19:16 +0800
Subject: [PATCH] feat(投资): 市州月报统一填报模板 + 县(市、区)列解析 + 表头行判定收紧
---
traffic-audit-web/src/views/DataImport.vue | 111 +++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 94 insertions(+), 17 deletions(-)
diff --git a/traffic-audit-web/src/views/DataImport.vue b/traffic-audit-web/src/views/DataImport.vue
index caa322a..deb64c6 100644
--- a/traffic-audit-web/src/views/DataImport.vue
+++ b/traffic-audit-web/src/views/DataImport.vue
@@ -150,6 +150,19 @@
: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>
@@ -193,6 +206,7 @@
clearDialog: false,
clearScope: 'all',
clearTypes: [],
+ resultDialog: { visible: false, title: '', html: '', rows: [], columns: [], fileName: '', level: '' },
sideOpen: false,
result: '',
error: '',
@@ -463,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)
@@ -505,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()
})
@@ -527,10 +549,10 @@
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: '鐭ラ亾浜�'
+ this.showResultDialog({
+ title: '鏁版嵁瀵煎叆澶辫触',
+ html: (msg || '鏁版嵁瀵煎叆澶辫触锛岃瑙佷笅鏂瑰け璐ヨ褰�').replace(/\n/g, '<br>'),
+ level: 'error'
})
}
},
@@ -646,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 []
@@ -723,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