From 44025036ca9baea036a629c78273e9df48ba8e2e Mon Sep 17 00:00:00 2001
From: yangyin <1850366751@qq.com>
Date: 星期五, 05 七月 2024 14:04:39 +0800
Subject: [PATCH] fix: 修改应用场景

---
 src/components/chat/Chat.vue |  289 ++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 183 insertions(+), 106 deletions(-)

diff --git a/src/components/chat/Chat.vue b/src/components/chat/Chat.vue
index 4856176..d09d425 100644
--- a/src/components/chat/Chat.vue
+++ b/src/components/chat/Chat.vue
@@ -11,11 +11,28 @@
 								<component class="max-w-[100ch]" :is="answerTypeMapCom[item.content.type]" :data="item.content.values" />
 							</div>
 
-							<!-- <div v-if="item.role === RoleEnum.assistant" class="absolute flex items-center right-0 space-x-2 mr-2 mt-2">
-								<SvgIcon class="cursor-pointer" name="ele-CopyDocument" @click="copyClick(item.content)" />
-								<SvgIcon class="cursor-pointer" name="ywicon icon-dianzan" />
-								<SvgIcon class="cursor-pointer" :size="12" name="ywicon icon-buzan" />
-							</div> -->
+							<div v-if="item.role === RoleEnum.assistant" class="absolute flex items-center right-0 mr-2 mt-2 space-x-2">
+								<div class="flex items-center justify-center size-[15px]" v-if="item.content?.type === AnswerType.Text">
+									<i
+										class="p-2 ywicon icon-copy cursor-pointer hover:text-[#0284ff] hover:!text-[18px]"
+										@click="copyClick(item.content.values)"
+									/>
+								</div>
+								<div class="flex items-center justify-center size-[15px]">
+									<i
+										:class="{ 'text-[#0284ff]': item.state === AnswerState.Like }"
+										class="p-2 ywicon icon-dianzan cursor-pointer hover:text-[#0284ff] font-medium hover:!text-[18px]"
+										@click="likeClick(item)"
+									/>
+								</div>
+								<div class="flex items-center justify-center size-[15px]">
+									<i
+										:class="{ 'text-[#0284ff]': item.state === AnswerState.Unlike }"
+										class="p-2 ywicon icon-buzan cursor-pointer hover:text-[#0284ff] !text-[13px] hover:!text-[15px]"
+										@click="unLikeClick(item)"
+									/>
+								</div>
+							</div>
 						</div>
 
 						<Loding v-else />
@@ -31,18 +48,16 @@
 </template>
 
 <script setup lang="ts">
-import { computed, nextTick, onMounted, ref, watch } from 'vue';
+import { ElMessage } from 'element-plus';
+import { computed, nextTick, ref, watch } from 'vue';
 import useClipboard from 'vue-clipboard3';
 import Loding from './components/Loding.vue';
-import { RecordSet } from './model/Record';
 import type { ChatContent } from './model/types';
-import { AnswerType, RoleEnum, answerTypeMapCom, roleImageMap, type ChatMessage } from './model/types';
-import { GetHistoryAnswer, QueryHistoryDetail, QuestionAi } from '/@/api/ai/chat';
+import { AnswerType, RoleEnum, answerTypeMapCom, roleImageMap, type ChatMessage, AnswerState } from './model/types';
+import { GetHistoryAnswer, QueryHistoryDetail, QuestionAi, SetHistoryAnswerState } from '/@/api/ai/chat';
 import PlayBar from '/@/components/chat/components/playBar/PlayBar.vue';
 import router from '/@/router';
