From fc42a3c9fb49ecf6c72d22738757c5cda8c06130 Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期四, 10 十月 2024 16:10:18 +0800
Subject: [PATCH] 主动 scrollToBottom

---
 src/components/chat/Chat.vue                        |   69 ++++++++++++++---------
 src/components/chat/hooks/useScrollToBottom.ts      |   45 +++++---------
 src/components/chat/hooks/useAssistantContentOpt.ts |   13 +---
 3 files changed, 61 insertions(+), 66 deletions(-)

diff --git a/src/components/chat/Chat.vue b/src/components/chat/Chat.vue
index 943c8cd..2143389 100644
--- a/src/components/chat/Chat.vue
+++ b/src/components/chat/Chat.vue
@@ -2,7 +2,7 @@
 	<div class="flex h-full">
 		<div class="flex flex-col h-full flex-auto">
 			<div class="h-full flex flex-col items-center overflow-y-auto">
-				<div ref="chatListDom" class="h-full" :style="{ width: chatWidth }">
+				<div ref="chatListDom" class="h-full" v-loading="chatListLoading" :style="{ width: chatWidth }">
 					<div
 						class="group flex px-4 py-6 hover:bg-slate-100 rounded-lg relative"
 						:class="{ 'flex-row-reverse': item.role === RoleEnum.user }"
@@ -156,7 +156,6 @@
 </template>
 
 <script setup lang="ts">
-import { ElMessage } from 'element-plus';
 import _ from 'lodash';
 import { v4 as uuidv4 } from 'uuid';
 import { computed, onMounted, ref } from 'vue';
