diff --git a/src/api/settings/workflow/session.ts b/src/api/settings/workflow/session.ts index eda2978..d74f6a8 100644 --- a/src/api/settings/workflow/session.ts +++ b/src/api/settings/workflow/session.ts @@ -4,7 +4,7 @@ import request, { type RequestOptions } from '/@/utils/request'; // 后端结构: // ListSessionReq { page } → ListSessionRes { list: VOSession[], total } // GetSessionInfoReq { page, sessionId } → GetSessionInfoRes { list: VOSessionInfoResult[], total } -// DeleteSessionReq { id }(POST,级联删除普通对话结果,工作流结果保留) +// DeleteSessionReq { sessionId }(POST,级联删除普通对话结果,工作流结果保留) // 说明:会话为「会话 → 会话内结果(工作流/普通对话混排,按时间倒序)」模型。 export interface VOSession { @@ -19,6 +19,7 @@ export interface VOSessionInfoResult { status: number; // 1-运行中, 2-成功, 3-失败 flowId: string; requestParams: Record; + resultFileUrl: string; // 产出文件地址(单文件;工作流执行成功时后端填写,空串表示无产出) resultContent: string; // 回复文本内容(非文件地址) totalTokens: number; totalFee: number; @@ -44,11 +45,11 @@ export function getSessionResults(sessionId: string, params?: Record; } -export function deleteSessionV2(id: string, requestOptions?: RequestOptions) { +export function deleteSessionV2(sessionId: string, requestOptions?: RequestOptions) { return request({ url: '/ai-agent/session/delete', method: 'post', - data: { id }, + data: { sessionId }, requestOptions, }); } diff --git a/src/views/home/index.vue b/src/views/home/index.vue index cb45f0e..e61e9f3 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -91,7 +91,7 @@ import MainContent from './components/MainContent.vue'; import InputBar from './components/InputBar.vue'; import TemplateCompleteDialog from './components/TemplateCompleteDialog.vue'; import SessionModelSetter from './components/SessionModelSetter.vue'; -import { applyHomeFormValues, buildOutputsFromUrls, extractWorkflowOutputs } from './utils/flowDsl'; +import { applyHomeFormValues, buildOutputsFromUrls } from './utils/flowDsl'; import type { WorkflowOutput } from './utils/flowDsl'; import { getChatModel, listModelManage } from '/@/api/settings/modelConfigV2'; import { connectSessionSocket, sendAgentStart, sendWorkflowStart, sendCancel } from './utils/wsExecute'; @@ -100,7 +100,6 @@ import type { ExecutionTreeItem } from '/@/api/settings/creation'; import { getExecutionList, getWorkflowDetail, - getExecutionDetail, deleteExecutionResult, downloadToFile, } from '/@/api/settings/creation'; @@ -903,10 +902,11 @@ const runWorkflow = async ( formMsg.formProgress = undefined; curSession.status = success ? 'completed' : 'failed'; // 结果消息:成功时携带本次执行产出(outputs),直接以产出卡片渲染在对话里。 - // 产出来源优先 flow_complete 事件自带 resultFileUrls(buildOutputsFromUrls),异步详情链路作兜底 + // 产出来源为 flow_complete 事件自带的 resultFileUrls(buildOutputsFromUrls);无产出时提示「本次未生成产出文件」 const resultMsg: ChatMessage = { id: 'msg-' + Date.now() + (success ? '-done' : '-fail'), - content: success ? '✅ 执行完成' : `❌ ${errorMsg || '执行失败,请重试或联系管理员'}`, + // 成功但无产出:明确告知「本次未生成产出文件」,避免用户以为产出丢失(产出来自 flow_complete.resultFileUrls) + content: success ? (outputs?.length ? '✅ 执行完成' : '✅ 执行完成,本次未生成产出文件') : `❌ ${errorMsg || '执行失败,请重试或联系管理员'}`, time: formatTime(new Date()), isUser: false, outputs: outputs || [], @@ -919,20 +919,7 @@ const runWorkflow = async ( imgAddressPrefix.value = res.data?.imgAddressPrefix || ''; treeNodes.value = buildTreeNodes(res.data?.tree || []); }); - // 会话内渲染本次产出:拉最新 session/get 记录(时间倒序首条)→ getExecutionDetail → 附加到结果消息 - // 时序降级:记录未及时写入则静默跳过(用户重进会话可见回显产出) - // 会话在建连时已认领为后端正式号,直接按认领后的 sid 查询本次执行记录 - loadSessionResults(sid).then((results) => { - const latest = Array.isArray(results) && results.length ? results[0] : undefined; - if (latest && latest.type === 'workflow' && !latest.errorMsg) { - getExecutionDetail(String(latest.id)) - .then((res) => { - const outputs = extractWorkflowOutputs(res?.data, String(latest.id)); - if (outputs.length) resultMsg.outputs = outputs; - }) - .catch(() => {}); - } - }); + // 产出已由 flow_complete 事件携带的 resultFileUrls 渲染进结果消息,无需再调 execution/get 补查 } else { ElMessage.error(errorMsg || '执行失败,请重试'); } @@ -1202,6 +1189,13 @@ const runChat = async (sid: string, sessionId: string, message: string) => { } else { addMessage({ id: 'msg-' + Date.now() + '-fail', content, time: formatTime(new Date()), isUser: false }); } + } else if (list && aiIdx >= 0) { + // 成功兜底:后端未推任何回复内容时,给出明确提示并允许重新生成(避免空白气泡) + const ai = list[aiIdx]; + if (!ai.content) { + ai.content = '⚠️ 未收到回复内容,请重试'; + ai.retryQuestion = message; + } } // 更新会话状态 const session = historyList.value.find((h) => h.id === sid); @@ -1414,7 +1408,7 @@ const loadWorkflowSessionMessages = async (sid: string, results: VOSessionInfoRe formError: failed ? r.errorMsg || '执行失败' : '', }); } - // 结果消息:成功记录异步拉取产出(getExecutionDetail → outputParams/fileUrls)附加到 outputs + // 结果消息:成功记录直接带产出(session/get 记录自带的 resultFileUrl),不再调 execution/get const resultMsg: ChatMessage = { id: failed ? 'wfail-' + r.id : 'wok-' + r.id, content: failed ? '❌ ' + (r.errorMsg || '执行失败,请重试或联系管理员') : '✅ 执行完成,可前往工作空间查看产出', @@ -1424,15 +1418,14 @@ const loadWorkflowSessionMessages = async (sid: string, results: VOSessionInfoRe recordType: r.type, outputs: [], }; - msgs.push(resultMsg); - if (!failed) { - getExecutionDetail(String(r.id)) - .then((res) => { - const outputs = extractWorkflowOutputs(res?.data, String(r.id)); - if (outputs.length) resultMsg.outputs = outputs; - }) - .catch(() => {}); + if (!failed && r.resultFileUrl) { + resultMsg.outputs = buildOutputsFromUrls([String(r.resultFileUrl)], String(r.id)); } + // 成功但无产出文件:明确提示,避免「可前往工作空间查看产出」误导用户 + if (!failed && !r.resultFileUrl) { + resultMsg.content = '✅ 执行完成,本次未生成产出文件'; + } + msgs.push(resultMsg); } }); sessionMessages.value.set(sid, msgs);