diff --git a/frontend/src/layout/components/Main/Task.vue b/frontend/src/layout/components/Main/Task.vue index eff3ba1..286ede1 100644 --- a/frontend/src/layout/components/Main/Task.vue +++ b/frontend/src/layout/components/Main/Task.vue @@ -71,6 +71,77 @@ function handleBlur() { }, 200) } +// 🆕 预加载所有任务的智能体评分数据(顺序加载,确保任务详情已填充) +async function preloadAllTaskAgentScores(outlineData: any, goal: string) { + const tasks = outlineData['Collaboration Process'] || [] + + if (tasks.length === 0) { + console.log('ℹ️ 没有任务需要预加载评分数据') + return + } + + console.log(`🚀 开始预加载 ${tasks.length} 个任务的智能体评分数据...`) + + // 🆕 顺序预加载:等待每个任务详情填充完成后再预加载其评分 + for (const task of tasks) { + // 确保任务有 Id + if (!task.Id) { + task.Id = `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}` + } + + const taskId = task.Id + + // 检查是否已有缓存数据 + if (agentsStore.hasTaskScoreData(taskId)) { + console.log(`⏭️ 任务 "${task.StepName}" (${taskId}) 已有缓存数据,跳过`) + continue + } + + // 🆕 等待任务详情填充完成(通过检查 AgentSelection 是否存在) + // 最多等待 60 秒,超时则跳过该任务 + let waitCount = 0 + const maxWait = 60 // 60 * 500ms = 30秒 + while (!task.AgentSelection && waitCount < maxWait) { + await new Promise(resolve => setTimeout(resolve, 500)) + waitCount++ + } + + if (!task.AgentSelection) { + console.warn(`⚠️ 任务 "${task.StepName}" (${taskId}) 详情未填充完成,跳过评分预加载`) + continue + } + + try { + // 调用初始化接口获取评分数据 + const agentScores = await api.agentSelectModifyInit({ + goal: goal, + stepTask: { + StepName: task.StepName, + TaskContent: task.TaskContent, + InputObject_List: task.InputObject_List, + OutputObject: task.OutputObject + } + }) + + // 提取维度列表 + const firstAgent = Object.keys(agentScores)[0] + const aspectList = firstAgent ? Object.keys(agentScores[firstAgent] || {}) : [] + + // 存储到 store(按任务ID存储) + agentsStore.setTaskScoreData(taskId, { + aspectList, + agentScores + }) + + console.log(`✅ 任务 "${task.StepName}" (${taskId}) 的评分数据预加载完成,维度数: ${aspectList.length}`) + } catch (error) { + console.error(`❌ 任务 "${task.StepName}" (${taskId}) 的评分数据预加载失败:`, error) + } + } + + console.log(`🎉 所有 ${tasks.length} 个任务的智能体评分数据预加载完成(或已跳过)`) +} + // 重置文本区域高度到最小行数 function resetTextareaHeight() { nextTick(() => { @@ -158,6 +229,9 @@ async function handleSearch() { outlineLoaded = true emit('search', searchValue.value) + // 🆕 预加载所有任务的智能体评分数据(在后台静默执行) + preloadAllTaskAgentScores(outlineData, searchValue.value) + // 开始填充步骤详情,设置状态 isFillingSteps.value = true diff --git a/frontend/src/layout/components/Main/TaskTemplate/TaskSyllabus/components/AgentAllocation.vue b/frontend/src/layout/components/Main/TaskTemplate/TaskSyllabus/components/AgentAllocation.vue index 1be6565..6ee1f44 100644 --- a/frontend/src/layout/components/Main/TaskTemplate/TaskSyllabus/components/AgentAllocation.vue +++ b/frontend/src/layout/components/Main/TaskTemplate/TaskSyllabus/components/AgentAllocation.vue @@ -101,22 +101,42 @@ const handleSubmit = async () => { // 3. 异步更新 store(等前端显示完成后再更新,避免触发重新初始化) await nextTick() + const taskId = currentTask.value?.Id + + // 🆕 更新按任务ID的存储 + if (taskId) { + const existingTaskData = agentsStore.getTaskScoreData(taskId) + if (existingTaskData) { + // 检查维度是否已存在 + if (!existingTaskData.aspectList.includes(response.aspectName)) { + existingTaskData.aspectList.push(response.aspectName) + } + // 更新评分数据 + for (const [agentName, scoreInfo] of Object.entries(response.agentScores)) { + if (!existingTaskData.agentScores[agentName]) { + existingTaskData.agentScores[agentName] = {} + } + existingTaskData.agentScores[agentName][response.aspectName] = scoreInfo + } + // 保存到 store + agentsStore.setTaskScoreData(taskId, existingTaskData) + console.log(`✅ 已更新任务 ${taskId} 的 store,新增维度: ${response.aspectName}`) + } + } + + // 兼容旧版本:更新全局存储 const currentStoreData = agentsStore.IAgentSelectModifyAddRequest if (currentStoreData && currentStoreData.aspectList) { - // 检查维度是否已存在(防止store中已存在) if (!currentStoreData.aspectList.includes(response.aspectName)) { currentStoreData.aspectList.push(response.aspectName) } - // 更新评分数据 - // response.agentScores: { agentName: { score, reason } } - // 转换为 agentScores[agentName][aspectName] = { score, reason } for (const [agentName, scoreInfo] of Object.entries(response.agentScores)) { if (!currentStoreData.agentScores[agentName]) { currentStoreData.agentScores[agentName] = {} } currentStoreData.agentScores[agentName][response.aspectName] = scoreInfo } - console.log(`已更新 store`) + console.log(`已更新全局 store(兼容旧版本)`) } // 清空输入框 @@ -495,40 +515,45 @@ const calculateAgentAverage = (agentData: AgentHeatmapData, selectedDimensions?: // 模拟API调用 - 获取智能体评分数据 const fetchAgentScores = async () => { - // 先检查 store 中是否已有数据 - const storedData = agentsStore.IAgentSelectModifyAddRequest + const taskId = currentTask.value?.Id + if (!taskId) { + console.warn('⚠️ fetchAgentScores: 当前任务没有 Id') + return null + } + + // 🆕 先检查 store 中是否有该任务的评分数据 + const storedData = agentsStore.getTaskScoreData(taskId) if (storedData && storedData.aspectList && storedData.aspectList.length > 0) { - console.log('使用 store 中的评分数据') - return { - aspectList: storedData.aspectList, - agentScores: storedData.agentScores + console.log('✅ 使用任务缓存的评分数据') + return storedData + } + + // 🆕 如果正在预加载中,等待预加载完成 + if (agentsStore.isTaskPreloading(taskId)) { + console.log('⏳ 任务正在预加载中,等待完成...') + // 等待一小段时间,让预加载完成 + await new Promise(resolve => setTimeout(resolve, 1000)) + // 再次尝试获取 + const cachedAfterPreload = agentsStore.getTaskScoreData(taskId) + if (cachedAfterPreload) { + return cachedAfterPreload } } - // TODO: 切换到真实API时,取消注释下面这行 + // 调用 API 获取评分(如果没有缓存或预加载) const agentScores = await api.agentSelectModifyInit({ goal: agentsStore.agentRawPlan.data?.['General Goal'] || '', stepTask: currentTask.value }) - // 🆕 使用 Mock API(开发阶段),传递当前任务的 AgentSelection 以获取对应的维度 - const goal = agentsStore.agentRawPlan.data?.['General Goal'] || '开发智能协作系统' - console.log('📤 调用 mockAgentSelectModifyInit,参数:', { - goal, - stepTask: currentTask.value, - agentSelection: currentTask.value?.AgentSelection - }) - - // const agentScores = await api.mockAgentSelectModifyInit() - // 从转换后的数据中提取维度列表(第一个agent的所有维度) const firstAgent = Object.keys(agentScores)[0] const aspectList = firstAgent ? Object.keys(agentScores[firstAgent] || {}) : [] console.log('✅ 获取到的维度列表:', aspectList) - // 保存到 store - agentsStore.setAgentScoreData({ + // 🆕 保存到 store(按任务ID存储) + agentsStore.setTaskScoreData(taskId, { aspectList, agentScores }) @@ -579,7 +604,13 @@ const initHeatmapData = async () => { try { // 获取接口数据 - const { aspectList, agentScores } = await fetchAgentScores() + const scoreData = await fetchAgentScores() + if (!scoreData) { + console.warn('⚠️ initHeatmapData: 没有获取到评分数据') + return + } + + const { aspectList, agentScores } = scoreData // 设置评分维度 scoreDimensions.value = aspectList @@ -591,17 +622,17 @@ const initHeatmapData = async () => { const scoreDetails: Array<{ dimension: string; score: number; reason: string }> = [] // 按照维度顺序获取评分 - aspectList.forEach(dimension => { + aspectList.forEach((dimension: string) => { // 数据结构:agentScores[agentName][dimension] const agentScoreData = agentScores[agentName] - const scoreData = agentScoreData ? agentScoreData[dimension] : null + const scoreItem = agentScoreData ? agentScoreData[dimension] : null - if (scoreData) { - scores.push(scoreData.score) + if (scoreItem) { + scores.push(scoreItem.score) scoreDetails.push({ dimension, - score: scoreData.score, - reason: scoreData.reason + score: scoreItem.score, + reason: scoreItem.reason }) } else { // 如果没有评分数据,默认为1 @@ -655,11 +686,12 @@ const initHeatmapData = async () => { } } -// 监听agent列表变化,初始化热力矩阵 +// 🆕 监听agent列表变化或任务切换,初始化热力矩阵 watch( - () => allAgents.value.length, - newLength => { - if (newLength > 0) { + [() => allAgents.value.length, () => currentTask.value?.Id], + ([agentLength, taskId]) => { + if (agentLength > 0 && taskId) { + console.log(`🔄 触发初始化热力图数据: agentCount=${agentLength}, taskId=${taskId}`) initHeatmapData() } }, @@ -704,9 +736,8 @@ watch( ) // 初始化和任务切换处理 -// 1. 首次加载时,自动将初始 agent 组合添加到 confirmedAgentGroups +// 1. 首次加载时,自动将初始 agent 组合添加到 confirmedAgentGroups(不调用 API,使用已有的 TaskProcess) // 2. 恢复之前的选择状态 -// 3. 加载 TaskProcess 数据 watch( () => currentTask.value, async newTask => { @@ -718,23 +749,27 @@ watch( const existingGroups = agentsStore.getConfirmedAgentGroups(newTask.Id) const hasInitialGroup = existingGroups.length > 0 - // 首次初始化:自动添加初始组合(相当于系统自动执行了 confirmAgentSelection) + // 首次初始化:自动添加初始组合到 confirmedAgentGroups if (!hasInitialGroup) { console.log('🎯 首次初始化,自动添加初始 agent 组合到 Assignment') agentsStore.addConfirmedAgentGroup(newTask.Id, [...newTask.AgentSelection]) - // 调用 API 获取初始 agent 组合的 TaskProcess 数据 - console.log('🔄 开始加载初始 agent 组合的 TaskProcess...') + // 🆕 检查 newTask 是否已有 TaskProcess(步骤详情填充时已经包含) + if (newTask.TaskProcess && newTask.TaskProcess.length > 0) { + console.log('✅ 初始 agent 组合已有 TaskProcess 数据,直接使用') - // 检查是否已有数据 - if (!selectionStore.hasAgentTaskProcess(newTask.Id, newTask.AgentSelection)) { + // 直接存储已有的 TaskProcess 到 selectionStore(不调用 API) + selectionStore.setAgentTaskProcess(newTask.Id, newTask.AgentSelection, { + process: newTask.TaskProcess, + brief: newTask.Collaboration_Brief_frontEnd || { template: '', data: {} } + }) + console.log('✅ 初始 agent 组合的 TaskProcess 已从现有数据加载') + } else { + // 🆕 如果没有 TaskProcess,才调用 API 获取(兜底逻辑) + console.log('⚠️ 初始 agent 组合没有 TaskProcess 数据,调用 API 获取...') try { isLoadingInitialTask.value = true - console.log('=== 开始加载初始 agent 组合的 TaskProcess ===') - console.log('1. 任务ID:', newTask.Id) - console.log('2. 初始 agents:', newTask.AgentSelection) - // 将 IRawStepTask 转换为 IApiStepTask 格式 const stepTaskForApi = { name: newTask.StepName || '', content: newTask.TaskContent || '', @@ -748,31 +783,21 @@ watch( process: [] } - console.log('3. 转换后的 API 请求参数:', stepTaskForApi) - const goal = agentsStore.agentRawPlan.data?.['General Goal'] || '开发智能协作系统' - console.log('4. General Goal:', goal) - // 调用 Mock API 获取 TaskProcess const filledTask = await api.fillStepTaskTaskProcess({ goal, stepTask: stepTaskForApi, agents: newTask.AgentSelection }) - console.log('=== 初始 agent 组合 TaskProcess 加载成功 ===') - console.log('5. TaskProcess 流程数量:', filledTask.process?.length || 0) - - // 存储到 selectionStore + console.log('✅ 初始 agent 组合 TaskProcess API 加载成功') selectionStore.setAgentTaskProcess(newTask.Id, newTask.AgentSelection, filledTask) - console.log('✅ 初始 agent 组合的 TaskProcess 已加载并存储') } catch (error) { console.error('❌ 加载初始 agent 组合的 TaskProcess 失败:', error) } finally { isLoadingInitialTask.value = false } - } else { - console.log('ℹ️ 初始 agent 组合已有 TaskProcess 数据,跳过加载') } } diff --git a/frontend/src/stores/modules/agents.ts b/frontend/src/stores/modules/agents.ts index 6ce9216..15153af 100644 --- a/frontend/src/stores/modules/agents.ts +++ b/frontend/src/stores/modules/agents.ts @@ -73,6 +73,13 @@ export interface IScoreItem { reason: string } +// 单个任务的评分数据结构 +export interface ITaskScoreData { + aspectList: string[] // 维度列表 + agentScores: Record> // agent -> 维度 -> 评分 + timestamp: number // 缓存时间戳 +} + export interface IAgentSelectModifyAddRequest { aspectList: string[] // 维度列表 agentScores: Record> // agent -> 维度 -> 评分(与后端返回格式一致) @@ -105,13 +112,104 @@ export const useAgentsStore = defineStore('agents', () => { agents.value = agent } - // 智能体评分数据存储 + // 🆕 新的按任务ID存储的评分数据 + const taskScoreDataMap = useStorage>( + `${storageKey}-task-score-data`, + {}, + ) + + // 🆕 预加载状态追踪(用于避免重复预加载) + const preloadingTaskIds = ref>(new Set()) + + // 🆕 获取指定任务的评分数据(按任务ID获取) + function getTaskScoreData(taskId: string): IAgentSelectModifyAddRequest | null { + if (!taskId) { + console.warn('⚠️ getTaskScoreData: taskId 为空') + return null + } + + const taskScoreData = taskScoreDataMap.value[taskId] + if (taskScoreData) { + console.log(`✅ 使用任务 ${taskId} 的缓存评分数据,维度数: ${taskScoreData.aspectList.length}`) + return { + aspectList: taskScoreData.aspectList, + agentScores: taskScoreData.agentScores, + } + } + + console.log(`ℹ️ 任务 ${taskId} 没有缓存的评分数据`) + return null + } + + // 🆕 设置指定任务的评分数据 + function setTaskScoreData(taskId: string, data: IAgentSelectModifyAddRequest) { + if (!taskId) { + console.warn('⚠️ setTaskScoreData: taskId 为空,无法存储') + return + } + taskScoreDataMap.value = { + ...taskScoreDataMap.value, + [taskId]: { + ...data, + timestamp: Date.now(), + }, + } + console.log(`✅ 任务 ${taskId} 的评分数据已存储`, { + aspectCount: data.aspectList.length, + agentCount: Object.keys(data.agentScores).length, + }) + } + + // 🆕 检查指定任务是否有评分数据 + function hasTaskScoreData(taskId: string): boolean { + if (!taskId) return false + return !!taskScoreDataMap.value[taskId]?.aspectList?.length + } + + // 🆕 获取所有已预加载的任务ID列表 + function getPreloadedTaskIds(): string[] { + return Object.keys(taskScoreDataMap.value) + } + + // 🆕 清除指定任务的评分数据 + function clearTaskScoreData(taskId: string) { + if (taskId && taskScoreDataMap.value[taskId]) { + const newMap = { ...taskScoreDataMap.value } + delete newMap[taskId] + taskScoreDataMap.value = newMap + console.log(`✅ 任务 ${taskId} 的评分数据已清除`) + } + } + + // 🆕 清除所有任务的评分数据 + function clearAllTaskScoreData() { + taskScoreDataMap.value = {} + preloadingTaskIds.value.clear() + console.log('✅ 所有任务的评分数据已清除') + } + + // 🆕 标记任务正在预加载中 + function markTaskPreloading(taskId: string) { + preloadingTaskIds.value.add(taskId) + } + + // 🆕 标记任务预加载完成 + function markTaskPreloadComplete(taskId: string) { + preloadingTaskIds.value.delete(taskId) + } + + // 🆕 检查任务是否正在预加载 + function isTaskPreloading(taskId: string): boolean { + return preloadingTaskIds.value.has(taskId) + } + + // 兼容旧版本:全局评分数据存储(单任务模式,已废弃,保留用于兼容) const IAgentSelectModifyAddRequest = useStorage( `${storageKey}-score-data`, null, ) - // 设置智能体评分数据 + // 设置智能体评分数据(兼容旧版本) function setAgentScoreData(data: IAgentSelectModifyAddRequest) { IAgentSelectModifyAddRequest.value = data } @@ -131,8 +229,6 @@ export const useAgentsStore = defineStore('agents', () => { } // 添加该维度的评分数据 - // scores: { agentName: { score, reason } } - // 转换为 agentScores[agentName][aspectName] = { score, reason } for (const [agentName, scoreItem] of Object.entries(scores)) { if (!IAgentSelectModifyAddRequest.value.agentScores[agentName]) { IAgentSelectModifyAddRequest.value.agentScores[agentName] = {} @@ -141,7 +237,7 @@ export const useAgentsStore = defineStore('agents', () => { } } - // 清除智能体评分数据 + // 清除智能体评分数据(兼容旧版本) function clearAgentScoreData() { IAgentSelectModifyAddRequest.value = null } @@ -476,6 +572,18 @@ export const useAgentsStore = defineStore('agents', () => { setAgentScoreData, addAgentScoreAspect, clearAgentScoreData, + // 🆕 按任务ID存储的评分数据 + taskScoreDataMap, + getTaskScoreData, + setTaskScoreData, + hasTaskScoreData, + getPreloadedTaskIds, + clearTaskScoreData, + clearAllTaskScoreData, + preloadingTaskIds, + markTaskPreloading, + markTaskPreloadComplete, + isTaskPreloading, // 确认的agent组合列表(按任务ID分别存储) confirmedAgentGroupsMap, getConfirmedAgentGroups,