From a85cba463afc431acb4b963348e249ed7916bfd8 Mon Sep 17 00:00:00 2001 From: wujingjing <gersonwu@qq.com> Date: 星期日, 19 一月 2025 11:52:46 +0800 Subject: [PATCH] chat_start message notification --- src/components/chat/hooks/useSyncMsg.ts | 155 ++++++++++++++++++++++++++++----------------------- 1 files changed, 86 insertions(+), 69 deletions(-) diff --git a/src/components/chat/hooks/useSyncMsg.ts b/src/components/chat/hooks/useSyncMsg.ts index 1403909..1bcbf4f 100644 --- a/src/components/chat/hooks/useSyncMsg.ts +++ b/src/components/chat/hooks/useSyncMsg.ts @@ -1,85 +1,102 @@ -import { reverse } from 'lodash-es'; -import { type Ref } from 'vue'; -import type { ChatMessage } from '../model/types'; -import { MAIN_URL } from '/@/constants'; -import { SSEClient } from '/@/utils/sse/SSEClient'; -import { Local } from '/@/utils/storage'; -import { accessSessionKey } from '/@/utils/request'; +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 { Logger } from '/@/model/logger/Logger'; +import { ElNotification } from 'element-plus'; 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 } = options; - // 鍒涘缓瀹炰緥 - const sseClient = new SSEClient( - `${MAIN_URL}chat/connect_broadcast_chat`, + const { updateLoadIndex, msgList, historyGroupId, checkCanSync, loadReplyData, scrollToBottom } = options; - {}, - { - onMessage: (data) => { - return; - const recentIds = reverse([ - { id: 'a1b2c3d4', time: '2024-03-27 15:42:33' }, - { id: 'e5f6g7h8', time: '2024-02-15 09:23:45' }, - { id: 'i9j0k1l2', time: '2024-05-08 14:37:21' }, - { id: 'm3n4o5p6', time: '2024-01-30 11:55:16' }, - { id: 'q7r8s9t0', time: '2024-07-12 16:48:59' }, - { id: 'u1v2w3x4', time: '2024-04-03 10:15:27' }, - { id: 'y5z6a7b8', time: '2024-06-21 13:29:44' }, - { id: 'c9d0e1f2', time: '2024-08-09 17:52:38' }, - { id: 'g3h4i5j6', time: '2024-09-14 12:33:51' }, - { id: 'k7l8m9n0', time: '2024-10-25 08:19:07' }, - ]); - // const userHistoryIds = reverse(msgList.value.filter((item) => item.role === RoleEnum.user).map((item) => item.historyId)); - const userHistoryIds = reverse([ - { id: 'a1b2c3d4', time: '2024-03-27 15:42:33' }, - { id: 'e5f6g7h8', time: '2024-02-15 09:23:45' }, - // {id: 'i9j0k1l2', time: '2024-05-08 14:37:21'}, - // {id: 'm3n4o5p6', time: '2024-01-30 11:55:16'}, - { id: 'q7r8s9t0', time: '2024-07-12 16:48:59' }, - // {id: 'u1v2w3x4', time: '2024-04-03 10:15:27'}, - { id: 'y5z6a7b8', time: '2024-06-21 13:29:44' }, - { id: 'c9d0e1f2', time: '2024-08-09 17:52:38' }, - { id: 'g3h4i5j6', time: '2024-09-14 12:33:51' }, - // {id: 'k7l8m9n0', time: '2024-10-25 08:19:07'}, - ]); - - // 鑾峰彇鏈悓姝ョ殑娑堟伅 - const unsyncedMessages = findUnsyncedMessages(recentIds, userHistoryIds); - console.log('鏈悓姝ョ殑娑堟伅:', unsyncedMessages); - }, - onError: (error) => { - console.error('SSE error:', error); - }, - onOpen: () => { - console.log('SSE connection opened'); - }, - onClose: () => { - console.log('SSE connection closed'); - }, - onRetry: (retryCount) => { - console.log(`Retrying connection (${retryCount})`); - }, + 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; + } + } } - ); - sseClient.connect({ - websessionid: Local.get(accessSessionKey), + insertResult.forEach((resultItem) => { + msgList.value.splice(resultItem.index, 0, ...resultItem.item); + }); + }; + const historyUpdate = async (data: any) => { + if (!checkCanSync(data)) return; + if (!data) return; + Logger.info('sync message notification锛歕n\n' + JSON.stringify(data)); + + if (data?.type === 'chat_start') { + const fromTitle = data?.from || '鏈煡绔�'; + ElNotification({ + title: fromTitle, + message: `姝e湪澶勭悊鏂扮殑鎻愰棶锛岃鑰愬績绛夊緟锛屽璇濆畬鎴愬悗浼氳嚜鍔ㄥ悓姝, + type: 'info', + duration: 4000, + }); + } + 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) => ({ 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 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(() => { + sseClient?.subscribe(historyUpdate); }); - // onMounted(() => { - // sseClient.connect({}); - // }); + onDeactivated(() => { + sseClient?.unsubscribe(historyUpdate); + }); // onUnmounted(() => { // sseClient.disconnect(); // }); - - return { - reconnect: () => sseClient.reconnect(), - disconnect: () => sseClient.disconnect(), - isConnected: () => sseClient.isConnected(), - }; }; -- Gitblit v1.9.3