From 68df4582c1edaf1952e6c21d769981e348fb3d04 Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期四, 20 二月 2025 18:00:29 +0800
Subject: [PATCH] 流输出

---
 src/components/chat/assistant/index.vue |  229 +++++++++++++++++++++++++++++++--------------------------
 1 files changed, 124 insertions(+), 105 deletions(-)

diff --git a/src/components/chat/assistant/index.vue b/src/components/chat/assistant/index.vue
index 3bc4318..90393b4 100644
--- a/src/components/chat/assistant/index.vue
+++ b/src/components/chat/assistant/index.vue
@@ -15,6 +15,104 @@
 					<div class="rounded-[6px] p-4 leading-relaxed bg-white">
 						<!-- #region ====================== 娑堟伅鍐呭 ======================-->
 						<!-- <template v-if="item.content?.values"> -->
+
+						<!-- #region ====================== 鍥炵瓟缁勪欢 ======================-->
+						<template v-if="msg.content.type === AnswerType.Report">
+							<template v-if="msg?.stepGroup?.length > 0">
+								<div v-for="(num, index) in msg?.stepGroup?.length" :key="index">
+									<!-- 鎰忓浘鍒嗘瀽鍙睍绀虹涓�涓紝鍚庣画鐨� stepGroup 閮芥槸绌虹殑锛岀敤浜庡惊鐜嚭缁勪欢 -->
+									<!-- #region ====================== 鎰忓浘鍒嗘瀽 ======================-->
+									<div class="flex flex-col" v-if="msg?.stepGroup?.[index]?.value?.length > 0 && index === 0">
+										<!-- #region ====================== 鎰忓浘鍒嗘瀽 ======================-->
+										<div class="flex items-center">
+											<span class="mr-2">鎰忓浘鍒嗘瀽锛�</span>
+											<div
+												@click="toggleStepList(msg?.stepGroup?.[index])"
+												class="cursor-pointer border border-gray-300 border-solid w-fit px-2 flex items-center space-x-2 rounded-lg hover:bg-gray-100 active:bg-gray-200"
+											>
+												<span>
+													{{ toggleStepLabel(msg?.stepGroup?.[index]) }}
+												</span>
+												<span
+													class="ywifont"
+													:class="{
+														'ywicon-unfold': !msg?.stepGroup?.[index].isShow,
+														'ywicon-fold': msg?.stepGroup?.[index].isShow,
+													}"
+												></span>
+											</div>
+										</div>
+										<!-- #endregion -->
+
+										<!-- #region ====================== 杩囩▼杈撳嚭 ======================-->
+										<el-steps v-show="msg?.stepGroup?.[index].isShow" class="mt-3" direction="vertical">
+											<el-step
+												:key="`template-${stepIndex}`"
+												v-for="(subItem, stepIndex) in msg?.stepGroup?.[index].value"
+												:title="subItem.title"
+												:status="stepEnumMap[subItem.status]"
+											>
+												<template #icon v-if="stepIndex + 1 === msg?.stepGroup?.[index].value.length && isTalking && isLast&&(subItem.finishLoading===false || subItem.finishLoading===undefined)">
+													<span class="ywifont ywicon-loading1 animate-spin !text-[24px]"></span>
+												</template>
+												<template #title>
+													<span class="">
+														<span v-html="subItem.title.replace(/\n/g, '<br>')"></span>
+
+														<span v-if="subItem.ms" class="text-green-600">{{ `锛�${subItem.ms}锛塦 }}</span></span
+													>
+												</template>
+												
+
+												<template #description v-if="subItem?.subStep?.length > 0">
+													<div class="my-1 flex flex-col gap-1 text-[14px]">
+														<div
+															:key="`${msg.historyId}-${stepIndex + 1}-${multiChatIndex + 1}`"
+															v-for="(multiChatItem, multiChatIndex) in subItem.subStep"
+														>
+															<component
+																:order="`${stepIndex + 1}-${multiChatIndex + 1}`"
+																:item="multiChatItem"
+																:is="multiChatTypeMapCom[multiChatItem.type]"
+																@change="multiChatChange"
+																:disabled="!(stepIndex + 1 === msg?.stepGroup?.[index].value.length && isTalking && isLast)"
+															/>
+														</div>
+													</div>
+												</template>
+											</el-step>
+										</el-steps>
+										<!-- #endregion -->
+									</div>
+									<!-- #endregion -->
+									<!-- result 鏃�  recordSetTable 宸茬粡鍔犺浇锛宻ummary 鏃跺張鍔犺浇浜嗕竴娆★紝瀵艰嚧姣斾緥鍒� push 浜嗕袱娆�
+										涓轰簡瑙e喅杩欎釜闂锛岀瓑鍒� msg.historyId 瀛樺湪鏃讹紝鍐嶆覆鏌� recordSetTable
+										-->
+									<component
+										v-if="msg.content?.values?.[index]  && msg.content?.errCode !== ErrorCode.Message"
+										:reportIndex="index"
+										:conclusion="msg.content.values[index].conclusion"
+										:is="answerTypeMapCom[msg.content.values[index].content.type]"
+										:data="msg.content.values[index].content.values"
+										:originData="msg.content.values[index]"
+										:historyId="msg.historyId"
+										:isTalking="isTalking && isLast"
+									/>
+								</div>
+							</template>
+							<p v-else-if="msg.content?.errCode !== ErrorCode.Message" class="text-info">鏆傛棤鍐呭锛岃閲嶈瘯</p>
+						</template>
+						<component
+							v-else
+							:historyId="msg.historyId"
+							:conclusion="msg.conclusion"
+							:is="answerTypeMapCom[msg.content.type]"
+							:data="msg.content.values"
+							:originData="msg"
+							:isTalking="isTalking && isLast"
+						/>
+						<!-- #endregion -->
+						<!-- </template> -->
 						<!-- #region ====================== 鎶ラ敊淇℃伅 ======================-->
 						<div v-if="msg.content?.errCode === ErrorCode.Message" class="flex-column w-full">
 							<p class="text-danger">
@@ -37,120 +135,17 @@
 							</div>
 						</div>
 						<!-- #endregion -->
-						<!-- #region ====================== 鍥炵瓟缁勪欢 ======================-->
-						<template v-else>
-							<template v-if="msg.content.type === AnswerType.Report">
-								<template v-if="msg?.stepGroup?.length > 0">
-									<div v-for="(num, index) in msg?.stepGroup?.length" :key="index">
-										<!-- #region ====================== 鎰忓浘鍒嗘瀽 ======================-->
-										<div class="flex flex-col" v-if="msg?.stepGroup?.[index]?.value?.length > 0">
-											<!-- #region ====================== 鎰忓浘鍒嗘瀽 ======================-->
-											<div class="flex items-center">
-												<span class="mr-2">鎰忓浘鍒嗘瀽锛�</span>
-												<div
-													@click="toggleStepList(msg?.stepGroup?.[index])"
-													class="cursor-pointer border border-gray-300 border-solid w-fit px-2 flex items-center space-x-2 rounded-lg hover:bg-gray-100 active:bg-gray-200"
-												>
-													<span>
-														{{ toggleStepLabel(msg?.stepGroup?.[index]) }}
-													</span>
-													<span
-														class="ywifont"
-														:class="{
-															'ywicon-unfold': !msg?.stepGroup?.[index].isShow,
-															'ywicon-fold': msg?.stepGroup?.[index].isShow,
-														}"
-													></span>
-												</div>
-											</div>
-											<!-- #endregion -->
-
-											<!-- #region ====================== 杩囩▼杈撳嚭 ======================-->
-											<el-steps v-show="msg?.stepGroup?.[index].isShow" class="mt-3" direction="vertical">
-												<el-step
-													:key="`template-${stepIndex}`"
-													v-for="(subItem, stepIndex) in msg?.stepGroup?.[index].value"
-													:title="subItem.title"
-													:status="stepEnumMap[subItem.status]"
-												>
-													<template #icon v-if="stepIndex + 1 === msg?.stepGroup?.[index].value.length && isTalking && isLast">
-														<span class="ywifont ywicon-loading1 animate-spin !text-[24px]"></span>
-													</template>
-													<template #title>
-														<span class="">
-															{{ subItem.title }}
-
-															<span v-if="subItem.ms" class="text-green-600">{{ `锛�${subItem.ms}锛塦 }}</span></span
-														>
-													</template>
-
-													<template #description v-if="subItem?.subStep?.length > 0">
-														<div class="my-1 flex flex-col gap-1 text-[14px]">
-															<div
-																:key="`${msg.historyId}-${stepIndex + 1}-${multiChatIndex + 1}`"
-																v-for="(multiChatItem, multiChatIndex) in subItem.subStep"
-															>
-																<component
-																	
-																	:order="`${stepIndex + 1}-${multiChatIndex + 1}`"
-																	:item="multiChatItem"
-																	:is="multiChatTypeMapCom[multiChatItem.type]"
-																	:disabled="!(stepIndex + 1 === msg?.stepGroup?.[index].value.length && isTalking && isLast)"
-																/>
-																
-															</div>
-														</div>
-													</template>
-												</el-step>
-											</el-steps>
-											<!-- #endregion -->
-										</div>
-										<!-- #endregion -->
-										<!-- result 鏃�  recordSetTable 宸茬粡鍔犺浇锛宻ummary 鏃跺張鍔犺浇浜嗕竴娆★紝瀵艰嚧姣斾緥鍒� push 浜嗕袱娆�
-										涓轰簡瑙e喅杩欎釜闂锛岀瓑鍒� msg.historyId 瀛樺湪鏃讹紝鍐嶆覆鏌� recordSetTable
-										-->
-										<component
-										
-											v-if="msg.content?.values?.[index] && msg.historyId"
-											:reportIndex="index"
-											:conclusion="msg.content.values[index].conclusion"
-											:is="answerTypeMapCom[msg.content.values[index].content.type]"
-											:data="msg.content.values[index].content.values"
-											:originData="msg.content.values[index]"
-											:historyId="msg.historyId"
-											:isTalking="isTalking && isLast"
-										/>
-									</div>
-								</template>
-								<p v-else class="text-info">鏆傛棤鍐呭锛岃閲嶈瘯</p>
-							</template>
-							<component
-								v-else
-								:historyId="msg.historyId"
-								:conclusion="msg.conclusion"
-								:is="answerTypeMapCom[msg.content.type]"
-								:data="msg.content.values"
-								:originData="msg"
-								:isTalking="isTalking && isLast"
-							/>
-						</template>
-						<!-- #endregion -->
-						<!-- </template> -->
-
 						<!-- #endregion -->
 						<!-- #region ====================== 闄勫姞鍐呭 ======================-->
 						<!-- #region ====================== 鍋滄 ======================-->
 						<span v-if="msg.isStopMsg && msg?.role === RoleEnum.assistant" class="text-gray-400 text-[12px]">锛堝凡鍋滄锛�</span>
 						<!-- parseContent 杩斿洖涓� null -->
