From 41487b9a8ad1353c21dd1ac2bfafcf8d1d4f34e4 Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期五, 28 八月 2026 17:09:47 +0800
Subject: [PATCH] feat: 所有前端 API 请求加超时保护,超时/网络异常优雅提示,不再无限 pending
---
traffic-audit-web/src/views/DataImport.vue | 48 +++++++++++++++++++++++++++++++++---------------
1 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/traffic-audit-web/src/views/DataImport.vue b/traffic-audit-web/src/views/DataImport.vue
index f311c07..dd789fa 100644
--- a/traffic-audit-web/src/views/DataImport.vue
+++ b/traffic-audit-web/src/views/DataImport.vue
@@ -1,6 +1,6 @@
<template>
- <el-container>
- <el-header>浜ら�氱粺璁℃姤琛ㄥ鏍哥郴缁� - 鏁版嵁瀵煎叆</el-header>
+ <el-container direction="vertical">
+ <app-header title="浜ら�氱粺璁℃姤琛ㄥ鏍哥郴缁� - 鏁版嵁瀵煎叆"></app-header>
<el-container>
<el-aside width="200px">
<el-menu router default-active="/import">
@@ -12,7 +12,6 @@
<el-menu-item index="/report">鎶ヨ〃鐢熸垚</el-menu-item>
<el-menu-item index="/rules">瑙勫垯绠$悊</el-menu-item>
<el-menu-item index="/users">鐢ㄦ埛绠$悊</el-menu-item>
- <el-menu-item index="/login" @click="logout">閫�鍑虹櫥褰�</el-menu-item>
</el-menu>
</el-aside>
<el-main>
@@ -27,7 +26,7 @@
<el-card shadow="hover" class="import-card" style="margin-bottom:15px">
<div class="card-head">鏈湀瀵煎叆杩涘害锛坽{ period || '鏈�夋嫨鎶ヨ〃鏈�' }}锛�
- <el-button type="text" icon="el-icon-refresh" style="float:right" @click="loadOverview">鍒锋柊</el-button>
+ <el-button type="text" icon="el-icon-refresh" style="float:right" @click="loadData">鍒锋柊</el-button>
</div>
<div v-if="!period" class="tip">璇峰厛鍦ㄤ笂鏂归�夋嫨鎶ヨ〃鏈�</div>
<div v-else class="overview-grid">
@@ -159,6 +158,8 @@
<div class="tip">鍗曞嚮鏂囦欢澶硅繘鍏ュ瓙鏂囦欢澶癸紱<b>鍙屽嚮鐩爣鏂囦欢澶圭珛鍗冲鍏�</b>鍏朵腑鍏ㄩ儴 Excel锛涗篃鍙繘鍏ュ悗鐐逛笅鏂规寜閽�傚鍏ユ椂浼氭寜鏂囦欢鍚嶈嚜鍔ㄨ瘑鍒湀浠姐��</div>
<div v-if="dirExcelCount === 0" class="tip">褰撳墠鏂囦欢澶瑰唴娌℃湁 Excel 鏂囦欢锛�.xlsx/.xls锛�</div>
<div v-else class="tip">褰撳墠鏂囦欢澶瑰唴 Excel锛歿{ dirExcelCount }} 涓� 鈥斺�� {{ dirFiles.slice(0, 6).join('銆�') }}{{ dirFiles.length > 6 ? ' 绛�' : '' }}锛堜粎瀵煎叆鐩存帴浣嶄簬璇ユ枃浠跺す鐨勬枃浠讹級</div>
+ <div v-if="dirDirsTruncated" class="tip">瀛愭枃浠跺す杩囧锛屼粎鏄剧ず鍓� 300 涓�</div>
+ <div v-if="dirFilesTruncated" class="tip">Excel 鏂囦欢杩囧锛堝叡 {{ dirExcelCount }} 涓級锛屼粎鏄剧ず鍓� 300 涓�</div>
</div>
<span slot="footer">
<el-button size="small" @click="dirDialog = false">鍙栨秷</el-button>
@@ -169,7 +170,7 @@
<el-card shadow="never" style="margin-top:15px" class="batch-card">
<div slot="header" class="card-head">
瀵煎叆璁板綍锛坽{ period || '鍏ㄩ儴鎶ヨ〃鏈�' }}锛�
- <el-button type="text" icon="el-icon-refresh" style="float:right" @click="loadBatches">鍒锋柊</el-button>
+ <el-button type="text" icon="el-icon-refresh" style="float:right" @click="loadData">鍒锋柊</el-button>
</div>
<el-table :data="batches" border size="small" v-loading="batchLoading" style="width:100%">
<el-table-column prop="importType" label="瀵煎叆绫诲瀷" width="150">
@@ -206,6 +207,7 @@
</el-container>
</template>
<script>
+import AppHeader from '@/components/AppHeader.vue'
import api from '@/api'
const TYPE_LABELS = {
h2032: 'H203-2鏈堟姤', transportAuth: '杩愭斂杞﹁締', trackMileage: '杞ㄨ抗閲岀▼', scaleSplit: '瑙勪笂瑙勪笅鎷嗗垎',
@@ -229,6 +231,7 @@
INVEST_SYSTEM: 'investmentSystem'
}
export default {
+ components: { AppHeader },
name: 'DataImport',
data() {
return {
@@ -242,7 +245,9 @@
dirCurrent: '',
dirParent: '',
dirDirs: [],
+ dirDirsTruncated: false,
dirExcelCount: 0,
+ dirFilesTruncated: false,
dirFiles: [],
dirLoading: false,
dirImporting: false,
@@ -389,7 +394,7 @@
this.importType = this.moduleSel[key] || ''
this.dirPath = (this.importType && localStorage.getItem('dirLast_' + this.importType)) || ''
},
- onPeriodChange() { this.loadOverview(); this.loadBatches() },
+ onPeriodChange() { this.loadData() },
endpoint(t) {
const map = {
h2032: '/import/h2032',
@@ -427,10 +432,12 @@
this.dirCurrent = d.current || ''
this.dirParent = d.parent || ''
this.dirDirs = d.dirs || []
+ this.dirDirsTruncated = !!d.dirsTruncated
this.dirExcelCount = d.excelCount || 0
this.dirFiles = d.files || []
+ this.dirFilesTruncated = !!d.filesTruncated
})
- .catch(e => { this.$message.error((e.response && e.response.data && e.response.data.message) || '鐩綍鍔犺浇澶辫触') })
+ .catch(e => { if (e && e._toast) return; this.$message.error((e.response && e.response.data && e.response.data.message) || '鐩綍鍔犺浇澶辫触') })
.finally(() => { this.dirLoading = false })
},
goDirParent() { if (this.dirParent) this.loadDirs(this.dirParent) },
@@ -457,6 +464,11 @@
const d = (res && res.data) || {}
const files = (d.files || []).filter(n => /\.(xlsx|xls)$/i.test(n))
if (!files.length) { this.$message.warning('璇ョ洰褰曟病鏈� Excel 鏂囦欢锛�.xlsx/.xls锛夛細' + dir); this.dirImporting = false; return }
+ if (files.length > 60) {
+ this.dirImporting = false
+ this.$message.warning('鐩綍鍐� Excel 鏂囦欢杩囧锛�' + files.length + ' 涓級锛屼负閬垮厤娴忚鍣ㄥ崱椤胯鍒嗘壒瀵煎叆锛堟瘡鎵逛笉瓒呰繃 60 涓級')
+ return
+ }
localStorage.setItem('dirLast_' + type, dir)
this.dirPath = dir
this.dirImportFiles = files.map(n => ({ name: n, status: 'pending', period: '', msg: '' }))
@@ -493,6 +505,7 @@
})
.catch(e => {
this.dirImporting = false
+ if (e && e._toast) return
this.$message.error((e.response && e.response.data && e.response.data.message) || '鐩綍涓嶅瓨鍦ㄦ垨鏃犳硶璁块棶锛�' + dir)
})
},
@@ -573,6 +586,7 @@
this.afterImport()
})
.catch(e => {
+ if (e && e._toast) return
this.$message.error((e.response && e.response.data && e.response.data.message) || '鎵归噺瀵煎叆澶辫触')
})
.finally(() => { this.cityDirLoading = false })
@@ -643,13 +657,17 @@
run(0)
})
},
- afterImport() { this.loadOverview(); this.loadBatches() },
- loadOverview() {
- if (!this.period) return
- api.get('/import/batches', { params: { period: this.period, limit: 200 } })
+ afterImport() { this.loadData() },
+ loadData() {
+ if (this.batchLoading) return
+ this.batchLoading = true
+ const params = { limit: 200 }
+ if (this.period) params.period = this.period
+ api.get('/import/batches', { params })
.then(res => {
- const map = {}
const records = (res.data && res.data.records) || []
+ this.batches = records.slice(0, 50)
+ const map = {}
records.forEach(r => {
const key = this.batchKeyToType(r.importType)
if (!key) return
@@ -660,7 +678,8 @@
})
this.overview = map
})
- .catch(() => {})
+ .catch(e => { if (!e || !e._toast) this.$message.error('瀵煎叆璁板綍鍔犺浇澶辫触锛岃鍒锋柊閲嶈瘯') })
+ .finally(() => { this.batchLoading = false })
},
batchKeyToType(k) {
if (BATCH_TYPE_MAP[k]) return BATCH_TYPE_MAP[k]
@@ -712,8 +731,7 @@
}
},
mounted() {
- this.loadBatches()
- this.loadOverview()
+ this.loadData()
}
}
</script>
--
Gitblit v1.9.1