From d8fcafcd94bcc0f6f276d0ebbe532e91da269475 Mon Sep 17 00:00:00 2001 From: duorameng <2997944583@qq.com> Date: Thu, 30 Apr 2026 16:11:25 +0800 Subject: [PATCH] chore: try to add stop task more info --fix pass status #75 --- web/src/views/history/History.vue | 4 +++- web/src/views/history/LogViewer.vue | 5 ++++- web/src/views/tasks/Tasks.vue | 30 +++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/web/src/views/history/History.vue b/web/src/views/history/History.vue index c59ca14..1af5453 100644 --- a/web/src/views/history/History.vue +++ b/web/src/views/history/History.vue @@ -494,7 +494,9 @@ watch(() => route.query, (newQuery) => { + :is-stopping="isStopping" + :content="decompressedOutput" + @stop="stopTask" /> diff --git a/web/src/views/history/LogViewer.vue b/web/src/views/history/LogViewer.vue index 8b27920..5226ed2 100644 --- a/web/src/views/history/LogViewer.vue +++ b/web/src/views/history/LogViewer.vue @@ -10,10 +10,12 @@ const props = withDefaults(defineProps<{ title?: string loading?: boolean variant?: 'full' | 'simple' + isStopping?: boolean emptyTitle?: string emptyDescription?: string }>(), { - variant: 'simple' + variant: 'simple', + isStopping: false }) const emit = defineEmits<{ @@ -70,6 +72,7 @@ onUnmounted(() => { :content="content" :title="title" :loading="loading" + :is-stopping="isStopping" :variant="isFullscreen ? 'simple' : variant" :empty-title="emptyTitle" :empty-description="emptyDescription" diff --git a/web/src/views/tasks/Tasks.vue b/web/src/views/tasks/Tasks.vue index bb3f91a..c534afc 100644 --- a/web/src/views/tasks/Tasks.vue +++ b/web/src/views/tasks/Tasks.vue @@ -263,6 +263,7 @@ const logContent = ref('') const logEmptyTitle = ref(undefined) const logEmptyDesc = ref(undefined) let logSocket: WebSocket | null = null +let durationTimer: ReturnType | null = null function cleanupLogSocket() { if (logSocket) { @@ -275,15 +276,24 @@ function cleanupLogSocket() { } } +function cleanupDurationTimer() { + if (durationTimer) { + clearInterval(durationTimer) + durationTimer = null + } +} + watch(showLogViewer, (val) => { if (!val) { cleanupLogSocket() + cleanupDurationTimer() logContent.value = '' } }) onUnmounted(() => { cleanupLogSocket() + cleanupDurationTimer() }) import { decompressFromBase64 } from '@/utils/decompress' @@ -327,6 +337,26 @@ async function viewLogs(taskId: string) { logSocket.onmessage = (event) => { logContent.value += event.data } + + // 启动状态轮询 + cleanupDurationTimer() + const updateLogStatus = async () => { + try { + const res = await api.logs.get(latestLog.id) + if (res && selectedLog.value && selectedLog.value.id === latestLog.id) { + selectedLog.value.duration = res.duration + selectedLog.value.status = res.status + selectedLog.value.end_time = res.end_time + + // 如果任务结束,停止轮询 + if (res.status !== TASK_STATUS.RUNNING) { + cleanupDurationTimer() + loadTasks() // 同时刷新列表状态 + } + } + } catch { /* ignore */ } + } + durationTimer = setInterval(updateLogStatus, 3000) } else { // 如果没有日志,构造一个基础的任务信息对象用于展示弹窗 const task = tasks.value.find(t => t.id === taskId)