@@ -331,7 +330,7 @@
 };
 
 const sendChatMessage = async (content: ChatContent = messageContent.value, cb?: any, isCallExtParams?: any) => {
-	if (!content?.values || isTalking.value) return;
+	if (!content?.values || isTalking.value ||chatListLoading.value) return;
 	const isNewChat = messageList.value.length === 0;
 	if (isNewChat) {
 		if (activeSampleId.value) {
@@ -355,6 +354,9 @@
 
 		// 鍑虹幇鍥炲锛岀疆绌哄嚭鐜扮瓑寰呭姩鐢�
 		messageList.value.push(assistantItem);
+		// 婊氬姩鑷冲綋鍓嶅彂閫佹秷鎭�
+		scrollToBottom();
+
 		if (isCallExtParams) {
 			const extRes = await extCallQuery(isCallExtParams);
 			questionRes = extRes;
@@ -374,6 +376,8 @@
 		assistantItem.historyId = questionRes.history_id;
 		assistantItem.sectionAId = finalCalcSectionAId;
 		appendLastMessageContent(resMsgContent);
+		// 鏀跺埌鎭㈠锛岀户缁粴
+		scrollToBottom();
 	} catch (error: any) {
 		// appendLastMessageContent({
 		// 	type: AnswerType.Text,
@@ -400,7 +404,7 @@
 let userMsgHistory = [];
 // 涓嬫鍔犺浇鐢ㄦ埛鎻愰棶绱㈠紩浣嶇疆
 let nextUserMsgEndIndex = 0;
-
+const chatListLoading = ref(false);
 onMounted(async () => {
 	const res = await QueryHistoryDetail({
 		history_group_id: currentRouteId,
@@ -409,7 +413,8 @@
 	nextUserMsgEndIndex = userMsgHistory.length;
 	// 鎴彇鍊掓暟 LOAD_CHAT_LIMIT 鏉$敤鎴锋秷鎭�
 	const currentUserMsgList = userMsgHistory.slice(nextUserMsgEndIndex - LOAD_CHAT_LIMIT, nextUserMsgEndIndex);
-	messageList.value = currentUserMsgList.map((item) => {
+
+	const tmpMessageList = currentUserMsgList.map((item) => {
 		return {
 			historyId: item.history_id,
 			role: RoleEnum.user,
@@ -421,44 +426,55 @@
 	});
 	const sectionAIdMap = new Map();
 
-	// 鑾峰彇缁撴灉鎻掑叆鍒扮敤鎴锋彁闂箣鍚�
-	currentUserMsgList.map((item) => {
-		sectionAIdMap.set(item.history_id, item.section_a_id);
-		getAnswerById(item.history_id).then((aiRobot) => {
-			// 鐢ㄦ埛鎻愰棶绱㈠紩
-			const userMsgIndex = messageList.value.findIndex((subItem) => subItem?.historyId === item.history_id);
-			const userMsg = messageList.value[userMsgIndex];
-			// values 鍙栧洖绛斾箣鍚庢渶缁堢殑 question
-			userMsg.content.values = aiRobot.answer?.question ?? userMsg.content.values;
-			messageList.value.splice(
-				userMsgIndex + 1,
+	try {
+		chatListLoading.value = true;
+		const resList = await Promise.all(
+			(currentUserMsgList ?? []).map((item) => {
+				sectionAIdMap.set(item.history_id, item.section_a_id);
+				return getAnswerById(item.history_id);
+			})
+		);
+		let i = 0;
+		resList.map((item, index) => {
+			const insertIndex = index + 1 + i;
+			const userMsg = tmpMessageList[insertIndex - 1];
+			userMsg.content.values = item?.answer?.question ?? userMsg.content.values;
+			tmpMessageList.splice(
+				insertIndex,
 				0,
-				aiRobot.answer === null
+				item.answer === null
 					? null
 					: {
-							historyId: aiRobot.answer?.history_id,
+							historyId: item.answer?.history_id,
 							role: RoleEnum.assistant,
-							content: parseContent(aiRobot.answer),
-							state: aiRobot.answer_state,
-							sectionAId: sectionAIdMap.get(aiRobot.answer.history_id),
+							content: parseContent(item.answer),
+							state: item.answer_state,
+							sectionAId: sectionAIdMap.get(item.answer.history_id),
 					  }
 			);
+			i++;
 		});
-	});
-
-	if (messageList.value.length === 0) {
+	} finally {
+		chatListLoading.value = false;
+	}
+	messageList.value = tmpMessageList;
+	if (tmpMessageList.length === 0) {
 		messageContent.value = {
 			type: AnswerType.Text,
 			values: activeChatRoom.value.title,
 		};
 
 		sendChatMessage();
+	} else {
+		setTimeout(() => {
+			// 鍒濆鐘舵�佹粴涓�涓�
+			scrollToBottom();
+		}, 300);
 	}
 });
 
-const { forbidScroll } = useScrollToBottom({
+const { scrollToBottom } = useScrollToBottom({
 	chatListDom: chatListDom,
-	displayMessageList: computedMessageList,
 });
 
 //#region ====================== 鍏宠仈鏌ヨ ======================
@@ -495,7 +511,6 @@
 	showFixQuestion,
 	showAskMore,
 } = useAssistantContentOpt({
-	forbidScroll,
 	sendChatMessage,
 	displayMessageList: computedMessageList,
 });
diff --git a/src/components/chat/hooks/useAssistantContentOpt.ts b/src/components/chat/hooks/useAssistantContentOpt.ts
index a691603..843bc1c 100644
--- a/src/components/chat/hooks/useAssistantContentOpt.ts
+++ b/src/components/chat/hooks/useAssistantContentOpt.ts
@@ -9,13 +9,12 @@
 import { onClickOutside } from '@vueuse/core';
 
 export type AssistantContentOptOption = {
-	forbidScroll: Ref<boolean>;
 	sendChatMessage: any;
 	displayMessageList: ComputedRef<ChatMessage[]>;
 };
 
 export const useAssistantContentOpt = (option: AssistantContentOptOption) => {
-	const { forbidScroll, sendChatMessage, displayMessageList } = option;
+	const { sendChatMessage, displayMessageList } = option;
 	const { toClipboard } = useClipboard();
 	const preQuestion = ref(null);
 
@@ -38,10 +37,7 @@
 			answer_state: toSetState,
 		});
 		item.state = toSetState;
-		forbidScroll.value = true;
-		nextTick(() => {
-			forbidScroll.value = false;
-		});
+		
 	};
 
 	const unLikeClick = async (item) => {
@@ -52,10 +48,7 @@
 		});
 		item.state = toSetState;
 
-		forbidScroll.value = true;
-		nextTick(() => {
-			forbidScroll.value = false;
-		});
+	
 	};
 	const feedbackPosition = ref({
 		x: 0,
diff --git a/src/components/chat/hooks/useScrollToBottom.ts b/src/components/chat/hooks/useScrollToBottom.ts
index 3272653..f7484b2 100644
--- a/src/components/chat/hooks/useScrollToBottom.ts
+++ b/src/components/chat/hooks/useScrollToBottom.ts
@@ -6,49 +6,36 @@
 
 export type UseScrollToBottomOption = {
 	chatListDom: Ref<HTMLDivElement>;
-	displayMessageList: ComputedRef<ChatMessage[]>;
 };
 
 export const useScrollToBottom = (option: UseScrollToBottomOption) => {
-	const { chatListDom, displayMessageList } = option;
+	const { chatListDom } = option;
 
 	const scrollToBottom = () => {
-		if (!chatListDom.value) return;
-		const parent = chatListDom.value.parentElement;
-		if (!parent) return;
-		if (parent.scrollHeight > parent.clientHeight) {
-			parent.scrollTop = parent.scrollHeight - parent.clientHeight;
-		}
+		nextTick(() => {
+			if (!chatListDom.value) return;
+			const parent = chatListDom.value.parentElement;
+			if (!parent) return;
+			if (parent.scrollHeight > parent.clientHeight) {
+				parent.scrollTop = parent.scrollHeight - parent.clientHeight;
+			}
+		});
 	};
 	const debounceAmisScroll = debounce(({ instance }) => {
-		nextTick(() => {
-			scrollToBottom();
-		});
+		scrollToBottom();
 	}, 500);
 
-	emitter.on('amis.page.ready', debounceAmisScroll);
+	// emitter.on('amis.page.ready', debounceAmisScroll);
 
-	onUnmounted(()=>{
-		emitter.off('amis.page.ready');
-	})
-	const forbidScroll = ref(false);
-	watch(
-		displayMessageList,
-		() => {
-			if (forbidScroll.value) return;
-			nextTick(() => scrollToBottom());
-		},
-		{
-			deep: true,
-		}
-	);
+	// onUnmounted(() => {
+	// 	emitter.off('amis.page.ready');
+	// });
 
 	onActivated(() => {
-		if (forbidScroll.value) return;
-		nextTick(() => scrollToBottom());
+		scrollToBottom();
 	});
 
 	return {
-		forbidScroll,
+		scrollToBottom,
 	};
 };

--
Gitblit v1.9.3