108 lines
4.6 KiB
JavaScript
108 lines
4.6 KiB
JavaScript
import { defineStore } from "pinia";
|
|
import { messagesDb } from "@/utils/db/messageDB";
|
|
import { messageService } from "@/services/message";
|
|
|
|
export const useChatStore = defineStore('chat', {
|
|
state: () => ({
|
|
activeSessionId: null,
|
|
activeConversationId: null,
|
|
messages: [],
|
|
pageSize: 20
|
|
}),
|
|
actions: {
|
|
// 抽取统一的排序去重方法
|
|
pushAndSortMessages(newMsgs) {
|
|
const combined = [...this.messages, ...newMsgs];
|
|
// 1. 根据 msgId 或唯一 key 去重
|
|
const uniqueMap = new Map();
|
|
combined.forEach(m => uniqueMap.set(m.msgId || m.id, m));
|
|
|
|
// 2. 转换为数组并按时间戳升序排序 (旧的在前,新的在后)
|
|
this.messages = Array.from(uniqueMap.values()).sort((a, b) => {
|
|
return new Date(a.timeStamp).getTime() - new Date(b.timeStamp).getTime();
|
|
});
|
|
},
|
|
async addMessage(msg, sessionId) {
|
|
await messagesDb.save({ ...msg, sessionId, isLoading: false });
|
|
this.messages.push({ ...msg, sessionId })
|
|
},
|
|
/**
|
|
* 切换会话加载当前会话消息列表
|
|
* @param {*} sessionId
|
|
*/
|
|
async swtichSession(sessionId, conversationId) {
|
|
this.activeSessionId = sessionId;
|
|
this.activeConversationId = conversationId;
|
|
this.messages = [];
|
|
//先从浏览器缓存加载一部分消息列表
|
|
const localHistory = await messagesDb.getPageMessages(sessionId, new Date().toISOString(), this.pageSize);
|
|
console.log(localHistory)
|
|
if (localHistory.length > 0) {
|
|
this.messages = localHistory;
|
|
} else {
|
|
//如果本地没有消息数据则从后端拉取数据
|
|
const conversation = (await messageService.getConversationById(this.activeConversationId)).data;
|
|
const serverHistoryMsg = await this.fetchHistoryFromServer(this.activeConversationId, conversation.lastReadMessageId);
|
|
//对消息进行过滤,防止重复消息
|
|
const filterMsg = serverHistoryMsg.filter(m => !this.messages.find(exist => exist.msgId === m.msgId));
|
|
this.pushAndSortMessages([...filterMsg, ...this.messages]);
|
|
}
|
|
//拉取新消息
|
|
this.fetchNewMsgFromServier(this.activeConversationId).then((newMsg) => {
|
|
//去重
|
|
const filterNewMsg = newMsg.filter(m => !this.messages.find(exist => exist.msgId === m.msgId));
|
|
this.pushAndSortMessages([...filterNewMsg, ...this.messages])
|
|
});
|
|
},
|
|
/**
|
|
* 从服务器加载新消息
|
|
* @param {*} sessionId
|
|
* @returns
|
|
*/
|
|
async fetchNewMsgFromServier(conversationId) {
|
|
const newMsg = (await messageService.getMessages(conversationId)).data;
|
|
if (newMsg.length > 0) {
|
|
const sessionId = this.activeSessionId;
|
|
await Promise.all(newMsg.map(msg =>
|
|
messagesDb.save({ ...msg, sessionId })
|
|
));
|
|
return newMsg;
|
|
} else {
|
|
return [];
|
|
}
|
|
},
|
|
/**
|
|
* 从服务器加载历史消息
|
|
* @param {*} sessionId
|
|
* @param {*} msgId
|
|
* @returns
|
|
*/
|
|
async fetchHistoryFromServer(conversationId, msgId) {
|
|
const res = (await messageService.getHistoryMessages(conversationId, msgId, this.pageSize)).data;
|
|
|
|
if (res.length > 0) {
|
|
const sessionId = this.activeSessionId;
|
|
await Promise.all(res.map(msg =>
|
|
messagesDb.save({ ...msg, sessionId })
|
|
));
|
|
return res;
|
|
} else {
|
|
return [];
|
|
}
|
|
},
|
|
/**
|
|
* 加载更多历史消息
|
|
*/
|
|
async loadMoreMessages() {
|
|
const lastTimeStamp = this.messages.length > 0 ? this.messages[0].timeStamp : new Date().toISOString();
|
|
const history = await messagesDb.getPageMessages(this.activeSessionId, lastTimeStamp, this.pageSize);
|
|
if (history.length > 0) {
|
|
this.messages = [...history, ...this.messages]
|
|
} else {
|
|
const fetchMsg = await this.fetchHistoryFromServer(this.conversationId, this.messages[0].msgId);
|
|
const newMsgs = fetchMsg.filter(m => !this.messages.find(exist => exist.msgId === m.msgId));
|
|
this.pushAndSortMessages([...newMsgs, ...this.messages])
|
|
}
|
|
}
|
|
}
|
|
}) |