海信医疗-远程超声管理平台-信创国产化
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
9.4 KiB

1 month ago
<template>
<div class="message-main">
<MessageList
ref="messageList"
@select-contact="handleSelectContact"
/>
<div class="message-right">
<MessageDisplay
ref="messageDisplay"
@clear-unread="handleClearUnread"
@send-files="handleSendFiles"
@group-setting="handleGroupSetting"
/>
<MessageEditor
ref="messageEditor"
@send-message="handleSendMessage"
@update-message-status="handleUpdateMessageStatus"
/>
</div>
<!-- 群设置弹窗 -->
<GroupSetting
:visible.sync="groupSettingVisible"
:chat="currentChat"
@quit-group="handleQuitGroup"
@dismiss-group="handleDismissGroup"
/>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import MessageList from './components/MessageList.vue'
import MessageDisplay from './components/MessageDisplay.vue'
import GroupSetting from './components/GroupSetting.vue'
import MessageEditor from './components/MessageEditor.vue'
// import { getMultiChatInfo } from '@/api/multichat'
import { MessageType, ContactsScene, MqttTopics } from '@/utils/constants'
export default {
name: 'MessageMain',
components: {
MessageList,
MessageDisplay,
GroupSetting,
MessageEditor
},
data() {
return {
groupSettingVisible: false
}
},
computed: {
...mapGetters(['mqttMessages', 'currentChat', 'userInfo', 'mqttConnected'])
},
watch: {
mqttMessages: {
deep: true,
handler(newMessages, oldMessages) {
const oldLen = oldMessages ? oldMessages.length : 0
const newLen = newMessages ? newMessages.length : 0
if (newLen > oldLen) {
for (let i = oldLen; i < newLen; i++) {
this.handleMqttMessage(newMessages[i])
}
}
}
}
},
mounted() {
this.initMqttSubscriptions()
},
beforeDestroy() {
// 清理
},
methods: {
...mapActions('mqtt', ['subscribe', 'unsubscribe']),
async initMqttSubscriptions() {
// 订阅个人消息主题
if (this.userInfo?.id) {
await this.subscribe(MqttTopics.PRIVATE_CHAT + this.userInfo.id)
}
},
handleMqttMessage(msg) {
const type = msg.type || msg.message_type
switch (type) {
case MessageType.READ:
this.handleReadMessage(msg)
break
case MessageType.TEXT:
case MessageType.IMAGE:
case MessageType.VIDEO:
case MessageType.AUDIO:
case MessageType.FILE:
case MessageType.REPORT_SHARE:
case MessageType.KNOWLEDGE_SHARE:
case MessageType.CONSULTATION_MESSAGE_INVITE:
this.handleBaseMessage(msg)
break
case MessageType.MULTI_CHAT_INVITE:
this.handleMultiChatInvite(msg)
break
case MessageType.MULTI_CHAT_JOIN:
this.handleMultiChatJoin(msg)
break
case MessageType.MULTI_CHAT_EDIT:
this.handleMultiChatEdit(msg)
break
case MessageType.MULTI_CHAT_QUIT:
this.handleMultiChatQuit(msg)
break
case MessageType.MULTI_CHAT_DISMISS:
this.handleMultiChatDismiss(msg)
break
case MessageType.NOTIFY_CONTENT:
this.handleNotifyContent(msg)
break
default:
console.log('未处理的MQTT消息类型:', type, msg)
}
},
handleReadMessage(msg) {
// 更新消息已读状态
if (this.$refs.messageDisplay) {
this.$refs.messageDisplay.updateMessageStatus(msg.message_id, { read: true, read_status: 1 })
}
},
handleBaseMessage(msg) {
const isSelf = msg.source_id === this.userInfo?.id
const scene = msg.scene || (msg.multi_chat_id ? ContactsScene.GROUP : ContactsScene.PRIVATE)
const targetId = msg.target_id || msg.source_id
const contactId = isSelf ? targetId : msg.source_id
// 如果当前正在查看该会话,展示消息
if (this.currentChat &&
this.currentChat.id === (scene === ContactsScene.GROUP ? msg.multi_chat_id : contactId) &&
this.currentChat.scene === scene) {
if (this.$refs.messageDisplay) {
this.$refs.messageDisplay.addChatMessage(msg)
}
// 标记已读
if (!isSelf) {
this.handleClearUnread(this.currentChat.id, this.currentChat.scene)
}
}
// 更新联系人列表最后消息
if (this.$refs.messageList) {
this.$refs.messageList.updateContactLastMessage(
scene === ContactsScene.GROUP ? msg.multi_chat_id : contactId,
scene,
msg,
msg.timestamp || new Date().toISOString()
)
}
},
async handleMultiChatInvite(msg) {
const payload = msg.payload || {}
const multiChatId = payload.multi_chat_id || msg.multi_chat_id
if (!multiChatId) return
// 订阅群主题
await this.subscribe(MqttTopics.MULTI_CHAT + multiChatId)
// 获取群详情
try {
const res = await getMultiChatInfo({ multi_chat_id: multiChatId })
const group = res.data
if (group && this.$refs.messageList) {
this.$refs.messageList.loadContacts()
}
} catch (e) {
console.error('获取群详情失败', e)
}
},
async handleMultiChatJoin(msg) {
const multiChatId = msg.multi_chat_id || msg.payload?.multi_chat_id
if (!multiChatId) return
try {
await getMultiChatInfo({ multi_chat_id: multiChatId })
if (this.$refs.messageList) {
this.$refs.messageList.loadContacts()
}
} catch (e) {
console.error('获取群详情失败', e)
}
},
async handleMultiChatEdit(msg) {
const multiChatId = msg.multi_chat_id || msg.payload?.multi_chat_id
if (!multiChatId) return
try {
await getMultiChatInfo({ multi_chat_id: multiChatId })
if (this.$refs.messageList) {
this.$refs.messageList.loadContacts()
}
// 如果当前正在该群聊,刷新标题
if (this.currentChat && this.currentChat.id === multiChatId && this.currentChat.scene === ContactsScene.GROUP) {
this.$refs.messageList.loadContacts()
}
} catch (e) {
console.error('获取群详情失败', e)
}
},
handleMultiChatQuit(msg) {
const payload = msg.payload || {}
const multiChatId = payload.multi_chat_id || msg.multi_chat_id
const quitUserId = payload.user_id || msg.source_id
if (!multiChatId) return
if (quitUserId === this.userInfo?.id) {
// 自己退出,取消订阅并删除列表项
this.unsubscribe(MqttTopics.MULTI_CHAT + multiChatId)
if (this.$refs.messageList) {
this.$refs.messageList.removeContact(multiChatId, ContactsScene.GROUP)
}
} else {
// 他人退出,更新列表
if (this.$refs.messageList) {
this.$refs.messageList.loadContacts()
}
}
},
handleMultiChatDismiss(msg) {
const multiChatId = msg.multi_chat_id || msg.payload?.multi_chat_id
if (!multiChatId) return
this.unsubscribe(MqttTopics.MULTI_CHAT + multiChatId)
if (this.$refs.messageList) {
this.$refs.messageList.removeContact(multiChatId, ContactsScene.GROUP)
}
},
handleNotifyContent(msg) {
// 系统通知处理
this.$notify({
title: '系统通知',
message: msg.payload?.content || msg.content || '新通知',
type: 'info',
duration: 5000
})
},
handleSelectContact(contact) {
// 如果是群聊,订阅MQTT主题
if (contact.scene === ContactsScene.GROUP) {
this.subscribe(MqttTopics.MULTI_CHAT + contact.id)
}
},
handleClearUnread(contactId, scene) {
if (this.$refs.messageList) {
this.$refs.messageList.clearUnread(contactId, scene)
}
},
handleSendMessage(message) {
if (this.$refs.messageDisplay) {
this.$refs.messageDisplay.addChatMessage(message)
}
// 更新联系人列表
if (this.$refs.messageList) {
this.$refs.messageList.updateContactLastMessage(
message.target_id,
message.scene,
message,
new Date().toISOString()
)
}
},
handleUpdateMessageStatus(messageId, updates) {
if (this.$refs.messageDisplay) {
this.$refs.messageDisplay.updateMessageStatus(messageId, updates)
}
},
handleSendFiles(files) {
if (this.$refs.messageEditor) {
files.forEach(file => {
const type = file.type.startsWith('image/') ? 'image'
: file.type.startsWith('video/') ? 'video'
: file.type.startsWith('audio/') ? 'audio'
: 'file'
this.$refs.messageEditor.sendFileMessage(file, type)
})
}
},
handleGroupSetting(chat) {
this.groupSettingVisible = true
},
handleQuitGroup(chat) {
// 退出群组逻辑
if (this.$refs.messageList) {
this.$refs.messageList.removeContact(chat.id, chat.scene)
}
},
handleDismissGroup(chat) {
// 解散群组逻辑
if (this.$refs.messageList) {
this.$refs.messageList.removeContact(chat.id, chat.scene)
}
}
}
}
</script>
<style lang="scss" scoped>
.message-main {
display: flex;
height: 100%;
background: #fff;
.message-right {
flex: 1;
display: flex;
flex-direction: column;
min-width: 0;
}
}
</style>