import Base from './base' import { nextTick } from 'vue' import ws from '@/connect' import { parseTime } from '@/utils/datetime' import * as message from '@/constant/message' import { formatTalkItem, palyMusic, formatTalkRecord } from '@/utils/talk' // import { isElectronMode } from '@/utils/common' import { ServeClearTalkUnreadNum, ServeCreateTalkList, } from '@/api/chat/index.js' import { useTalkStore, useDialogueStore, useDialogueListStore, useGroupStore, } from '@/store' /** * 好友状态事件 */ class Talk extends Base { /** * @var resource 资源 */ resource /** * 发送者ID */ sender_id = 0 /** * 接收者ID */ receiver_id = 0 /** * 聊天类型[1:私聊;2:群聊;] */ talk_type = 0 /** * 文件上传唯一随机值 */ fileNum = '' /** * 初始化构造方法 * * @param {Object} resource Socket消息 */ constructor(resource) { super() this.sender_id = resource.sender_id this.receiver_id = resource.receiver_id this.talk_type = resource.talk_type // this.fileNum = resource.file_num if (resource.file_num) { resource.data.file_num = resource.file_num } this.resource = resource.data this.handle() } /** * 判断消息发送者是否来自于我 * @returns */ isCurrSender() { return this.sender_id == this.getAccountId() } /** * 获取对话索引 * * @return String */ getIndexName() { if (this.talk_type == 2) { return `${this.talk_type}_${this.receiver_id}` } let receiver_id = this.isCurrSender() ? this.receiver_id : this.sender_id return `${this.talk_type}_${receiver_id}` } /** * 获取聊天列表左侧的对话信息 */ getTalkText() { let text = '' if (this.resource.msg_type != message.ChatMsgTypeText) { text = message.ChatMsgTypeMapping[this.resource.msg_type] } else { text = this.resource.extra.content.replace(//g, '') } return text } // 播放提示音 play() { // 客户端有消息提示 // if (isElectronMode()) return // useSettingsStore().isPromptTone && palyMusic() } async handle() { // 不是自己发送的消息则需要播放提示音 if (!this.isCurrSender()) { this.play() } // 判断会话列表是否存在,不存在则创建 if (useTalkStore().findTalkIndex(this.getIndexName()) == -1) { if (this.resource.msg_type == 1102) { //被邀请进入群聊时,需要热更新会话列表 await useTalkStore().loadTalkList() } else if (this.resource.msg_type == 1106) { //群解散时,需要热更新会话列表 await useTalkStore().loadTalkList() } else if ( this.resource.msg_type == 1104 || this.resource.msg_type == 1115 ) { //群成员被移出时,需要热更新会话列表 await useTalkStore().loadTalkList() } else { return this.addTalkItem() } } // 判断当前是否正在和好友对话 if (this.isTalk(this.talk_type, this.receiver_id, this.sender_id)) { this.insertTalkRecord() } else { this.updateTalkItem() if ( !useTalkStore().items[useTalkStore().findTalkIndex(this.getIndexName())] ?.is_disturb && !( useTalkStore().findTalkIndex(this.getIndexName()) == -1 && (this.resource.msg_type == 1104 || this.resource.msg_type == 1115) ) ) { this.updateUnreadMsgNumAdd() } } } //更新未读数量+1 updateUnreadMsgNumAdd() { if (typeof plus !== 'undefined') { let OAWebView = plus.webview.all() OAWebView.forEach((webview) => { if (webview.id === 'webviewId1') { webview.evalJS(`updateUnreadMsgNumAdd()`) } }) } else { document.addEventListener('plusready', () => { let OAWebView = plus.webview.all() OAWebView.forEach((webview) => { if (webview.id === 'webviewId1') { webview.evalJS(`updateUnreadMsgNumAdd()`) } }) }) } } /** * 显示消息提示 * @returns */ showMessageNocice() { // if (useSettingsStore().isLeaveWeb) { // const notification = new Notification('LumenIM 在线聊天', { // dir: 'auto', // lang: 'zh-CN', // body: '您有新的消息请注意查收' // }) // notification.onclick = () => { // notification.close() // } // } else { // window['$notification'].create({ // title: '消息通知', // content: '您有新的消息请注意查收', // duration: 3000 // }) // } } /** * 加载对接节点 */ addTalkItem() { let receiver_id = this.sender_id let talk_type = this.talk_type if (talk_type == 1 && this.receiver_id != this.getAccountId()) { receiver_id = this.receiver_id } else if (talk_type == 2) { receiver_id = this.receiver_id } ServeCreateTalkList({ talk_type, receiver_id, }).then(async ({ code, data }) => { if (code == 200) { let item = formatTalkItem(data) if (!item?.is_disturb) { item.unread_num = 1 this.updateUnreadMsgNumAdd() } useTalkStore().addItem(item) await useTalkStore().loadTalkList() } }) } /** * 插入对话记录 */ insertTalkRecord() { let record = this.resource let newRecord = formatTalkRecord(this.getAccountId(), this.resource) const { addDialogueRecord, addChatRecord } = useDialogueListStore() // 群成员变化的消息,需要更新群成员列表 if ([1102, 1103, 1104, 1115].includes(record.msg_type)) { useDialogueStore().updateGroupMembers() } //群解散时,需要更新群成员权限 if ([1106].includes(record.msg_type)) { useDialogueStore().updateDismiss() } //群成员被移出时,需要更新群成员权限 if ([1104, 1115].includes(record.msg_type)) { console.error(this.resource.extra.members, 'this.resource.extra.members') if (this.resource?.extra?.members?.length > 0) { const isMeQuit = this.resource.extra.members.find( (item) => item.user_id === this.getAccountId(), ) if (isMeQuit) { useDialogueStore().updateQuit() } } } //群禁言变化时,需要更新群禁言状态——即更新群成员列表 if ([1107, 1108, 1109, 1110].includes(record.msg_type)) { useDialogueStore().updateGroupMembers() } //群公告变化时,需要更新群公告(新增和修改有热更新,删除没有) if ([13].includes(record.msg_type)) { useGroupStore().ServeGetGroupNotices() } //群管理员变化时,需要更新群管理员列表——即更新群成员列表,同时更新群信息 if ([1114].includes(record.msg_type)) { useDialogueStore().updateGroupMembers() useGroupStore().ServeGroupDetail() } if ([1116].includes(record.msg_type)) { // 更新会话信息 useDialogueStore().setDialogue({ name: record.extra.group_name, talk_type: record.talk_type, receiver_id: record.receiver_id, }) // 更新群聊信息 useGroupStore().updateGroupInfo({ group_name: record.extra.group_name, avatar: record.extra.group_avatar, }) // 更新会话列表中的会话信息 const dialogue = useDialogueListStore().getDialogueList( `${record.talk_type}_${record.receiver_id}`, ) if (dialogue) { dialogue.talk.username = record.extra.group_name } } addDialogueRecord([newRecord], 'add') addChatRecord(this.getIndexName(), newRecord) useDialogueStore().addDialogueRecord(newRecord) if (!this.isCurrSender()) { // 推送已读消息 // setTimeout(() => { // ws.emit('im.message.read', { // receiver_id: this.sender_id, // msg_ids: [this.resource.msg_id], // }) // }, 1000) } // 获取聊天面板元素节点 const el = document.getElementById('imChatPanel') if (!el) return // 判断的滚动条是否在底部 const isBottom = Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight if (isBottom || record.user_id == this.getAccountId()) { nextTick(() => { el.scrollTop = el.scrollHeight + 1000 }) } else { useDialogueStore().setUnreadBubble() } useTalkStore().updateItem({ index_name: this.getIndexName(), msg_text: this.getTalkText(), updated_at: parseTime(new Date()), }) if (this.talk_type == 1 && this.getAccountId() !== this.sender_id) { //不在此处维护未读消息数量 // ServeClearTalkUnreadNum({ // talk_type: 1, // receiver_id: this.sender_id, // }) } } /** * 更新对话列表记录 */ updateTalkItem() { useTalkStore().updateMessage({ index_name: this.getIndexName(), msg_text: this.getTalkText(), updated_at: parseTime(new Date()), }) //收到新消息时,同时判断是否有人@我 if ( this.resource.msg_type === 1 && this.resource?.extra?.mentions?.length > 0 ) { const findMention = this.resource?.extra?.mentions?.find( (mention) => mention === this.getAccountId(), ) //有人@我或者@所有人,则更新会话列表 if (findMention || this.resource?.extra?.mentions?.includes(0)) { useTalkStore().loadTalkList() } } if (this.resource.msg_type == 1116) { // 更新会话列表中的会话信息 const dialogue = useDialogueListStore().getDialogueList( `${this.resource.talk_type}_${this.resource.receiver_id}`, ) if (dialogue) { dialogue.talk.username = this.resource.extra.group_name } useTalkStore().loadTalkList() } } } export default Talk