feat:RESTful API架构改WebSocket架构-执行结果可以分步显示版本

This commit is contained in:
liailing1026
2026-01-22 17:22:30 +08:00
parent 1c8036adf1
commit 786c674d21
15 changed files with 2591 additions and 308 deletions

View File

@@ -3,6 +3,7 @@ import { ref, onMounted, computed, reactive, nextTick } from 'vue'
import SvgIcon from '@/components/SvgIcon/index.vue'
import { useAgentsStore, useConfigStore } from '@/stores'
import api from '@/api'
import websocket from '@/utils/websocket'
import { changeBriefs } from '@/utils/collaboration_Brief_FrontEnd.ts'
import { ElMessage } from 'element-plus'
import AssignmentButton from './TaskTemplate/TaskSyllabus/components/AssignmentButton.vue'
@@ -18,6 +19,10 @@ const triggerOnFocus = ref(true)
const isFocus = ref(false)
const hasAutoSearched = ref(false)
const isExpanded = ref(false)
// 添加一个状态来跟踪是否正在填充步骤数据
const isFillingSteps = ref(false)
// 存储当前填充任务的取消函数
const currentStepAbortController = ref<{ cancel: () => void } | null>(null)
// 解析URL参数
function getUrlParam(param: string): string | null {
@@ -83,6 +88,39 @@ function resetTextareaHeight() {
})
}
// 停止填充数据的处理函数
async function handleStop() {
try {
// 通过 WebSocket 发送停止信号
if (websocket.connected) {
await websocket.send('stop_generation', {
goal: searchValue.value
})
ElMessage.success('已发送停止信号,正在停止生成...')
} else {
ElMessage.warning('WebSocket 未连接,无法停止')
}
} catch (error) {
console.error('停止生成失败:', error)
ElMessage.error('停止生成失败')
} finally {
// 无论后端是否成功停止,都重置状态
isFillingSteps.value = false
currentStepAbortController.value = null
}
}
// 处理按钮点击事件
function handleButtonClick() {
if (isFillingSteps.value) {
// 如果正在填充数据,点击停止
handleStop()
} else {
// 否则开始搜索
handleSearch()
}
}
async function handleSearch() {
// 用于标记大纲是否成功加载
let outlineLoaded = false
@@ -103,6 +141,11 @@ async function handleSearch() {
inputs: []
})
// 检查是否已被停止
if (!isFillingSteps.value && currentStepAbortController.value) {
return
}
// 处理简报数据格式
outlineData['Collaboration Process'] = changeBriefs(outlineData['Collaboration Process'])
@@ -111,6 +154,9 @@ async function handleSearch() {
outlineLoaded = true
emit('search', searchValue.value)
// 开始填充步骤详情,设置状态
isFillingSteps.value = true
// 并行填充所有步骤的详情
const steps = outlineData['Collaboration Process'] || []
@@ -118,6 +164,12 @@ async function handleSearch() {
const fillStepWithRetry = async (step: any, retryCount = 0): Promise<void> => {
const maxRetries = 2 // 最多重试2次
// 检查是否已停止
if (!isFillingSteps.value) {
console.log('检测到停止信号,跳过步骤填充')
return
}
try {
if (!step.StepName) {
console.warn('步骤缺少 StepName跳过填充详情')
@@ -135,6 +187,12 @@ async function handleSearch() {
}
})
// 再次检查是否已停止(在 API 调用后)
if (!isFillingSteps.value) {
console.log('检测到停止信号,跳过更新步骤详情')
return
}
// 更新该步骤的详情到 store
updateStepDetail(step.StepName, detailedStep)
} catch (error) {
@@ -166,6 +224,9 @@ async function handleSearch() {
}
} finally {
triggerOnFocus.value = true
// 完成填充,重置状态
isFillingSteps.value = false
currentStepAbortController.value = null
// 如果大纲加载失败确保关闭loading
if (!outlineLoaded) {
agentsStore.setAgentRawPlan({ loading: false })
@@ -255,18 +316,24 @@ onMounted(() => {
class="task-button"
color="linear-gradient(to right, #00C7D2, #315AB4)"
size="large"
title="点击搜索任务"
:title="isFillingSteps ? '点击停止生成' : '点击搜索任务'"
circle
:loading="agentsStore.agentRawPlan.loading"
:disabled="!searchValue"
@click.stop="handleSearch"
@click.stop="handleButtonClick"
>
<SvgIcon
v-if="!agentsStore.agentRawPlan.loading"
v-if="!agentsStore.agentRawPlan.loading && !isFillingSteps"
icon-class="paper-plane"
size="18px"
color="#ffffff"
/>
<SvgIcon
v-if="!agentsStore.agentRawPlan.loading && isFillingSteps"
icon-class="stoprunning"
size="30px"
color="#ffffff"
/>
</el-button>
</div>
<AssignmentButton v-if="planReady" @click="openAgentAllocationDialog" />