From f1360cc184810c1458af6577b9e43f32aca7b24d Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期四, 16 一月 2025 14:18:37 +0800 Subject: [PATCH] 消息同步 --- src/components/chat/hooks/useSyncMsg.ts | 94 +++++++++++++++++++++++++++++------------------ 1 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/components/chat/hooks/useSyncMsg.ts b/src/components/chat/hooks/useSyncMsg.ts index 4e5c82d..8a17e9c 100644 --- a/src/components/chat/hooks/useSyncMsg.ts +++ b/src/components/chat/hooks/useSyncMsg.ts @@ -1,65 +1,87 @@ +import { differenceBy } from 'lodash-es'; +import moment from 'moment'; import { onActivated, onDeactivated, unref, type Ref } from 'vue'; import { RoleEnum, type ChatMessage } from '../model/types'; import { QueryHistoryDetail } from '/@/api/ai/chat'; import { sseClient } from '/@/stores/global'; -import { LOAD_CHAT_LIMIT } from '../constants'; -import { differenceBy } from 'lodash-es'; type UseSyncMsgOptions = { updateLoadIndex: (addCount: number) => void; msgList: Ref<ChatMessage[]>; historyGroupId: string | Ref<string>; + checkCanSync: (data: any) => boolean; + loadReplyData: (data: any) => Promise<ChatMessage[]>; + scrollToBottom: () => void; }; export const useSyncMsg = (options: UseSyncMsgOptions) => { - const { updateLoadIndex, msgList, historyGroupId } = options; + const { updateLoadIndex, msgList, historyGroupId, checkCanSync, loadReplyData, scrollToBottom } = options; - // const loadRangeData = async (lastEnd = nextUserMsgEndIndex) => { - // const res = await QueryHistoryDetail({ - // history_group_id: unref(historyGroupId), - // last_end: lastEnd, - // last_count: LOAD_CHAT_LIMIT, - // }); - // const result: ChatMessage[] = res.details ?? []; - // if (result.length) { - // nextUserMsgEndIndex += result.length; - // const rangeMsgList = await loadReplyData(res.details); - // messageList.value.unshift(...rangeMsgList); - // } else { - // isNoMore = true; - // } - - // return result; - // }; + const insertSyncMsg = (replayData: any[]) => { + const insertResult: { index: number; item: any }[] = []; + for (let i = replayData.length - 1; i >= 0; i--) { + const insertItem = replayData[i]; + if (insertItem.role === RoleEnum.assistant) continue; + for (let j = msgList.value.length - 1; j >= 0; j--) { + const currentItem = msgList.value[j]; + if (currentItem.role === RoleEnum.assistant) continue; + if (moment(insertItem.createTime).isAfter(currentItem.createTime)) { + const insertAssistantItem = replayData[i + 1]; + insertResult.push({ + index: j + 2, + item: [insertItem, insertAssistantItem], + }); + break; + } + } + } + insertResult.forEach((resultItem) => { + msgList.value.splice(resultItem.index, 0, ...resultItem.item); + }); + }; const historyUpdate = async (data: any) => { + if (!checkCanSync(data)) return; if (!data) return; - const groupId = unref(historyGroupId); - if (!groupId) return; + if (data?.type === 'chat_history_id') { + const groupId = unref(historyGroupId); + if (!groupId) return; const recentIds = data.id_list ?? []; + const recentGroupHistoryIds = recentIds.filter((item) => item.group_id === groupId); + if (recentGroupHistoryIds.length === 0) return; const userHistoryIds = msgList.value .filter((item) => item.role === RoleEnum.user) - .map((item) => ({ id: item.historyId, time: item.createTime })); - const unSyncedHistoryIds = differenceBy(recentIds, userHistoryIds, 'id'); - console.log('unSyncedHistoryIds', unSyncedHistoryIds); - } + .map((item) => ({ history_id: item.historyId, time: item.createTime })); + const tmpUnSyncedHistoryIds = differenceBy(recentGroupHistoryIds, userHistoryIds, 'history_id') as any[]; + const latestUserHistory = userHistoryIds[userHistoryIds.length - 1]; + let unSyncedHistoryIds = tmpUnSyncedHistoryIds; + // 澶櫄鐨勪笉闇�瑕佹洿鏂� + if (latestUserHistory) { + unSyncedHistoryIds = tmpUnSyncedHistoryIds.filter((item) => moment(item.time).isAfter(latestUserHistory.time)); + } + if (!unSyncedHistoryIds || unSyncedHistoryIds.length === 0) return; + const res = await QueryHistoryDetail({ + history_group_id: groupId, + id_list: unSyncedHistoryIds.map((item) => item.history_id).join(','), + }); + if (!checkCanSync(data)) return; - const res = await QueryHistoryDetail({ - history_group_id: groupId, - last_end: 0, - last_count: LOAD_CHAT_LIMIT, - }); - console.log('historyUpdate', data, groupId); + const result: ChatMessage[] = res.details ?? []; + if (!result || result.length === 0) return; + const replayData = await loadReplyData(res.details); + if (!checkCanSync(data)) return; + insertSyncMsg(replayData); + updateLoadIndex(unSyncedHistoryIds.length); + scrollToBottom(); + } }; onActivated(() => { - console.log('onActivated'); - sseClient.subscribe(historyUpdate); + sseClient?.subscribe(historyUpdate); }); onDeactivated(() => { - console.log('onDeactivated'); - sseClient.unsubscribe(historyUpdate); + sseClient?.unsubscribe(historyUpdate); }); // onUnmounted(() => { -- Gitblit v1.9.3