2024-12-24 08:14:21 +00:00
|
|
|
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'
|
|
|
|
import { useTalkStore, useDialogueStore, useSettingsStore } from '@/store'
|
2025-05-28 03:29:13 +00:00
|
|
|
import { isScrollAtBottom, scrollToBottom } from '@/utils/dom'
|
2024-12-24 08:14:21 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 好友状态事件
|
|
|
|
*/
|
|
|
|
class Talk extends Base {
|
|
|
|
/**
|
|
|
|
* @var resource 资源
|
|
|
|
*/
|
|
|
|
resource
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 发送者ID
|
|
|
|
*/
|
|
|
|
sender_id = 0
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 接收者ID
|
|
|
|
*/
|
|
|
|
receiver_id = 0
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 聊天类型[1:私聊;2:群聊;]
|
|
|
|
*/
|
|
|
|
talk_type = 0
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 初始化构造方法
|
|
|
|
*
|
|
|
|
* @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.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(/<img .*?>/g, '')
|
|
|
|
}
|
|
|
|
|
|
|
|
return text
|
|
|
|
}
|
|
|
|
|
|
|
|
// 播放提示音
|
|
|
|
play() {
|
|
|
|
// 客户端有消息提示
|
|
|
|
if (isElectronMode()) return
|
|
|
|
|
|
|
|
useSettingsStore().isPromptTone && palyMusic()
|
|
|
|
}
|
|
|
|
|
2025-05-30 19:53:18 +00:00
|
|
|
async handle() {
|
2024-12-24 08:14:21 +00:00
|
|
|
// 不是自己发送的消息则需要播放提示音
|
|
|
|
if (!this.isCurrSender()) {
|
|
|
|
this.play()
|
|
|
|
}
|
|
|
|
|
|
|
|
// 判断会话列表是否存在,不存在则创建
|
|
|
|
if (useTalkStore().findTalkIndex(this.getIndexName()) == -1) {
|
2025-05-30 19:53:18 +00:00
|
|
|
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()
|
|
|
|
}
|
2024-12-24 08:14:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 判断当前是否正在和好友对话
|
|
|
|
if (this.isTalk(this.talk_type, this.receiver_id, this.sender_id)) {
|
|
|
|
this.insertTalkRecord()
|
|
|
|
} else {
|
|
|
|
this.updateTalkItem()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 显示消息提示
|
|
|
|
* @returns
|
|
|
|
*/
|
|
|
|
showMessageNocice() {
|
|
|
|
if (useSettingsStore().isLeaveWeb) {
|
2025-05-22 02:30:02 +00:00
|
|
|
const notification = new Notification('IM 在线聊天', {
|
2024-12-24 08:14:21 +00:00
|
|
|
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(({ code, data }) => {
|
|
|
|
if (code == 200) {
|
|
|
|
let item = formatTalkItem(data)
|
|
|
|
item.unread_num = 1
|
|
|
|
useTalkStore().addItem(item)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 插入对话记录
|
|
|
|
*/
|
|
|
|
insertTalkRecord() {
|
|
|
|
let record = this.resource
|
|
|
|
|
|
|
|
// 群成员变化的消息,需要更新群成员列表
|
2025-05-30 19:53:18 +00:00
|
|
|
if ([1102, 1103, 1104, 1115].includes(record.msg_type)) {
|
2024-12-24 08:14:21 +00:00
|
|
|
useDialogueStore().updateGroupMembers()
|
|
|
|
}
|
|
|
|
|
2025-05-30 19:53:18 +00:00
|
|
|
//群解散时,需要更新群成员权限
|
|
|
|
if ([1106].includes(record.msg_type)) {
|
|
|
|
useDialogueStore().updateDismiss(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
//群成员被移出时,需要更新群成员权限
|
|
|
|
if ([1104, 1115].includes(record.msg_type)) {
|
|
|
|
if (this.resource?.extra?.members?.length > 0) {
|
|
|
|
const isMeQuit = this.resource.extra.members.find(
|
|
|
|
(item) => item.user_id === this.getAccountId()
|
|
|
|
)
|
|
|
|
if (isMeQuit) {
|
|
|
|
useDialogueStore().updateQuit(true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 群信息变更时,需要更新群信息
|
|
|
|
if ([1116].includes(record.msg_type)) {
|
|
|
|
// 更新会话信息
|
|
|
|
useDialogueStore().updateDialogueTalk({
|
|
|
|
username: record.extra.group_name,
|
|
|
|
avatar: record.extra.group_avatar
|
|
|
|
})
|
|
|
|
//更新会话列表中的会话信息
|
|
|
|
useTalkStore().updateItem({
|
|
|
|
index_name: this.getIndexName(),
|
|
|
|
name: record.extra.group_name,
|
|
|
|
avatar: record.extra.group_avatar
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-12-24 08:14:21 +00:00
|
|
|
useDialogueStore().addDialogueRecord(formatTalkRecord(this.getAccountId(), this.resource))
|
|
|
|
|
|
|
|
if (!this.isCurrSender()) {
|
|
|
|
// 推送已读消息
|
|
|
|
setTimeout(() => {
|
|
|
|
ws.emit('im.message.read', {
|
|
|
|
receiver_id: this.sender_id,
|
|
|
|
msg_ids: [this.resource.msg_id]
|
|
|
|
})
|
|
|
|
}, 1000)
|
|
|
|
}
|
2025-06-27 08:26:02 +00:00
|
|
|
console.log('输出加载1')
|
2024-12-24 08:14:21 +00:00
|
|
|
// 获取聊天面板元素节点
|
|
|
|
const el = document.getElementById('imChatPanel')
|
|
|
|
if (!el) return
|
|
|
|
|
|
|
|
// 判断的滚动条是否在底部
|
2025-05-28 03:29:13 +00:00
|
|
|
const isBottom = isScrollAtBottom(el)
|
2024-12-24 08:14:21 +00:00
|
|
|
if (isBottom || record.user_id == this.getAccountId()) {
|
2025-05-28 03:29:13 +00:00
|
|
|
scrollToBottom()
|
2024-12-24 08:14:21 +00:00
|
|
|
} 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())
|
|
|
|
})
|
2025-05-30 19:53:18 +00:00
|
|
|
//收到新消息时,同时判断是否有人@我
|
|
|
|
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()
|
|
|
|
useTalkStore().updateItem({
|
|
|
|
index_name: this.getIndexName(),
|
|
|
|
msg_text: this.getTalkText(),
|
|
|
|
atsign_num: 1
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2024-12-24 08:14:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Talk
|