mirror of
https://gitee.com/lijingbo-2021/open-anylink-web.git
synced 2025-12-30 02:52:26 +00:00
合并消息转发重构
This commit is contained in:
@@ -32,6 +32,10 @@ export const msgChatQuerySessionService = (obj) => {
|
||||
return request.get('/chat/querySession', { params: obj })
|
||||
}
|
||||
|
||||
export const msgChatQueryMessagesService = (obj) => {
|
||||
return request.get('/chat/queryMessages', { params: obj })
|
||||
}
|
||||
|
||||
export const msgChatCloseSessionService = (obj) => {
|
||||
return request.post('/chat/closeSession', obj)
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export const msgContentType = {
|
||||
EMOJI: 5, // 表情
|
||||
VIDEO: 6, // 视频
|
||||
DOCUMENT: 7, // 文档
|
||||
FORWARD_TOGETHER: 8 // 合并转发消息
|
||||
FORWARD_TOGETHER: 10 // 合并转发消息
|
||||
}
|
||||
|
||||
// 消息发送状态
|
||||
|
||||
@@ -1158,22 +1158,22 @@ const onSelectOprMenu = (label) => {
|
||||
|
||||
const inputMultiSelectRef = ref(null)
|
||||
const isMultiSelect = ref(false)
|
||||
const multiSelectedMsgIds = ref(new Set())
|
||||
const multiSelectedMsgKeys = ref(new Set())
|
||||
const handleMsgItemSelect = (msgKey, selected) => {
|
||||
if (!isMultiSelect.value) {
|
||||
isMultiSelect.value = true
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
multiSelectedMsgIds.value.add(msgKey)
|
||||
multiSelectedMsgKeys.value.add(msgKey)
|
||||
} else {
|
||||
multiSelectedMsgIds.value.delete(msgKey)
|
||||
multiSelectedMsgKeys.value.delete(msgKey)
|
||||
}
|
||||
}
|
||||
|
||||
const handleCancleMultiSelect = () => {
|
||||
isMultiSelect.value = false
|
||||
multiSelectedMsgIds.value.clear()
|
||||
multiSelectedMsgKeys.value.clear()
|
||||
}
|
||||
|
||||
const handleForwardTogether = () => {
|
||||
@@ -1187,14 +1187,17 @@ const handleForwardOneByOne = () => {
|
||||
}
|
||||
|
||||
const handleBatchDeleteMsg = () => {
|
||||
const deleteMsgIds = [...multiSelectedMsgKeys.value].map((item) => {
|
||||
return messageData.getMsg(selectedSessionId.value, item).msgId
|
||||
})
|
||||
msgChatDeleteMsgService({
|
||||
sessionId: selectedSessionId.value,
|
||||
deleteMsgIds: [...multiSelectedMsgIds.value]
|
||||
deleteMsgIds: [...deleteMsgIds]
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data.code === 0) {
|
||||
multiSelectedMsgIds.value.forEach((item) => {
|
||||
messageData.removeMsgRecord(selectedSessionId.value, item)
|
||||
multiSelectedMsgKeys.value.forEach((msgKey) => {
|
||||
messageData.removeMsgRecord(selectedSessionId.value, msgKey)
|
||||
})
|
||||
handleCancleMultiSelect()
|
||||
ElMessage.success('消息已删除')
|
||||
@@ -1326,10 +1329,10 @@ const handleGlobalMouseUp = (e) => {
|
||||
isMultiSelect.value = true
|
||||
}
|
||||
|
||||
const msgId = el.dataset.msgId
|
||||
const msgKey = el.dataset.msgKey
|
||||
const disabled = el.dataset.disabled
|
||||
if (disabled !== 'true' && !multiSelectedMsgIds.value.has(msgId)) {
|
||||
multiSelectedMsgIds.value.add(msgId)
|
||||
if (disabled !== 'true' && !multiSelectedMsgKeys.value.has(msgKey)) {
|
||||
multiSelectedMsgKeys.value.add(msgKey)
|
||||
}
|
||||
|
||||
const cancelClick = (e) => {
|
||||
@@ -1346,40 +1349,6 @@ const handleGlobalMouseUp = (e) => {
|
||||
|
||||
const isShowForwardMsgDialog = ref(false)
|
||||
const showForwardMsgDialogTitle = ref('')
|
||||
// 待转发的消息
|
||||
const forwardMsgs = computed(() => {
|
||||
let msgs = []
|
||||
multiSelectedMsgIds.value.forEach((item) => {
|
||||
const msg = messageData.getMsg(selectedSessionId.value, item)
|
||||
let nickName = ''
|
||||
if (msg.msgType === MsgType.CHAT) {
|
||||
if (myAccount.value === msg.fromId) {
|
||||
nickName = userData.user.nickName
|
||||
} else {
|
||||
nickName = messageData.sessionList[msg.sessionId].objectInfo.nickName
|
||||
}
|
||||
} else if (msg.msgType === MsgType.GROUP_CHAT) {
|
||||
const groupId = messageData.sessionList[msg.sessionId].remoteId
|
||||
const members = groupData.groupMembersList[groupId]
|
||||
nickName = members[msg.fromId].nickName
|
||||
}
|
||||
msgs.push({
|
||||
...msg,
|
||||
nickName
|
||||
})
|
||||
})
|
||||
|
||||
if (showForwardMsgDialogTitle.value === '合并转发') {
|
||||
return [
|
||||
{
|
||||
type: msgContentType.FORWARD_TOGETHER,
|
||||
value: msgs
|
||||
}
|
||||
]
|
||||
} else {
|
||||
return msgs
|
||||
}
|
||||
})
|
||||
|
||||
const sessionListSortedKey = computed(() => {
|
||||
return sessionListSorted.value
|
||||
@@ -1389,11 +1358,11 @@ const sessionListSortedKey = computed(() => {
|
||||
.map((item) => item.sessionId)
|
||||
})
|
||||
|
||||
const showForwardMsgDialog = (msgId) => {
|
||||
multiSelectedMsgIds.value.clear()
|
||||
multiSelectedMsgIds.value.add(msgId)
|
||||
const showForwardMsgDialog = (msgKey) => {
|
||||
multiSelectedMsgKeys.value.clear()
|
||||
multiSelectedMsgKeys.value.add(msgKey)
|
||||
isShowForwardMsgDialog.value = true
|
||||
showForwardMsgDialogTitle.value = '转发消息'
|
||||
showForwardMsgDialogTitle.value = '逐条转发'
|
||||
}
|
||||
|
||||
const handleConfirmForwardMsg = async (sessions) => {
|
||||
@@ -1412,14 +1381,43 @@ const handleConfirmForwardMsg = async (sessions) => {
|
||||
messageData.addSession(res.data.data.session)
|
||||
}
|
||||
|
||||
for (const forwardMsg of forwardMsgs.value) {
|
||||
const content =
|
||||
showForwardMsgDialogTitle.value !== '合并转发'
|
||||
? forwardMsg.content
|
||||
: JSON.stringify(forwardMsg)
|
||||
if (showForwardMsgDialogTitle.value === '逐条转发') {
|
||||
for (const msgKey of multiSelectedMsgKeys.value) {
|
||||
const msg = messageData.getMsg(selectedSessionId.value, msgKey)
|
||||
await handleSendForwardMsg({
|
||||
session: item,
|
||||
content: msg.content
|
||||
})
|
||||
}
|
||||
} else if (showForwardMsgDialogTitle.value === '合并转发') {
|
||||
const msgs = [...multiSelectedMsgKeys.value].map((item) => {
|
||||
const msg = messageData.getMsg(selectedSessionId.value, item)
|
||||
let nickName = ''
|
||||
if (selectedSession.value.sessionType === MsgType.CHAT) {
|
||||
if (myAccount.value === msg.fromId) {
|
||||
nickName = userData.user.nickName
|
||||
} else {
|
||||
nickName = selectedSession.value.objectInfo.nickName
|
||||
}
|
||||
} else if (selectedSession.value.sessionType === MsgType.GROUP_CHAT) {
|
||||
const groupId = selectedSession.value.remoteId
|
||||
const members = groupData.groupMembersList[groupId]
|
||||
nickName = members[msg.fromId].nickName
|
||||
}
|
||||
return {
|
||||
nickName,
|
||||
msgId: msg.msgId
|
||||
}
|
||||
})
|
||||
await handleSendForwardMsg({
|
||||
session: item,
|
||||
content: content
|
||||
content: JSON.stringify({
|
||||
type: msgContentType.FORWARD_TOGETHER,
|
||||
value: {
|
||||
sessionId: selectedSessionId.value,
|
||||
data: [...msgs]
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1675,7 +1673,7 @@ const onShowRecorder = () => {
|
||||
:isLoadMoreLoading="selectedSessionCache[selectedSessionId]?.isLoadMoreLoading"
|
||||
:inputEditorRef="inputEditorRef"
|
||||
:isMultiSelect="isMultiSelect"
|
||||
:isSelected="multiSelectedMsgIds.has(item)"
|
||||
:isSelected="multiSelectedMsgKeys.has(item)"
|
||||
@loadMore="onLoadMore"
|
||||
@showUserCard="onShowUserCard"
|
||||
@showGroupCard="onShowGroupCard"
|
||||
@@ -1728,7 +1726,7 @@ const onShowRecorder = () => {
|
||||
<el-container v-if="isMultiSelect">
|
||||
<InputMultiSelect
|
||||
ref="inputMultiSelectRef"
|
||||
:selectedCount="multiSelectedMsgIds.size"
|
||||
:selectedCount="multiSelectedMsgKeys.size"
|
||||
@exit="handleCancleMultiSelect"
|
||||
@forwardTogether="handleForwardTogether"
|
||||
@forwardOneByOne="handleForwardOneByOne"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="jsx">
|
||||
import { onMounted, computed, watch, createApp, h } from 'vue'
|
||||
import { ref, onMounted, computed, watch, createApp, h } from 'vue'
|
||||
import { ElDialog, ElLoading } from 'element-plus'
|
||||
import {
|
||||
useUserStore,
|
||||
@@ -24,6 +24,7 @@ import MsgBoxDocument from '@/views/message/components/MsgBoxDocument.vue'
|
||||
import DialogForMsgList from '@/views/message/components/DialogForMsgList.vue'
|
||||
import { emojis } from '@/js/utils/emojis'
|
||||
import { MsgType } from '@/proto/msg'
|
||||
import { msgChatQueryMessagesService } from '@/api/message'
|
||||
|
||||
const props = defineProps(['isShow', 'title', 'sessionId', 'msgs', 'tier'])
|
||||
const emit = defineEmits(['update:isShow', 'showUserCard', 'close'])
|
||||
@@ -36,8 +37,16 @@ const audioData = useAudioStore()
|
||||
const videoData = useVideoStore()
|
||||
const documentData = useDocumentStore()
|
||||
|
||||
const msgsFromServer = ref({})
|
||||
|
||||
onMounted(async () => {
|
||||
await messageData.preloadResource(props.msgs)
|
||||
const loadingInstance = ElLoading.service(el_loading_options)
|
||||
try {
|
||||
await messageData.preloadResource(props.msgs)
|
||||
await loadForwardTogetherMsgs()
|
||||
} finally {
|
||||
loadingInstance.close()
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -50,6 +59,65 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const loadForwardTogetherMsgs = async () => {
|
||||
for (const msg of props.msgs) {
|
||||
const content = msg.content
|
||||
const contentJson = jsonParseSafe(content)
|
||||
if (!contentJson) {
|
||||
return
|
||||
}
|
||||
|
||||
const type = contentJson['type']
|
||||
const value = contentJson['value']
|
||||
if (!type || !value) {
|
||||
return
|
||||
} else {
|
||||
if (type === msgContentType.FORWARD_TOGETHER) {
|
||||
let res
|
||||
try {
|
||||
const msgIds = value.data
|
||||
.map((item) => {
|
||||
return item.msgId
|
||||
})
|
||||
.join(',')
|
||||
res = await msgChatQueryMessagesService({
|
||||
sessionId: value.sessionId,
|
||||
msgIds
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return
|
||||
}
|
||||
|
||||
const msgs = res.data.data
|
||||
if (!res.data.data || res.data.data.length == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
// value.data(取里面的nickName) 和 msgs合一
|
||||
const newMsgs = {}
|
||||
msgs.forEach((item) => {
|
||||
newMsgs[item.msgId] = item
|
||||
})
|
||||
value.data.forEach((item) => {
|
||||
if (item.msgId in newMsgs) {
|
||||
newMsgs[item.msgId] = {
|
||||
...newMsgs[item.msgId],
|
||||
...item
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
msgsFromServer.value[msg.msgId] = Object.values(newMsgs).sort((a, b) => {
|
||||
const timeA = new Date(a.sendTime || a.msgTime).getTime()
|
||||
const timeB = new Date(b.sendTime || b.msgTime).getTime()
|
||||
return timeA - timeB
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const myAccount = computed(() => {
|
||||
return userData.user.account
|
||||
})
|
||||
@@ -91,7 +159,7 @@ const renderContent = ({ msg }) => {
|
||||
case msgContentType.DOCUMENT:
|
||||
return renderDocument(value)
|
||||
case msgContentType.FORWARD_TOGETHER:
|
||||
return renderForwardTogether(value)
|
||||
return renderForwardTogether(msgId)
|
||||
default:
|
||||
return <span>{content}</span>
|
||||
}
|
||||
@@ -232,13 +300,13 @@ const renderDocument = (content) => {
|
||||
}
|
||||
}
|
||||
|
||||
const renderForwardTogether = (msgs) => {
|
||||
const renderForwardTogether = (msgId) => {
|
||||
const title = '聊天记录'
|
||||
const msgsSorted = msgs.sort((a, b) => {
|
||||
const timeA = new Date(a.sendTime || a.msgTime).getTime()
|
||||
const timeB = new Date(b.sendTime || b.msgTime).getTime()
|
||||
return timeA - timeB
|
||||
})
|
||||
const msgsSorted = msgsFromServer.value[msgId]
|
||||
|
||||
if (!msgsSorted) {
|
||||
return <div class={'forward-together'}></div>
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -23,7 +23,11 @@ import MsgBoxVideo from '@/views/message/components/MsgBoxVideo.vue'
|
||||
import MsgBoxDocument from '@/views/message/components/MsgBoxDocument.vue'
|
||||
import MenuMsgItem from '@/views/message/components/MenuMsgItem.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { msgChatDeleteMsgService, msgChatRevokeMsgService } from '@/api/message'
|
||||
import {
|
||||
msgChatDeleteMsgService,
|
||||
msgChatQueryMessagesService,
|
||||
msgChatRevokeMsgService
|
||||
} from '@/api/message'
|
||||
import DialogForMsgList from '@/views/message/components/DialogForMsgList.vue'
|
||||
|
||||
const props = defineProps([
|
||||
@@ -61,18 +65,18 @@ const audioData = useAudioStore()
|
||||
const videoData = useVideoStore()
|
||||
const documentData = useDocumentStore()
|
||||
|
||||
onMounted(() => {
|
||||
rendering()
|
||||
onMounted(async () => {
|
||||
await rendering()
|
||||
})
|
||||
|
||||
let app = null
|
||||
const rendering = () => {
|
||||
const rendering = async () => {
|
||||
const msgContent = document.querySelector(`#div-content-${msg.value.msgId}`)
|
||||
if (msgContent) {
|
||||
if (app) {
|
||||
app.unmount()
|
||||
}
|
||||
const vnode = renderComponent(msg.value.content)
|
||||
const vnode = await renderComponent(msg.value.content)
|
||||
app = createApp({
|
||||
render: () => vnode
|
||||
})
|
||||
@@ -84,7 +88,7 @@ const rendering = () => {
|
||||
* 动态渲染消息内容
|
||||
* @param content 消息内容
|
||||
*/
|
||||
const renderComponent = (content) => {
|
||||
const renderComponent = async (content) => {
|
||||
const contentJson = jsonParseSafe(content)
|
||||
if (!contentJson) {
|
||||
return renderMix(content)
|
||||
@@ -114,7 +118,7 @@ const renderComponent = (content) => {
|
||||
case msgContentType.DOCUMENT:
|
||||
return renderDocument(value)
|
||||
case msgContentType.FORWARD_TOGETHER:
|
||||
return renderForwardTogether(value)
|
||||
return await renderForwardTogether(value)
|
||||
default:
|
||||
return h('span', content)
|
||||
}
|
||||
@@ -263,11 +267,46 @@ const showMsgContentInForwardTogether = (content) => {
|
||||
}
|
||||
}
|
||||
|
||||
const renderForwardTogether = (msgs) => {
|
||||
const renderForwardTogether = async (content) => {
|
||||
let res
|
||||
try {
|
||||
const msgIds = content.data
|
||||
.map((item) => {
|
||||
return item.msgId
|
||||
})
|
||||
.join(',')
|
||||
res = await msgChatQueryMessagesService({
|
||||
sessionId: content.sessionId,
|
||||
msgIds
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return h('span', content)
|
||||
}
|
||||
|
||||
const msgs = res.data.data
|
||||
if (!res.data.data || res.data.data.length == 0) {
|
||||
return h('span', content)
|
||||
}
|
||||
|
||||
// 把content.data(取里面的nickName) 和 msgs合一
|
||||
const newMsgs = {}
|
||||
msgs.forEach((item) => {
|
||||
newMsgs[item.msgId] = item
|
||||
})
|
||||
content.data.forEach((item) => {
|
||||
if (item.msgId in newMsgs) {
|
||||
newMsgs[item.msgId] = {
|
||||
...newMsgs[item.msgId],
|
||||
...item
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const title =
|
||||
(msgs[0].msgType === MsgType.GROUP_CHAT ? '群聊' : nickNameFromMsg.value) + '的聊天记录'
|
||||
|
||||
const msgsSorted = msgs.sort((a, b) => {
|
||||
const msgsSorted = Object.values(newMsgs).sort((a, b) => {
|
||||
const timeA = new Date(a.sendTime || a.msgTime).getTime()
|
||||
const timeB = new Date(b.sendTime || b.msgTime).getTime()
|
||||
return timeA - timeB
|
||||
@@ -1046,7 +1085,7 @@ const handleItemClick = () => {
|
||||
</div>
|
||||
<div
|
||||
class="message-item"
|
||||
:data-msg-id="props.msgKey"
|
||||
:data-msg-key="props.msgKey"
|
||||
:data-disabled="multiSelectOptionDisabled"
|
||||
:class="{ unreadMsg: isUnreadMsg }"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user