From 4f74eec055a0cc570e74b923a6c7cbafb7e9dc28 Mon Sep 17 00:00:00 2001 From: zhouyonggao <1971162852@qq.com> Date: Wed, 17 Dec 2025 09:29:02 +0800 Subject: [PATCH] =?UTF-8?q?fix(web):=20=E4=BC=98=E5=8C=96=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E5=88=97=E8=A1=A8=E5=8A=A0=E8=BD=BD=E4=B8=8E=E8=BD=AE?= =?UTF-8?q?=E8=AF=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 抛出加载失败错误而非静默清空任务列表 - 在加载任务失败时增加控制台错误日志输出 - 添加检查任务完成并停止轮询的函数 - 任务轮询采用异步方式并在适当时停止 - 使用常量替换硬编码对话框宽度限制和默认值 - 组件卸载时停止任务轮询定时器 - 移除已废弃的兼容性字段和方法映射代码 --- web/main.js | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/web/main.js b/web/main.js index 611f924..66171a5 100644 --- a/web/main.js +++ b/web/main.js @@ -1215,8 +1215,7 @@ const app = createApp({ } const res = await fetch(API_BASE + '/api/exports?' + qs.toString() + (qsUser() ? ('&' + qsUser().slice(1)) : '')); if (!res.ok) { - state.jobs = []; - return; + throw new Error(`加载任务列表失败: ${res.status}`); } const data = await res.json(); const payload = data?.data || data || {}; @@ -1224,19 +1223,34 @@ const app = createApp({ state.jobs = arr; state.jobsTotal = Number(payload.total || 0); state.jobsPage = Number(payload.page || page); - } catch (_e) { + } catch (e) { + console.error('加载任务列表失败:', e); state.jobs = []; } }; let jobsPollTimer = null; + + /** + * 检查是否所有任务都已完成,若是则停止轮询 + */ + const checkAndStopPollingIfComplete = () => { + const hasRunningJob = state.jobs.some(job => + job.status === 'queued' || job.status === 'running' + ); + if (!hasRunningJob && state.jobs.length > 0) { + stopJobsPolling(); + } + }; + const startJobsPolling = () => { if (jobsPollTimer) return; - jobsPollTimer = setInterval(() => { + jobsPollTimer = setInterval(async () => { if (state.jobsVisible) { - loadJobs(state.jobsPage); + await loadJobs(state.jobsPage); + checkAndStopPollingIfComplete(); } - }, 1000); + }, CONSTANTS.JOBS_POLL_INTERVAL); }; const stopJobsPolling = () => { @@ -1338,18 +1352,18 @@ const app = createApp({ // ==================== 对话框尺寸管理 ==================== const clampWidth = (w) => { - const n = Math.max(500, Math.min(1400, w)); + const n = Math.max(CONSTANTS.DIALOG_MIN_WIDTH, Math.min(CONSTANTS.DIALOG_MAX_WIDTH, w)); return n + 'px'; }; const resizeDialog = (kind, delta) => { if (kind === 'create') { - const cur = parseInt(String(state.createWidth).replace('px', '') || '900', 10); + const cur = parseInt(String(state.createWidth).replace('px', '') || String(CONSTANTS.DIALOG_DEFAULT_WIDTH), 10); const next = clampWidth(cur + delta); state.createWidth = next; localStorage.setItem('tplDialogWidth', next); } else if (kind === 'edit') { - const cur = parseInt(String(state.editWidth).replace('px', '') || '600', 10); + const cur = parseInt(String(state.editWidth).replace('px', '') || String(CONSTANTS.DIALOG_EDIT_DEFAULT_WIDTH), 10); const next = clampWidth(cur + delta); state.editWidth = next; localStorage.setItem('tplEditDialogWidth', next); @@ -1429,6 +1443,11 @@ const app = createApp({ loadTemplates(); loadFieldsMeta(state.form.datasource, state.form.orderType); + // 组件销毁时清理定时器 + Vue.onUnmounted(() => { + stopJobsPolling(); + }); + // ==================== 返回 ==================== return { ...Vue.toRefs(state), @@ -1483,11 +1502,6 @@ const app = createApp({ editFieldTreeData, onTreeCheck, setTreeChecked, - // 兼容性保留(已废弃) - createFieldsCascader: createFieldsTree, - editFieldsCascader: editFieldsTree, - onCascaderVisible, - onFieldsSelChange, hasUserId, currentUserId };