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