From 736d644792fbe7d9f19b74a7d6b48e1eaf2efc4f Mon Sep 17 00:00:00 2001 From: DXC Date: Tue, 15 Sep 2026 17:42:51 +0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=E6=89=8B=E5=8A=A8=E9=87=87?= =?UTF-8?q?=E9=9B=86=E6=94=B9=E4=B8=BA=E7=9C=9F=E5=AE=9E=E7=AD=89=E5=BE=85?= =?UTF-8?q?=EF=BC=8C=E5=8E=BB=E6=8E=89=E5=9B=BA=E5=AE=9A=E5=BB=B6=E6=97=B6?= =?UTF-8?q?=E7=9A=84=E5=81=87=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原实现: runningTask.value=true await axios.post(`${API_BASE}/api/run_monitor`) setTimeout(()=>fetchData(), 3000) setTimeout(()=>runningTask.value=false, 1000) 后端 run_monitor 里的 execute_monitor_task() 是同步阻塞的,105 台设备逐个登录、 请求目录、下载文件,实测要跑几分钟。原实现发完请求就固定等 3 秒刷新,此时爬虫 还在跑,拿到的是上一次的数据;1 秒后 loading 也复位了,用户以为跑完了 —— 这就是 “点检测没反应/数据不更新”的来源,和之前反复修的那类症状同源。 - 显式传 timeout: 600000(10 分钟),硬抗后端同步阻塞,避免请求先于爬虫断开。 - 改为 await fetchData(),等后端真正返回后再取数,不再用固定延时猜。 - try/catch/finally 收敛:成功提示、失败把后端 message 透出来、loading 一律复位。 - 开头加 runningTask 守卫,防止重复点击并发触发多次采集。 构建产物 web_dist 已同步更新(index-0c48fe24.js),按 .gitignore 不入库。 --- .../光谱数据监控/src/views/Dashboard.vue | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/zhandianxinxi/光谱数据监控/src/views/Dashboard.vue b/zhandianxinxi/光谱数据监控/src/views/Dashboard.vue index 0120ee6..ccc3224 100644 --- a/zhandianxinxi/光谱数据监控/src/views/Dashboard.vue +++ b/zhandianxinxi/光谱数据监控/src/views/Dashboard.vue @@ -535,7 +535,22 @@ const handleAddDeviceSubmit = async () => { if (!newDeviceForm.name) return; awa const handleDeviceClick = (row) => { if (!row.is_hidden && dataMonitorRef.value) dataMonitorRef.value.open(row) } const openLogCenter = (row) => { if (maintenanceLogsRef.value) maintenanceLogsRef.value.open(row ? { deviceName: row.name } : null) } const openIoTBinder = () => { if (iotBinderRef.value) iotBinderRef.value.open() } -const runManualMonitor = async () => { runningTask.value=true; await axios.post(`${API_BASE}/api/run_monitor`); setTimeout(()=>fetchData(), 3000); setTimeout(()=>runningTask.value=false, 1000) } +const runManualMonitor = async () => { + if (runningTask.value) return; // 防止重复点击 + runningTask.value = true; + try { + // 后端 execute_monitor_task() 是同步阻塞的,105 台设备逐个登录+下载要跑几分钟, + // 必须给足超时,否则请求会先断开、爬虫却还在后台跑 + await axios.post(`${API_BASE}/api/run_monitor`, {}, { timeout: 600000 }); + ElMessage.success('手动采集完成!'); + await fetchData(); // 等后端真正跑完再取数,不再用固定 setTimeout 瞎猜 + } catch (error) { + console.error("手动采集失败:", error); + ElMessage.error('采集失败或超时:' + (error.response?.data?.message || error.message)); + } finally { + runningTask.value = false; // 无论成功失败都关掉 loading + } +} const handleEditSite = (row) => { row.tempSite = row.install_site; row.isEditingSite = true; nextTick(() => document.querySelector('.site-input-inner input')?.focus()) } const saveSite = async (row) => { if(!row.isEditingSite)return; row.isEditingSite=false; await axios.post(`${API_BASE}/api/update_site`, {name:row.name, site:row.tempSite}); row.install_site=row.tempSite } const handleMaintenanceBeforeChange = (row) => { return new Promise(r => { axios.post(`${API_BASE}/api/toggle_maintenance`, {name:row.name, is_maintaining:!row.is_maintaining}).then(() => {row.is_maintaining=!row.is_maintaining; fetchData(); r(true)}).catch(()=>r(false)) }) }