-						<p v-if="!msg.content && !isTalking && !msg.isStopMsg" class="text-red-500">鏆傛棤鏁版嵁</p>
+						<p v-if="!msg.content && !isTalking && !msg.isStopMsg && msg.content?.errCode !== ErrorCode.Message" class="text-red-500">鏆傛棤鏁版嵁</p>
 						<!-- #endregion -->
 						<!-- #endregion -->
 					</div>
 					<!-- #region ====================== ai 娑堟伅鎿嶄綔 ======================-->
-					<div
-						v-if="msg.role === RoleEnum.assistant && msg.content?.values && !isSharePage"
-						class="absolute flex items-center right-0 mr-4 mt-2 space-x-2"
-					>
+					<div v-if="msg.content?.values && !isSharePage" class="absolute flex items-center right-0 mr-4 mt-2 space-x-2">
 						<div
 							class="flex items-center justify-center size-[15px]"
 							v-if="msg.content?.type === AnswerType.Text || msg.content?.type === AnswerType.Knowledge"
@@ -210,6 +205,16 @@
 						</el-tooltip>
 					</div>
 					<!-- #endregion -->
+
+					<div class="absolute flex items-center left-18 mt-2 space-x-2 pb-7">
+						<div
+							v-if="isTalking && isLast"
+							class="text-blue-400 cursor-pointer z-20 py-2 px-2 border border-solid border-blue-400 hover:text-blue-500 hover:border-blue-500 rounded-lg hover:bg-[#ebeffa]"
+							@click="stopGenClick"
+						>
+							鍋滄杈撳嚭
+						</div>
+					</div>
 				</div>
 			</div>
 		</div>
@@ -235,6 +240,7 @@
 import { multiChatTypeMapCom } from '/@/components/chat/chatComponents/multiChat';
 import { isSharePage } from '/@/stores/chatRoom';
 import { ErrorCode } from '/@/utils/request';
+import { question_stream_reply } from '/@/api/ai/chat';
 
 const props = defineProps({
 	/** @description 褰撳墠娑堟伅 */
@@ -257,10 +263,15 @@
 const emit = defineEmits({
 	sendChatMessage: (content: ChatContent) => true,
 	shareMsg: (msg: ChatMessage) => true,
+	stopGenClick: () => true,
 });
 
 const sendChatMessage = (content: ChatContent) => {
 	emit('sendChatMessage', content);
+};
+
+const stopGenClick = () => {
+	emit('stopGenClick');
 };
 
 //#region ====================== 姝ラ step ======================
@@ -293,6 +304,14 @@
 	emit('shareMsg', item);
 };
 //#endregion
+
+const multiChatChange = async (replyId: string, val: any) => {
+	const res = await question_stream_reply({
+		start_time: val.start_time,
+		end_time: val.end_time,
+		reply_id: replyId,
+	});
+};
 </script>
 <style scoped lang="scss">
 pre {

--
Gitblit v1.9.3