From cbf5bba17d557c12b8236805595dbec08af213a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jack=E9=AD=8F?= Date: Thu, 4 Sep 2025 19:24:58 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A3=8E=E9=99=A9=E6=8F=90=E7=A4=BA=E6=A1=86?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=A1=AE=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/dialoguePanel/DialogueFlow.vue | 99 +++++++++++++++-- .../dialoguePanel/DialoguePanel.scss | 1 - src/i18n/lang/en.ts | 6 +- src/i18n/lang/zh-cn.ts | 2 + src/store/conversation.ts | 105 ++++++++++++++++-- src/views/dialogue/types.ts | 1 + 6 files changed, 187 insertions(+), 27 deletions(-) diff --git a/src/components/dialoguePanel/DialogueFlow.vue b/src/components/dialoguePanel/DialogueFlow.vue index e0c6a5d7..2a101c11 100644 --- a/src/components/dialoguePanel/DialogueFlow.vue +++ b/src/components/dialoguePanel/DialogueFlow.vue @@ -2,8 +2,12 @@ import { ref, watch } from 'vue'; import FlowCode from './FlowCode.vue'; import { StatusInfoTitle } from '@/views/createapp/components/types'; -import { IconSuccess, IconError } from '@computing/opendesign-icons'; +import { getCookie } from '@/apis/tools'; +import { useSessionStore } from '@/store'; +import i18n from 'src/i18n'; +const { t } = i18n.global; +const { sendQuestion } = useSessionStore(); const props = withDefaults( defineProps<{ flowdata: any; @@ -13,14 +17,47 @@ const props = withDefaults( {}, ); const contents = ref(); +const exData = ref([]); +const taskId = ref(); const totalTime = ref(0); if (props.flowdata) { contents.value = [props.flowdata]; + + if (props.flowdata.data[0]) { + for (const item of props.flowdata.data[0]) { + if (item && item?.data.exData) { + exData.value.push(item.data.exData); + } + } + } } const activeNames = ref([contents.value[0].id]); const secondCollapseActiveName = ref([]); +function getRiskType(risk) { + const mapping = { + low: 'warning', + }; + return mapping[risk] || 'warning'; +} +const doFlow = async (type) => { + if (taskId) { + taskId.value = null; + let content = ''; + await sendQuestion( + undefined, + content, + undefined, + undefined, + undefined, + undefined, + { params: type }, + null, + 'wait', + ); + } +}; watch( () => props, () => { @@ -31,6 +68,10 @@ watch( totalTime.value += item.costTime || 0; }); } + if (props.flowdata?.taskId) { + exData.value.push(props.flowdata?.data.exData); + taskId.value = props.flowdata?.taskId; + } }, { deep: true, immediate: true }, ); @@ -40,9 +81,10 @@ watch(
@@ -56,7 +98,7 @@ watch( @@ -203,6 +260,14 @@ watch( diff --git a/src/components/dialoguePanel/DialoguePanel.scss b/src/components/dialoguePanel/DialoguePanel.scss index 2ff42f9a..a88c204a 100644 --- a/src/components/dialoguePanel/DialoguePanel.scss +++ b/src/components/dialoguePanel/DialoguePanel.scss @@ -288,7 +288,6 @@ .loading { display: flex; - background-color: var(--o-bg-color-base); border-radius: 8px !important; border-top-left-radius: 0px !important; border-radius: 8px !important; diff --git a/src/i18n/lang/en.ts b/src/i18n/lang/en.ts index 5adcf021..913e5d2e 100644 --- a/src/i18n/lang/en.ts +++ b/src/i18n/lang/en.ts @@ -372,8 +372,10 @@ export default { fiveKnowledge: 'Select up to 5 knowledge bases.', }, flow: { - //flow_start: 'Workflow in progress', - //flow_end: 'Workflow completed.', + flow_start: 'Workflow in progress', + flow_end: 'Workflow completed.', + flow_cancel: 'Cancel running', + flow_risk: 'Risk statement', flow_params_error: 'Parameter missing', flow_pause: 'Workflow paused', edit_flow: 'Edit', diff --git a/src/i18n/lang/zh-cn.ts b/src/i18n/lang/zh-cn.ts index c729f327..922987cf 100644 --- a/src/i18n/lang/zh-cn.ts +++ b/src/i18n/lang/zh-cn.ts @@ -405,6 +405,8 @@ export default { flow: { flow_start: '工作流进行中', flow_end: '工作流结束', + flow_cancel: '取消运行', + flow_risk: '风险提示', flow_params_error: '缺少参数', flow_pause: '工作流暂停', edit_flow: '编辑工作流', diff --git a/src/store/conversation.ts b/src/store/conversation.ts index f287a33b..bc601955 100644 --- a/src/store/conversation.ts +++ b/src/store/conversation.ts @@ -66,6 +66,8 @@ export const useSessionStore = defineStore('conversation', () => { // ai回复是否还在生成中 const isAnswerGenerating = ref(false); + const currentTaskId = ref(null); + // 方法集合 - 用于处理不同类型的event message const dataTransfers = { textAdd: ( @@ -174,11 +176,12 @@ export const useSessionStore = defineStore('conversation', () => { } else if (content.type !== 'schema' && conversationItem.flowdata) { // 删除 end 逻辑 conversationItem.flowdata = { - id: contentFlow.stepId, - title: i18n.global.t('flow.flow_end'), - progress: contentFlow.stepProgress, - status: 'success', + id: messageFlow.stepId, + title: currentTaskId ? i18n.global.t('flow.flow_start') : i18n.global.t('flow.flow_end'), + progress: messageFlow.stepProgress, + status: currentTaskId ? messageFlow.flowStatus : 'success', display: true, + taskId: currentTaskId.value, data: conversationItem.flowdata.data, }; } else { @@ -207,6 +210,44 @@ export const useSessionStore = defineStore('conversation', () => { $bus.emit('debugChatEnd'); } }, + waitingForStart: ( + conversationItem: RobotConversationItem, + message: Record, + ) => { + const flow = (message.flow || {}) as Record; + const content = (message.content || {}) as Record; + conversationItem.flowdata = { + id: flow.stepId, + title: flow.stepName, + status: flow.stepStatus, + taskId: currentTaskId, + data: { + exData: content, + }, + }; + if (conversationItem.flowdata) { + conversationItem.flowdata.progress = flow.stepProgress; + conversationItem.flowdata.status = flow.stepStatus; + } + }, + flowCancel: ( + conversationItem: RobotConversationItem, + message: Record, + ) => { + const content = (message.content || {}) as Record; + const contentFlow = (content.flow || {}) as Record; + const messageFlow = (message.flow || {}) as Record; + + // 取消运行 + conversationItem.flowdata = { + id: contentFlow.stepId, + title: i18n.global.t('flow.flow_cancel'), + progress: contentFlow.stepProgress, + status: messageFlow.stepStatus, + display: true, + data: conversationItem?.flowdata?.data, + }; + }, }; // chat message回调 @@ -225,6 +266,10 @@ export const useSessionStore = defineStore('conversation', () => { dataTransfers.dataDone(conversationItem, !!params.type); return; } + if (rawMsgData === '[ERROR]') { + dataTransfers.dataDone(conversationItem, !!params.type); + return; + } // 同一时间戳传来的decodeValue是含有三条信息的合并,so需要分割 // 这里json解析 @@ -233,6 +278,7 @@ export const useSessionStore = defineStore('conversation', () => { if ('metadata' in message) { conversationItem.metadata = message.metadata; } + currentTaskId.value = message.taskId; if ('event' in message) { switch (eventType) { case 'text.add': @@ -267,6 +313,14 @@ export const useSessionStore = defineStore('conversation', () => { case 'step.output': dataTransfers.stepOutput(conversationItem, message); break; + case 'step.waiting_for_start': + // 事件流等待开始 + dataTransfers.waitingForStart(conversationItem, message); + break; + case 'flow.cancel': + // 事件流取消 + dataTransfers.flowCancel(conversationItem, message); + break; case 'flow.stop': //时间流结束 dataTransfers.flowStop(conversationItem, message, !!params.type); @@ -377,6 +431,18 @@ export const useSessionStore = defineStore('conversation', () => { openWhenHidden: true, }); }, + fetchWait: async ( + url: string, + params: Record, + innerParams: Record, + fetchParams: Record, + ) => { + await fetchEventSource(url, { + ...fetchParams, + body: JSON.stringify({ taskId: currentTaskId.value, params: params.params }), + openWhenHidden: true, + }); + }, }; const judgeResp = async (resp) => { @@ -408,6 +474,7 @@ export const useSessionStore = defineStore('conversation', () => { type?: any; }, ind?: number, + waitType?: string, ): Promise => { const { currentSelectedSession } = useHistorySessionStore(); params.conversationId = currentSelectedSession; @@ -459,8 +526,8 @@ export const useSessionStore = defineStore('conversation', () => { } else if (params.user_selected_app) { // 新的工作流调试记录 await funcFetch.fetchAppNew(streamUrl, params, pp, fetchParams); - // } else if (false) { - // //写传参数情况 + } else if (waitType) { + await funcFetch.fetchWait(streamUrl, params, pp, fetchParams); } else { await funcFetch.fetchDefault(streamUrl, params, pp, fetchParams); } @@ -510,6 +577,7 @@ export const useSessionStore = defineStore('conversation', () => { * @param user_selected_flow * @param params * @param type + * @param waitType */ const sendQuestion = async ( groupId: string | undefined, @@ -520,6 +588,7 @@ export const useSessionStore = defineStore('conversation', () => { user_selected_flow?: string, params?: any, type?: any, + waitType?: string, ): Promise => { const { updateSessionTitle, currentSelectedSession } = useHistorySessionStore(); @@ -543,7 +612,7 @@ export const useSessionStore = defineStore('conversation', () => { comment: 'none', }); targetItem.currentInd = targetItem.message.length - 1; //123 - } else { + } else if (!waitType) { // 初次生成 ,创建一个问题和一个回答 const ind = conversationList.value.length - 1; const messageList = new MessageArray(); @@ -592,7 +661,10 @@ export const useSessionStore = defineStore('conversation', () => { params: params || undefined, }; } - await getStream(getStreamParams, regenerateInd ?? undefined); + if (waitType) { + getStreamParams = params; + } + await getStream(getStreamParams, regenerateInd ?? undefined, waitType); }; /** @@ -686,10 +758,10 @@ export const useSessionStore = defineStore('conversation', () => { */ const handleMessage = (record: any): string => { let message = record.content.answer; - record.metadata.footNoteMetadataList?.reverse().forEach((footNoteMetadata: any)=>{ - const insertFile = record.document?.filter((file: any)=>file._id === footNoteMetadata.releatedId); + record.metadata.footNoteMetadataList?.reverse().forEach((footNoteMetadata: any) => { + const insertFile = record.document?.filter((file: any) => file._id === footNoteMetadata.releatedId); const insertNumber = insertFile[0]?.order; - if(!insertNumber)return; + if (!insertNumber) return; const pos = footNoteMetadata.insertPosition; message = message.slice(0, pos) + `[[${insertNumber}]]` + message.slice(pos) }); @@ -769,6 +841,8 @@ export const useSessionStore = defineStore('conversation', () => { flowId: record.flowId, data: [[]] as any[], }; + // 看有没有取消的 + let isCancelled = false; for (let i = 0; i < record.steps.length; i++) { flowData.data[0].push({ id: record.steps[i].stepId, @@ -777,8 +851,15 @@ export const useSessionStore = defineStore('conversation', () => { data: { input: record.steps[i].input, output: record.steps[i].output, + exData: record.steps[i].exData, }, }); + if (record.steps[i].stepStatus === 'cancelled') { + isCancelled = true; + } + } + if (isCancelled) { + flowData.status = 'cancelled'; } return flowData; }; @@ -790,7 +871,7 @@ export const useSessionStore = defineStore('conversation', () => { isPaused.value = true; ( conversationList.value[ - conversationList.value.length - 1 + conversationList.value.length - 1 ] as RobotConversationItem ).isFinish = true; cancel(); diff --git a/src/views/dialogue/types.ts b/src/views/dialogue/types.ts index 90e5656c..d5b78943 100644 --- a/src/views/dialogue/types.ts +++ b/src/views/dialogue/types.ts @@ -61,6 +61,7 @@ export interface FlowType { display: boolean; progress: string; flowId?: string; + taskId?: string; } export interface FlowDataType { -- Gitee