From 05f34e1af59e139e6e914e772ba7dcd5b4bf680d Mon Sep 17 00:00:00 2001 From: yangyin <1850366751@qq.com> Date: 星期四, 31 十月 2024 15:56:26 +0800 Subject: [PATCH] 修改当天询问的问题时间 --- src/components/chat/Chat.vue | 164 ++++++++++++++++++++++++++++-------------------------- 1 files changed, 86 insertions(+), 78 deletions(-) diff --git a/src/components/chat/Chat.vue b/src/components/chat/Chat.vue index 1a85964..3fb1699 100644 --- a/src/components/chat/Chat.vue +++ b/src/components/chat/Chat.vue @@ -1,14 +1,19 @@ <template> <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="relative h-full flex flex-col items-center overflow-y-auto"> + <span + class="more-loading absolute text-blue-400 left-[50%] translate-x-[-50%] cursor-pointer w-10" + v-loading="moreIsLoading" + ></span> + <div class="h-full relative" 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 }" v-for="(item, index) of computedMessageList" - :key="index" + :key="`${item.historyId}_${item.role}`" > + <div class="absolute top-0 left-[72px] text-[#8d8e99]">{{ item?.createTime }}</div> <img class="rounded-full size-12 flex-0" :class="{ 'mr-4': item.role === RoleEnum.assistant, 'ml-4': item.role === RoleEnum.user }" @@ -119,11 +124,11 @@ </div> </div> - <Loding v-if="isTalking && index === messageList.length - 1" class="w-fit" :process="process" /> + <Loding v-if="isTalking && index === computedMessageList.length - 1" class="w-fit" :process="process" /> </div> </div> </div> - <div v-if="showAskMore" class="ml-4 mt-5 text-sm"> + <div v-if="showAskMore" class="ml-4 mt-5 text-sm pb-10"> <div class="text-gray-600 mb-5">浣犲彲浠ョ户缁棶鎴戯細</div> <div class="space-y-2 inline-flex flex-col"> <div @@ -139,7 +144,7 @@ </div> </div> - <div class="sticky bottom-0 w-full p-6 pb-8 bg-[rgb(247,248,250)] flex justify-center"> + <div class="sticky bottom-0 w-full p-6 bg-[rgb(247,248,250)] flex justify-center"> <PlayBar v-model:voicePageIsShow="voicePageIsShow" :isTalking="isTalking" @@ -156,22 +161,32 @@ </template> <script setup lang="ts"> -import { ElMessage } from 'element-plus'; import _ from 'lodash'; +import moment from 'moment'; import { v4 as uuidv4 } from 'uuid'; import { computed, onMounted, ref } from 'vue'; import FeedbackPanel from './components/FeedbackPanel.vue'; import Loding from './components/Loding.vue'; import { useAssistantContentOpt } from './hooks/useAssistantContentOpt'; import { useQueryProcess } from './hooks/useQueryProcess'; +import { useScrollLoad } from './hooks/useScrollLoad'; import { useScrollToBottom } from './hooks/useScrollToBottom'; import type { ChatContent } from './model/types'; import { AnswerState, AnswerType, RoleEnum, answerTypeMapCom, roleImageMap, type ChatMessage } from './model/types'; -import { GetHistoryAnswer, QueryHistoryDetail, QuestionAi, extCallQuery } from '/@/api/ai/chat'; +import { QuestionAi, extCallQuery } from '/@/api/ai/chat'; import PlayBar from '/@/components/chat/components/playBar/PlayBar.vue'; import CustomDrawer from '/@/components/drawer/CustomDrawer.vue'; import router from '/@/router'; -import { activeChatRoom, activeLLMId, activeSampleId, activeSectionAId, getRoomConfig, roomConfig } from '/@/stores/chatRoom'; +import { + activeChatRoom, + activeGroupType, + activeLLMId, + activeRoomId, + activeSampleId, + activeSectionAId, + getRoomConfig, + roomConfig, +} from '/@/stores/chatRoom'; import { ErrorCode } from '/@/utils/request'; const chatWidth = '75%'; @@ -183,12 +198,12 @@ }); const currentRoute = router.currentRoute; const currentRouteId = currentRoute.value.query.id as string; +activeRoomId.value = currentRouteId; const chatListDom = ref<HTMLDivElement>(); const messageList = ref<ChatMessage[]>([]); const computedMessageList = computed(() => { return messageList.value.filter((v) => !!v); }); - const parseContent = (res) => { if (!res) return null; let content: ChatContent = { @@ -248,15 +263,12 @@ content.origin = res; return content; }; - const { clearQueryProcess, process, processId, queryProcess } = useQueryProcess(); const DEFAULT_SECTION_A_ID = 'knowledge_base'; - let questionRes = null; let finalCalcSectionAId = null; const questionAi = async (text) => { - processId.value = uuidv4(); let judgeParams = null; if (!preQuestion.value) { @@ -267,7 +279,7 @@ // prev_question: lastQuestion, // } // : {}; - // 姝e父鍥炵瓟鏆傛椂涓嶉噰鐢� + // 姝e父鍥炵瓟鏆傛椂涓嶉噰鐢� judgeParams = {}; } else { judgeParams = { @@ -279,20 +291,27 @@ currentSectionAId = activeSectionAId.value; activeSectionAId.value = ''; } else { - const lastSectionAItem = _.findLast(computedMessageList.value as any, (item) => item.role === RoleEnum.assistant && !!item.sectionAId); + const lastSectionAItem = _.findLast( + computedMessageList.value as any, + (item) => item.role === RoleEnum.assistant && !!item.sectionAId + ); currentSectionAId = lastSectionAItem?.sectionAId ?? DEFAULT_SECTION_A_ID; } finalCalcSectionAId = currentSectionAId; - + const params = { process_id: processId.value, question: text, // FIXME: 鏆傛椂杩欐牱 - section_a_id: currentSectionAId, + // section_a_id: currentSectionAId, history_group_id: currentRouteId, raw_mode: roomConfig.value?.[currentRouteId]?.isAnswerByLLM ?? false, ...judgeParams, } as any; + + if (activeGroupType.value) { + params.group_type = activeGroupType.value; + } if (currentSampleId) { params.sample_id = currentSampleId; @@ -322,14 +341,8 @@ let currentLLMId = null; -const getAnswerById = async (historyId: string) => { - return await GetHistoryAnswer({ - history_id: historyId, - }); -}; - 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) { @@ -339,8 +352,6 @@ if (activeLLMId.value) { currentLLMId = activeLLMId.value; } - - } let resMsgContent: ChatContent = null; @@ -355,6 +366,9 @@ // 鍑虹幇鍥炲锛岀疆绌哄嚭鐜扮瓑寰呭姩鐢� messageList.value.push(assistantItem); + // 婊氬姩鑷冲綋鍓嶅彂閫佹秷鎭� + scrollToBottom(); + if (isCallExtParams) { const extRes = await extCallQuery(isCallExtParams); questionRes = extRes; @@ -362,7 +376,7 @@ } else { resMsgContent = await questionAi(content.values); } - + nextUserMsgEndIndex.value++; if (isNewChat) { const firstResCb = getRoomConfig(currentRouteId, 'firstResCb'); firstResCb?.(resMsgContent); @@ -374,6 +388,10 @@ assistantItem.historyId = questionRes.history_id; assistantItem.sectionAId = finalCalcSectionAId; appendLastMessageContent(resMsgContent); + setTimeout(() => { + // 鏀跺埌鍥炲锛岀户缁粴 + scrollToBottom(); + }, 300); } catch (error: any) { // appendLastMessageContent({ // type: AnswerType.Text, @@ -388,56 +406,33 @@ sendChatMessage(messageContent.value, cb); }; const appendLastMessageContent = (content: ChatContent) => { + const currentTime = moment().format('MM骞碊D鏃� HH:mm:ss'); if (messageList.value.at(-1)) { messageList.value.at(-1).content = content; + messageList.value.at(-1).createTime = currentTime; } }; +const { loadRangeData, onChatListScroll, moreIsLoading, nextUserMsgEndIndex } = useScrollLoad({ + container: chatListDom, + historyGroupId: currentRouteId, + messageList, + parseAnswerContent: parseContent, +}); + +const chatListLoading = ref(false); + +const { scrollToBottom } = useScrollToBottom({ + chatListDom: chatListDom, +}); onMounted(async () => { - const res = await QueryHistoryDetail({ - history_group_id: currentRouteId, + messageList.value = []; + // 鍔犺浇鍒濆鏁版嵁 + chatListLoading.value = true; + + await loadRangeData().finally(() => { + chatListLoading.value = false; }); - - messageList.value = (res.details ?? []).map((item) => { - return { - historyId: item.history_id, - role: RoleEnum.user, - content: { - type: AnswerType.Text, - values: item.question, - }, - } as ChatMessage; - }); - const sectionAIdMap = new Map(); - - const resList = await Promise.all( - (res.details ?? []).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 = messageList.value[insertIndex - 1]; - userMsg.content.values = item?.answer?.question ??userMsg.content.values; - messageList.value.splice( - insertIndex, - 0, - item.answer === null - ? null - : { - historyId: item.answer?.history_id, - role: RoleEnum.assistant, - content: parseContent(item.answer), - state: item.answer_state, - sectionAId: sectionAIdMap.get(item.answer.history_id), - - } - ); - i++; - }); - if (messageList.value.length === 0) { messageContent.value = { type: AnswerType.Text, @@ -445,14 +440,17 @@ }; sendChatMessage(); + } else { + setTimeout(() => { + // 鍒濆鐘舵�佹粴涓�涓� + scrollToBottom(); + + setTimeout(() => { + chatListDom.value.addEventListener('scroll', onChatListScroll); + }, 300); + }, 300); } }); - -const { forbidScroll } = useScrollToBottom({ - chatListDom: chatListDom, - displayMessageList: computedMessageList, -}); - //#region ====================== 鍏宠仈鏌ヨ ====================== const relativeQueryClick = async (val) => { sendChatMessage( @@ -487,7 +485,6 @@ showFixQuestion, showAskMore, } = useAssistantContentOpt({ - forbidScroll, sendChatMessage, displayMessageList: computedMessageList, }); @@ -501,10 +498,21 @@ //#endregion </script> -<style scoped> +<style scoped lang="scss"> pre { font-family: -apple-system, 'Noto Sans', 'Helvetica Neue', Helvetica, 'Nimbus Sans L', Arial, 'Liberation Sans', 'PingFang SC', 'Hiragino Sans GB', 'Noto Sans CJK SC', 'Source Han Sans SC', 'Source Han Sans CN', 'Microsoft YaHei', 'Wenquanyi Micro Hei', 'WenQuanYi Zen Hei', 'ST Heiti', SimHei, 'WenQuanYi Zen Hei Sharp', sans-serif; } + +.more-loading { + :deep(.el-loading-spinner) { + --loading-size: 35px; + margin-top: 0; + .circular { + width: var(--loading-size); + height: var(--loading-size); + } + } +} </style> -- Gitblit v1.9.3