Files
cunkebao_v3/Backend/src/plugins/socket/event/talk-event.js
2025-03-12 12:48:13 +08:00

233 lines
5.2 KiB
JavaScript
Executable File

import Vue from 'vue'
import store from '@/store'
import router from '@/router'
import AppMessageEvent from './app-message-event'
import { parseTime } from '@/utils/functions'
import { formateTalkItem, findTalkIndex } from '@/utils/talk'
import { ServeClearTalkUnreadNum, ServeCreateTalkList } from '@/api/chat'
/**
* 聊天消息处理
*/
class TalkEvent extends AppMessageEvent {
/**
* @var resource 资源
*/
resource
/**
* 初始化构造方法
*
* @param {Object} resource Socket消息
*/
constructor(resource) {
super()
this.resource = resource
}
handle() {
const indexName = this.getIndexName()
if (!this.isTalkPage()) {
if (this.resource.send_user != this.UserId) {
this.showMessageNocice(indexName)
}
return false
}
const index = findTalkIndex(indexName)
if (index == -1) {
// 判断消息来源是否在对话列表中...
this.loadTalkItem()
return
}
if (
this.isChatting(
this.resource.source_type,
this.resource.receive_user,
this.resource.send_user
)
) {
this.updateTalkRecord(index)
} else {
this.updateTalkItem(index)
}
}
/**
* 显示消息提示
*
* @param {String} index_name
* @returns
*/
showMessageNocice(index_name) {
let tag = this.resource.data.source == 1 ? '[私信]' : '[群聊]'
let group_name = this.resource.data.group_name || '好友'
let nickname = this.resource.data.nickname || this.resource.data.group_name
let content = this.getTalkText()
this.$notify({
title: `${tag} 聊天通知`,
message: `${group_name}」@${nickname} : ${content}`,
duration: 3000000,
customClass: 'talk-notify pointer',
onClick: function() {
sessionStorage.setItem('send_message_index_name', index_name)
router.push('/')
this.close()
},
position: 'bottom-right',
})
store.commit('INCR_UNREAD_NUM')
}
/**
* 更新对话记录
*
* @param {Number} index 聊天列表的索引
*/
updateTalkRecord(index) {
let record = this.resource.data
record.float =
record.user_id == 0
? 'center'
: record.user_id == this.UserId
? 'right'
: 'left'
store.commit('PUSH_DIALOGUE', record)
// 获取聊天面板元素节点
let elChatPanel = document.getElementById('lumenChatPanel')
// 判断的滚动条是否在底部
let isBottom =
Math.ceil(elChatPanel.scrollTop) + elChatPanel.clientHeight >=
elChatPanel.scrollHeight
if (isBottom || record.user_id == this.UserId) {
Vue.nextTick(() => {
// 更新聊天面板滚动条置底
elChatPanel.scrollTop = elChatPanel.scrollHeight
})
} else {
store.commit('SET_TLAK_UNREAD_MESSAGE', {
content: this.getTalkText(),
nickname: record.nickname,
})
}
store.commit('UPDATE_TALK_ITEM', {
index,
item: {
msg_text: this.getTalkText(),
updated_at: parseTime(new Date()),
},
})
if (
this.resource.data.source == 1 &&
this.UserId !== this.resource.data.user_id
) {
// 更新未读消息
ServeClearTalkUnreadNum({
type: store.state.dialogue.source,
receive: store.state.dialogue.receive_id,
})
}
}
/**
* 更新对话列表记录
*
* @param {Number} index 聊天列表的索引
*/
updateTalkItem(index) {
store.commit('INCR_UNREAD_NUM')
if (index == -1) {
// 对话列表不存在需请求后端...
return
}
store.commit('UPDATE_TALK_MESSAGE', {
index,
item: {
msg_text: this.getTalkText(),
updated_at: parseTime(new Date()),
},
})
}
/**
* 获取聊天列表左侧的对话信息
*/
getTalkText() {
let text = this.resource.data.content
switch (this.resource.data.msg_type) {
case 2:
let file_type = this.resource.data.file.file_type
text = file_type == 1 ? '[图片消息]' : '[文件消息]'
break
case 4:
text = '[会话记录]'
break
case 5:
text = '[代码消息]'
break
}
return text
}
/**
* 判断用户是否打开对话页
*/
isTalkPage() {
let path = router.currentRoute.fullPath
return !(path != '/message' && path != '/')
}
/**
* 通过消息获取消息对应的对话索引
*/
getIndexName() {
let message = this.resource
if (
message.source_type == 2 ||
(message.source_type == 1 && message.send_user == this.UserId)
) {
return `${message.source_type}_${message.receive_user}`
}
return `${message.source_type}_${message.send_user}`
}
/**
* 加载对接节点
*/
loadTalkItem() {
let receive_id = this.resource.send_user
let type = this.resource.source_type
if (type == 2 || this.resource.send_user == this.UserId) {
receive_id = this.resource.receive_user
}
ServeCreateTalkList({
type,
receive_id,
}).then(({ code, data }) => {
if (code == 200) {
let { talkItem } = data
talkItem.unread_num++
store.commit('INSERT_TALK_ITEM', formateTalkItem(talkItem))
}
})
}
}
export default TalkEvent