首页工作流产出链路去 execution/get 依赖,空结果兜底与删除接口契约对齐

- 实时执行产出只信 flow_complete 事件 resultFileUrls,删除 getExecutionDetail 兜底
- 历史回显产出改用 session/get 记录自带 resultFileUrl,不再调 execution/get
- 普通对话空回复:提示「未收到回复内容,请重试」并支持重新生成
- 工作流实时/历史无产出文件:明确提示「本次未生成产出文件」
- deleteSessionV2 对齐后端契约:/ai-agent/session/delete 传 sessionId
This commit is contained in:
2026-08-18 17:04:41 +08:00
parent 13a2aeee9f
commit c962cdd830
2 changed files with 24 additions and 30 deletions
+4 -3
View File
@@ -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<string, any>;
resultFileUrl: string; // 产出文件地址(单文件;工作流执行成功时后端填写,空串表示无产出)
resultContent: string; // 回复文本内容(非文件地址)
totalTokens: number;
totalFee: number;
@@ -44,11 +45,11 @@ export function getSessionResults(sessionId: string, params?: Record<string, any
}) as Promise<{ code: number; message: string; data: { list: VOSessionInfoResult[]; total: number } }>;
}
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,
});
}
+20 -27
View File
@@ -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 事件自带 resultFileUrlsbuildOutputsFromUrls,异步详情链路作兜底
// 产出来源 flow_complete 事件自带 resultFileUrlsbuildOutputsFromUrls;无产出时提示「本次未生成产出文件」
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);