fix(web): 优化任务列表加载与轮询逻辑
- 抛出加载失败错误而非静默清空任务列表 - 在加载任务失败时增加控制台错误日志输出 - 添加检查任务完成并停止轮询的函数 - 任务轮询采用异步方式并在适当时停止 - 使用常量替换硬编码对话框宽度限制和默认值 - 组件卸载时停止任务轮询定时器 - 移除已废弃的兼容性字段和方法映射代码
This commit is contained in:
parent
18e2e372a0
commit
4f74eec055
42
web/main.js
42
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
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue