chat-app/src/event/talk.js
wangyifeng dd0ccb9818
Some checks are pending
Check / lint (push) Waiting to run
Check / typecheck (push) Waiting to run
Check / build (build, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build, 18.x, windows-latest) (push) Waiting to run
Check / build (build:app, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:app, 18.x, windows-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, ubuntu-latest) (push) Waiting to run
Check / build (build:mp-weixin, 18.x, windows-latest) (push) Waiting to run
新增收起应用时同时停止已读未读定时器,并在恢复后打开;解决群聊踢人后自己也看不到右上角的管理按钮问题
2025-04-22 14:49:08 +08:00

372 lines
9.8 KiB
JavaScript

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(/<img .*?>/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