消息发送立即渲染逻辑重构

This commit is contained in:
bob
2025-04-09 11:17:57 +08:00
parent 06750ddf78
commit 026065f2f1
7 changed files with 116 additions and 126 deletions

View File

@@ -36,16 +36,17 @@ export const onReceiveChatMsg = (updateScroll, capacity) => {
...readParams
})
await messageData.addMsgRecords(sessionId, [
{
sessionId: sessionId,
msgId: msg.body.msgId,
fromId: msg.body.fromId,
msgType: MsgType.CHAT,
content: msg.body.content,
msgTime: now
}
])
const showMsg = {
sessionId: sessionId,
msgId: msg.body.msgId,
fromId: msg.body.fromId,
msgType: MsgType.CHAT,
content: msg.body.content,
msgTime: now
}
await messageData.preloadResource(sessionId, [showMsg])
messageData.addMsgRecords(sessionId, [showMsg])
messageData.updateMsgIdSort(sessionId)
if (!messageData.sessionList[sessionId].dnd) {
playMsgReceive()

View File

@@ -34,16 +34,17 @@ export const onReceiveGroupChatMsg = (updateScroll, capacity) => {
...readParams
})
await messageData.addMsgRecords(sessionId, [
{
sessionId: sessionId,
msgId: msg.body.msgId,
fromId: msg.body.fromId,
msgType: MsgType.GROUP_CHAT,
content: msg.body.content,
msgTime: now
}
])
const showMsg = {
sessionId: sessionId,
msgId: msg.body.msgId,
fromId: msg.body.fromId,
msgType: MsgType.GROUP_CHAT,
content: msg.body.content,
msgTime: now
}
await messageData.preloadResource(sessionId, [showMsg])
messageData.addMsgRecords(sessionId, [showMsg])
messageData.updateMsgIdSort(sessionId)
if (!messageData.sessionList[sessionId].dnd) {
playMsgReceive()

View File

@@ -26,17 +26,17 @@ export const onReceiveGroupSystemMsg = (updateScroll, capacity) => {
})
})
// 更新聊天记录
await messageData.addMsgRecords(sessionId, [
{
sessionId: sessionId,
msgId: msg.body.msgId,
fromId: msg.body.fromId,
msgType: msg.header.msgType,
content: msg.body.content,
msgTime: now
}
])
const showMsg = {
sessionId: sessionId,
msgId: msg.body.msgId,
fromId: msg.body.fromId,
msgType: msg.header.msgType,
content: msg.body.content,
msgTime: now
}
await messageData.preloadResource(sessionId, [showMsg])
messageData.addMsgRecords(sessionId, [showMsg])
messageData.updateMsgIdSort(sessionId)
// 如果是当前正打开的会话
if (messageData.selectedSessionId === sessionId) {

View File

@@ -338,7 +338,7 @@ class WsConnect {
sendMsg(sessionId, remoteId, msgType, content, seq, before, after) {
const sequence = seq || uuidv4()
const data = this.dataConstructor[msgType](sessionId, remoteId, content, sequence)
before(sequence, data)
before(data)
this.msgIdRefillCallback[sequence] = after
this.sendAgent(data)
}

View File

@@ -117,34 +117,22 @@ export const useMessageStore = defineStore('anylink-message', () => {
}
/**
* 对话列表中加入新的消息数组(预加载资源
* @param {*} sessionId 会话id
* @param {*} msgRecords 新的消息数组
* 预加载消息中的媒体资源
* @param {*} sessionId
* @param {*} msgRecords
*/
const addMsgRecords = async (sessionId, msgRecords) => {
// 预加载消息中的图片和音频
const preloadResource = async (sessionId, msgRecords) => {
await useImageStore().preloadImage(sessionId, msgRecords)
await useAudioStore().preloadAudio(sessionId, msgRecords)
await useVideoStore().preloadVideo(sessionId, msgRecords)
await useDocumentStore().preloadDocument(sessionId, msgRecords)
addMsgRecordsWithOutPreLoad(sessionId, msgRecords)
}
/**
* 对话列表中加入新的消息数组
* 更新msgId排序
* @param {*} sessionId 会话id
* @param {*} msgRecords 新的消息数组
*/
const addMsgRecordsWithOutPreLoad = (sessionId, msgRecords) => {
if (!msgRecords?.length) return
msgRecords.forEach((item) => {
if (!msgRecordsList.value[sessionId]) {
msgRecordsList.value[sessionId] = {}
}
msgRecordsList.value[sessionId][item.msgId] = item
})
const updateMsgIdSort = (sessionId) => {
// 更新排序
const array = Object.values(msgRecordsList.value[sessionId])
array.sort((a, b) => {
@@ -155,6 +143,21 @@ export const useMessageStore = defineStore('anylink-message', () => {
msgIdSortArray.value[sessionId] = array.map((item) => item.msgId)
}
/**
* 对话列表中加入新的消息数组(预加载资源)
* @param {*} sessionId 会话id
* @param {*} msgRecords 新的消息数组
*/
const addMsgRecords = (sessionId, msgRecords) => {
if (!msgRecords?.length) return
msgRecords.forEach((item) => {
if (!msgRecordsList.value[sessionId]) {
msgRecordsList.value[sessionId] = {}
}
msgRecordsList.value[sessionId][item.msgId] = item
})
}
/**
* 移除某个消息消息已发出后用正式消息替换temp消息场景
* @param {*} sessionId 会话id
@@ -163,15 +166,6 @@ export const useMessageStore = defineStore('anylink-message', () => {
const removeMsgRecord = (sessionId, msgId) => {
if (msgRecordsList.value[sessionId] && msgId in msgRecordsList.value[sessionId]) {
delete msgRecordsList.value[sessionId][msgId]
// 更新排序
const array = Object.values(msgRecordsList.value[sessionId])
array.sort((a, b) => {
const timeA = new Date(a.sendTime || a.msgTime).getTime()
const timeB = new Date(b.sendTime || b.msgTime).getTime()
return timeA - timeB
})
msgIdSortArray.value[sessionId] = array.map((item) => item.msgId)
}
}
@@ -235,7 +229,9 @@ export const useMessageStore = defineStore('anylink-message', () => {
addSession(res.data.data[item].session)
const msgList = res.data.data[item].msgList
if (msgList) {
await addMsgRecords(item, msgList)
await preloadResource(item, msgList)
addMsgRecords(item, msgList)
updateMsgIdSort(item)
}
})
}
@@ -280,8 +276,9 @@ export const useMessageStore = defineStore('anylink-message', () => {
msgRecordsList,
msgIdSortArray,
preloadResource,
updateMsgIdSort,
addMsgRecords,
addMsgRecordsWithOutPreLoad,
removeMsgRecord,
getMsg,

View File

@@ -416,7 +416,9 @@ const pullMsg = async (endMsgId = null) => {
const res = await msgChatPullMsgService(params)
const msgCount = res.data.data.count
if (msgCount > 0) {
await messageData.addMsgRecords(sessionId, res.data.data.msgList)
await messageData.preloadResource(sessionId, res.data.data.msgList)
messageData.addMsgRecords(sessionId, res.data.data.msgList)
messageData.updateMsgIdSort(sessionId)
}
if (msgCount < pageSize) {
@@ -491,20 +493,8 @@ const handleSendMessage = (msg) => {
if (inputToolBarRef.value) inputToolBarRef.value.closeWindow()
if (typeof msg === 'string') {
msg = {
sessionId: selectedSessionId.value,
fromId: myAccount.value,
msgType: selectedSession.value.sessionType,
content: msg,
status: msgSendStatus.PENDING,
msgTime: new Date(),
sendTime: new Date()
}
}
const resendInterval = 2000 //2秒
const before = async (seq, data) => {
const before = (data) => {
// 当2s内status如果还是pending中则重发3次。如果最后还是pending则把status置为failed
setTimeout(() => {
if (msg.status === msgSendStatus.PENDING) {
@@ -515,11 +505,12 @@ const handleSendMessage = (msg) => {
setTimeout(() => {
if (msg.status === msgSendStatus.PENDING) {
wsConnect.sendAgent(data)
setTimeout(async () => {
setTimeout(() => {
if (msg.status === msgSendStatus.PENDING) {
messageData.removeMsgRecord(msg.sessionId, msg.msgId)
msg.status = msgSendStatus.FAILED
await messageData.addMsgRecords(msg.sessionId, [msg])
messageData.addMsgRecords(msg.sessionId, [msg])
messageData.updateMsgIdSort(msg.sessionId)
ElMessage.error('消息发送失败')
}
}, resendInterval)
@@ -529,27 +520,21 @@ const handleSendMessage = (msg) => {
}, resendInterval)
}
}, resendInterval)
messageData.updateSession({
sessionId: msg.sessionId,
unreadCount: 0, // 最后一条消息是自己发的因此未读是0
draft: '' //草稿意味着要清空
})
msg.seq = seq
msg.msgId = seq //服务器没有回复DELIVERED消息之前都用seq暂代msgId
await messageData.addMsgRecords(msg.sessionId, [msg])
}
const after = async (msgId) => {
const after = (msgId) => {
messageData.updateSession({
sessionId: msg.sessionId,
readMsgId: msgId, // 最后一条消息是自己发的因此已读更新到刚发的这条消息的msgId
readTime: new Date()
})
messageData.removeMsgRecord(msg.sessionId, msg.msgId) //移除seq为key的msg
msg.msgId = msgId
msg.status = msgSendStatus.OK
await messageData.addMsgRecords(msg.sessionId, [msg]) //添加服务端返回msgId为key的msg
messageData.addMsgRecords(msg.sessionId, [msg]) //添加服务端返回msgId为key的msg
messageData.updateMsgIdSort(msg.sessionId)
if (!messageData.sessionList[msg.sessionId].dnd) {
playMsgSend()
}
@@ -565,7 +550,6 @@ const handleSendMessage = (msg) => {
after
)
capacity.value++
msgListReachBottom()
locateSession(msg.sessionId)
}
@@ -1008,7 +992,16 @@ const handleLocalMsg = ({ content, contentType, objectId, fn }) => {
msgTime: new Date(),
sendTime: new Date()
}
messageData.addMsgRecordsWithOutPreLoad(msg.sessionId, [msg])
messageData.addMsgRecords(msg.sessionId, [msg])
messageData.updateMsgIdSort(msg.sessionId)
capacity.value++
messageData.updateSession({
sessionId: selectedSessionId.value,
unreadCount: 0, // 最后一条消息是自己发的因此未读是0
draft: '' //草稿意味着要清空
})
fn(msg)
}

View File

@@ -217,44 +217,42 @@ const handleEnter = async () => {
return
}
if (contentObj.needUploadCount === 0) {
emit('sendMessage', content)
// 发送的时候设置本地缓存(非服务端数据),用于立即渲染
let msg = {}
emit('saveLocalMsg', {
contentType: msgContentType.MIX,
content: content,
fn: (result) => {
msg = result
}
})
if (contentObj.needUploadCount > 0) {
msg.uploadStatus = msgFileUploadStatus.UPLOADING
msg.uploadProgress = 0
} else {
// 发送的时候设置本地缓存(非服务端数据),用于立即渲染
let msg = {}
emit('saveLocalMsg', {
contentType: msgContentType.MIX,
content: content,
fn: (result) => {
msg = result
}
})
// 有图片需要上传
if (contentObj.needUploadCount > 0) {
msg.uploadStatus = msgFileUploadStatus.UPLOADING
msg.uploadProgress = 0
}
// callback每成功上传一个图片更新一下进度
callbacks.someOneUploadedSuccessFn = () => {
msg.uploadProgress = Math.floor(
(contentObj.uploadSuccessCount / contentObj.needUploadCount) * 100
)
}
// callback如果有失败的上传则状态修改为上传失败
callbacks.someUploadedFailFn = () => {
msg.uploadStatus = msgFileUploadStatus.UPLOAD_FAILED
}
// callback所有图片均上传则发送消息
callbacks.allUploadedSuccessFn = () => {
msg.uploadStatus = msgFileUploadStatus.UPLOAD_SUCCESS
msg.content = contentObj.contentFromServer.join('').trim()
emit('sendMessage', msg)
}
emit('sendMessage', msg)
}
// callback每成功上传一个图片更新一下进度
callbacks.someOneUploadedSuccessFn = () => {
msg.uploadProgress = Math.floor(
(contentObj.uploadSuccessCount / contentObj.needUploadCount) * 100
)
}
// callback如果有失败的上传则状态修改为上传失败
callbacks.someUploadedFailFn = () => {
msg.uploadStatus = msgFileUploadStatus.UPLOAD_FAILED
}
// callback所有图片均上传则发送消息
callbacks.allUploadedSuccessFn = () => {
msg.uploadStatus = msgFileUploadStatus.UPLOAD_SUCCESS
msg.content = contentObj.contentFromServer.join('').trim()
emit('sendMessage', msg)
}
getQuill().setText('') // 编辑窗口置空
}