-import { activeChatRoom, activeRoomId } from '/@/stores/chatRoom';
-import { ElMessage } from 'element-plus';
-import { content } from 'html2canvas/dist/types/css/property-descriptors/content';
+import { activeChatRoom, activeLLMId, activeRoomId, activeSampleId, activeSectionAId } from '/@/stores/chatRoom';
 
 let isTalking = ref(false);
 let messageContent = ref<ChatContent>({
@@ -54,66 +69,6 @@
 const computedMessageList = computed(() => {
 	return messageList.value.filter((v) => v.role !== RoleEnum.system);
 });
-// onMounted(() => {
-// 	if (!activeChatRoom.value) {
-// 		router.replace({
-// 			name: 'Home',
-// 		});
-// 		return;
-// 	}
-// 	messageContent.value = {
-// 		type: AnswerType.Text,
-// 		values: activeChatRoom.value.title,
-// 	};
-// 	sendChatMessage();
-// });
-
-const getAnswerById = async (historyId: string) => {
-	return await GetHistoryAnswer({
-		history_id: historyId,
-	});
-};
-let currentSectionId = '';
-watch(
-	() => activeRoomId.value,
-	async (val) => {
-		if (!val) {
-			router.replace({
-				name: 'Home',
-			});
-			return;
-		}
-
-		const res = await QueryHistoryDetail({
-			history_group_id: activeRoomId.value,
-		});
-		messageList.value = (res.details ?? []).map((item) => {
-			return {
-				role: RoleEnum.user,
-				content: {
-					type: AnswerType.Text,
-					values: item.question,
-				},
-			} as ChatMessage;
-		});
-		currentSectionId = res?.details?.[0]?.section_a_id;
-		const resList = await Promise.all((res.details ?? []).map((item) => getAnswerById(item.history_id)));
-		let i = 0;
-
-		resList.map((item, index) => {
-			const insertIndex = index + 1 + i;
-			messageList.value.splice(insertIndex, 0, {
-				role: RoleEnum.assistant,
-				content: parseContent(item.answer),
-			});
-			i++;
-		});
-		
-	},
-	{
-		immediate: true,
-	}
-);
 
 const parseContent = (res) => {
 	let content: ChatContent = {
@@ -157,12 +112,29 @@
 	return content;
 };
 
+let questionRes = null;
 const questionAi = async (text) => {
-	const res = await QuestionAi({
+	if (!currentSectionId) {
+		ElMessage.warning('鍙戦�佸け璐ワ紝鏈‘瀹氬簲鐢ㄥ満鏅紒');
+	}
+
+	const params = {
 		question: text,
+		// FIXME: 鏆傛椂杩欐牱
 		section_a_id: currentSectionId,
 		history_group_id: activeRoomId.value,
-	});
+	} as any;
+
+	if (currentSampleId) {
+		params.sample_id = currentSampleId;
+	}
+
+	if (currentLLMId) {
+		params.llm_id = currentLLMId;
+	}
+
+	const res = await QuestionAi(params);
+	questionRes = res;
 	// const res = {
 	// 	json_ok: true,
 	// 	question: '鏄ㄦ棩浜斾竴骞垮満鍘嬪姏',
@@ -182,38 +154,6 @@
 	return content;
 };
 
-const sendChatMessage = async (content: ChatContent = messageContent.value) => {
-	if (!messageContent.value?.values) return;
-	if (activeChatRoom.value.isInitial) {
-		activeChatRoom.value.title = messageContent.value.values;
-		activeChatRoom.value.isInitial = false;
-	}
-	try {
-		isTalking.value = true;
-		// 鍙戦�佸綋鍓�
-		messageList.value.push({ role: RoleEnum.user, content });
-		// 娓呯┖杈撳叆妗�
-		clearMessageContent();
-		// 鍑虹幇鍥炲锛岀疆绌哄嚭鐜扮瓑寰呭姩鐢�
-		messageList.value.push({ role: RoleEnum.assistant, content: null });
-
-		let resMsgContent: ChatContent = null;
-		resMsgContent = await questionAi(content.values);
-		appendLastMessageContent(resMsgContent);
-	} catch (error: any) {
-		appendLastMessageContent({
-			type: AnswerType.Text,
-			values: '鍙戠敓閿欒锛�',
-		});
-	} finally {
-		isTalking.value = false;
-	}
-};
-
-const appendLastMessageContent = (content: ChatContent) => {
-	messageList.value.at(-1).content = content;
-};
-
 const clearMessageContent = () =>
 	(messageContent.value = {
 		type: AnswerType.Text,
@@ -224,10 +164,120 @@
 	if (!chatListDom.value) return;
 	chatListDom.value.lastElementChild?.scrollIntoView();
 };
+let currentSectionId = null;
+let currentSampleId = null;
 
+let currentLLMId = null;
+const getAnswerById = async (historyId: string) => {
+	return await GetHistoryAnswer({
+		history_id: historyId,
+	});
+};
+const sendChatMessage = async (content: ChatContent = messageContent.value) => {
+	if (!messageContent.value?.values) return;
+	if (activeChatRoom.value.isInitial) {
+		activeChatRoom.value.title = messageContent.value.values;
+		activeChatRoom.value.isInitial = false;
+		if (activeSampleId.value) {
+			currentSampleId = activeSampleId.value;
+		}
+
+		if (activeLLMId.value) {
+			currentLLMId = activeLLMId.value;
+		}
+
+		if (activeSectionAId.value) {
+			currentSectionId = activeSectionAId.value;
+		}
+	}
+	try {
+		isTalking.value = true;
+		const userItem: ChatMessage = { role: RoleEnum.user, content } as any;
+		const assistantItem: ChatMessage = { role: RoleEnum.assistant, content: null, state: AnswerState.Null } as any;
+		// 鍙戦�佸綋鍓�
+		messageList.value.push(userItem);
+		// 娓呯┖杈撳叆妗�
+		clearMessageContent();
+
+		// 鍑虹幇鍥炲锛岀疆绌哄嚭鐜扮瓑寰呭姩鐢�
+		messageList.value.push(assistantItem);
+
+		let resMsgContent: ChatContent = null;
+		resMsgContent = await questionAi(content.values);
+		userItem.historyId = questionRes.history_id;
+		assistantItem.historyId = questionRes.history_id;
+		appendLastMessageContent(resMsgContent);
+	} catch (error: any) {
+		appendLastMessageContent({
+			type: AnswerType.Text,
+			values: '鍙戠敓閿欒锛�',
+		});
+	} finally {
+		isTalking.value = false;
+	}
+};
+const appendLastMessageContent = (content: ChatContent) => {
+	if (messageList.value.at(-1)) {
+		messageList.value.at(-1).content = content;
+	}
+};
+
+watch(
+	() => activeRoomId.value,
+	async (val) => {
+		if (!val) {
+			router.replace({
+				name: 'Home',
+			});
+			return;
+		}
+		if (activeChatRoom.value.isInitial) {
+			messageContent.value = {
+				type: AnswerType.Text,
+				values: activeChatRoom.value.title,
+			};
+			sendChatMessage();
+		} else {
+			const res = await QueryHistoryDetail({
+				history_group_id: activeRoomId.value,
+			});
+			messageList.value = (res.details ?? []).map((item) => {
+				return {
+					historyId: item.history_id,
+					role: RoleEnum.user,
+					content: {
+						type: AnswerType.Text,
+						values: item.question,
+					},
+				} as ChatMessage;
+			});
+			currentSectionId = res?.details?.[0]?.section_a_id;
+			currentSampleId = res?.details?.[0]?.sample_id;
+			const resList = await Promise.all((res.details ?? []).map((item) => getAnswerById(item.history_id)));
+			let i = 0;
+
+			resList.map((item, index) => {
+				const insertIndex = index + 1 + i;
+				messageList.value.splice(insertIndex, 0, {
+					historyId: item.answer.history_id,
+					role: RoleEnum.assistant,
+					content: parseContent(item.answer),
+					state: item.answer_state,
+				});
+				i++;
+			});
+		}
+	},
+	{
+		immediate: true,
+	}
+);
+
+let forbidScroll = false;
 watch(
 	messageList,
 	() => {
+		if (forbidScroll) return;
 		nextTick(() => scrollToBottom());
 	},
 	{
@@ -243,6 +293,33 @@
 	ElMessage.success('澶嶅埗鎴愬姛');
 	toClipboard(content);
 };
+
+const likeClick = async (item) => {
+	const toSetState = item.state === AnswerState.Like ? AnswerState.Null : AnswerState.Like;
+	const res = await SetHistoryAnswerState({
+		history_id: item.historyId,
+		answer_state: toSetState,
+	});
+	item.state = toSetState;
+	forbidScroll = true;
+	nextTick(() => {
+		forbidScroll = false;
+	});
+};
+
+const unLikeClick = async (item) => {
+	const toSetState = item.state === AnswerState.Unlike ? AnswerState.Null : AnswerState.Unlike;
+	const res = await SetHistoryAnswerState({
+		history_id: item.historyId,
+		answer_state: toSetState,
+	});
+	item.state = toSetState;
+
+	forbidScroll = true;
+	nextTick(() => {
+		forbidScroll = false;
+	});
+};
 //#endregion
 </script>
 

--
Gitblit v1.9.3