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)