fix(frontend): 手动采集改为真实等待,去掉固定延时的假刷新

原实现:

    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 不入库。
This commit is contained in:
DXC
2026-09-15 17:42:51 +08:00
parent 72bab25f3f
commit 736d644792

View File

@ -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)) }) }