From 2b7e900cd5622b4de6e519ec8563283eaf6d5c50 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Mon, 2 Jun 2025 09:48:46 +0800 Subject: [PATCH] update --- docker-compose.yml | 2 +- src/views/ChatAgentView.vue | 334 ++++++++++++++---------------------- 2 files changed, 134 insertions(+), 202 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 04256be..3219966 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: build: context: . dockerfile: Dockerfile - image: tradus-web:1.3.35 + image: tradus-web:1.3.36 container_name: tradus-web ports: - '6000:80' diff --git a/src/views/ChatAgentView.vue b/src/views/ChatAgentView.vue index b12e374..fc1c340 100644 --- a/src/views/ChatAgentView.vue +++ b/src/views/ChatAgentView.vue @@ -59,6 +59,10 @@ const conversationToRename = ref(null) const newConversationName = ref('') const renameInputRef = ref(null) +// 流式输出控制 +const currentTaskId = ref('') +const streamingAbortController = ref(null) + // 根据环境选择API基础URL const apiBaseUrl = import.meta.env.MODE === 'development' ? 'http://127.0.0.1:8000' : 'https://api.ibtc.work' @@ -201,6 +205,9 @@ const sendMessage = async () => { isLoading.value = true await scrollToBottom() + // 创建AbortController用于取消请求 + streamingAbortController.value = new AbortController() + try { const response = await http.post(`${apiBaseUrl}/analysis/chat-messages`, { message: message, @@ -233,6 +240,11 @@ const sendMessage = async () => { let buffer = '' while (true) { + // 检查是否被中止 + if (streamingAbortController.value?.signal.aborted) { + break + } + const { done, value } = await reader.read() if (done) break @@ -253,6 +265,11 @@ const sendMessage = async () => { switch (data.event) { case 'workflow_started': + // 提取task_id + if (data.task_id) { + currentTaskId.value = data.task_id + console.log('获取到task_id:', data.task_id) + } break case 'node_started': break @@ -292,12 +309,16 @@ const sendMessage = async () => { } } assistantMessage.isStreaming = false + // 清理task_id + currentTaskId.value = '' break case 'error': const errorMessage = data.error || '未知错误' assistantMessage.content = `错误: ${errorMessage}` assistantMessage.isStreaming = false + // 清理task_id + currentTaskId.value = '' await scrollToBottom() break @@ -309,6 +330,7 @@ const sendMessage = async () => { console.error('解析响应数据出错:', error, '原始数据:', line) assistantMessage.content = '错误: 解析响应数据时出错,请稍后重试' assistantMessage.isStreaming = false + currentTaskId.value = '' } } } @@ -323,6 +345,8 @@ const sendMessage = async () => { assistantMessage.isStreaming = false } finally { isLoading.value = false + currentTaskId.value = '' + streamingAbortController.value = null await scrollToBottom() } } @@ -504,6 +528,40 @@ const confirmDelete = async () => { cancelDelete() } + +// 停止流式输出 +const stopStreaming = async () => { + if (!currentTaskId.value) return + + try { + const response = await http.post(`${apiBaseUrl}/analysis/stop_streaming`, { + task_id: currentTaskId.value, + }) + + if (response.ok) { + console.log('停止流式输出成功') + } else { + console.error('停止流式输出失败') + } + } catch (error) { + console.error('停止流式输出失败:', error) + } + + // 无论是否成功,都清理状态 + currentTaskId.value = '' + if (streamingAbortController.value) { + streamingAbortController.value.abort() + streamingAbortController.value = null + } + + // 停止当前流式消息 + const lastMessage = messages.value[messages.value.length - 1] + if (lastMessage && lastMessage.isStreaming) { + lastMessage.isStreaming = false + } + + isLoading.value = false +}