diff --git a/src/js/event/receiveChatMsg.js b/src/js/event/receiveChatMsg.js index f0f0d2c..61a6c7f 100644 --- a/src/js/event/receiveChatMsg.js +++ b/src/js/event/receiveChatMsg.js @@ -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() diff --git a/src/js/event/receiveGroupChatMsg.js b/src/js/event/receiveGroupChatMsg.js index 01747ba..13fbf73 100644 --- a/src/js/event/receiveGroupChatMsg.js +++ b/src/js/event/receiveGroupChatMsg.js @@ -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() diff --git a/src/js/event/receiveGroupSystemMsg.js b/src/js/event/receiveGroupSystemMsg.js index 5afb004..d76857c 100644 --- a/src/js/event/receiveGroupSystemMsg.js +++ b/src/js/event/receiveGroupSystemMsg.js @@ -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) { diff --git a/src/js/websocket/wsConnect.js b/src/js/websocket/wsConnect.js index 7e73843..3ce5097 100644 --- a/src/js/websocket/wsConnect.js +++ b/src/js/websocket/wsConnect.js @@ -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) } diff --git a/src/stores/message.js b/src/stores/message.js index 6d21c28..81f8fa4 100644 --- a/src/stores/message.js +++ b/src/stores/message.js @@ -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, diff --git a/src/views/message/MessageLayout.vue b/src/views/message/MessageLayout.vue index 1ea20e3..663b0bf 100644 --- a/src/views/message/MessageLayout.vue +++ b/src/views/message/MessageLayout.vue @@ -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) } diff --git a/src/views/message/components/InputEditor.vue b/src/views/message/components/InputEditor.vue index d7ed6b9..0f74c69 100644 --- a/src/views/message/components/InputEditor.vue +++ b/src/views/message/components/InputEditor.vue @@ -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('') // 编辑窗口置空 }