chat-pc/src/store/modules/dialogue.js

294 lines
7.2 KiB
JavaScript
Raw Normal View History

2024-12-24 08:14:21 +00:00
import { defineStore } from 'pinia'
import {
ServeRemoveRecords,
ServeRevokeRecords,
ServePublishMessage,
ServeCollectEmoticon
} from '@/api/chat'
import { ServeGetGroupMembers,ServeGroupDetail } from '@/api/group.js'
2024-12-24 08:14:21 +00:00
import { useEditorStore } from './editor'
// 键盘消息事件定时器
let keyboardTimeout = null
export const useDialogueStore = defineStore('dialogue', {
state: () => {
return {
// 对话索引(聊天对话的唯一索引)
index_name: '',
// 对话节点
talk: {
avatar:'',
2024-12-24 08:14:21 +00:00
username: '',
talk_type: 0, // 对话来源[1:私聊;2:群聊]
receiver_id: 0,
group_type:0
2024-12-24 08:14:21 +00:00
},
// 好友是否正在输入文字
keyboard: false,
// 对方是否在线
online: false,
// 聊天记录
records: [],
// 查询指定消息上下文的消息信息
specifiedMsg: '',
// 是否是手动切换会话
isManualSwitch: false,
2024-12-24 08:14:21 +00:00
// 新消息提示
unreadBubble: 0,
// 是否开启多选操作模式
isOpenMultiSelect: false,
// 是否显示编辑器
isShowEditor: false,
// 是否显示会话列表
isShowSessionList: true,
groupInfo: {} ,
2024-12-24 08:14:21 +00:00
// 群成员列表
members: [],
// 群成员列表按字母分组
membersByAlphabet: {},
2024-12-24 08:14:21 +00:00
// 对话记录
items: {
'1_1': {
talk_type: 1, // 对话类型
receiver_id: 0, // 接收者ID
read_sequence: 0, // 当前已读的最后一条记录
records: []
}
}
}
},
getters: {
// 多选列表
selectItems: (state) => state.records.filter((item) => item.isCheck),
// 当前对话是否是群聊
isGroupTalk: (state) => state.talk.talk_type === 2
},
actions: {
// 更新在线状态
setOnlineStatus(status) {
this.online = status
},
// 更新对话信息
setDialogue(data = {}) {
this.online = data.is_online == 1
this.talk = {
username: data.remark || data.name,
talk_type: data.talk_type,
receiver_id: data.receiver_id,
avatar:data.avatar,
group_type:data.group_type
2024-12-24 08:14:21 +00:00
}
this.index_name = `${data.talk_type}_${data.receiver_id}`
this.records = []
this.unreadBubble = 0
this.isShowEditor = data?.is_robot === 0
// 只在手动切换会话时清空 specifiedMsg
// if (this.isManualSwitch) {
// this.specifiedMsg = ''
// this.isManualSwitch = false
// }
2024-12-24 08:14:21 +00:00
this.members = []
this.membersByAlphabet = []
2024-12-24 08:14:21 +00:00
if (data.talk_type == 2) {
this.updateGroupMembers()
this.getGroupInfo()
2024-12-24 08:14:21 +00:00
}
},
// 更新提及列表
async updateGroupMembers() {
let { code, data } = await ServeGetGroupMembers({
group_id: this.talk.receiver_id
})
if (code != 200) return
this.members = data.items.map((o) => ({
id: o.user_id,
nickname: o.nickname,
avatar: o.avatar,
gender: o.gender,
leader: o.leader,
remark: o.remark,
online: false,
value: o.nickname
}))
const groupMap = {};
data.sortItems.forEach(member => {
const alpha = (member.key || member.nickname?.[0] || '#').toUpperCase();
if (!groupMap[alpha]) groupMap[alpha] = [];
groupMap[alpha].push(member);
});
const alphabets = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
this.membersByAlphabet = alphabets.map(alpha => ({
alphabet: alpha,
members: groupMap[alpha] || []
})).filter(group => group.members.length > 0);
2024-12-24 08:14:21 +00:00
},
// 清空对话记录
clearDialogueRecord() {
this.records = []
},
// 数组头部压入对话记录
unshiftDialogueRecord(records) {
this.records.unshift(...records)
},
async getGroupInfo(){
const { code, data } = await ServeGroupDetail({
group_id: this.talk.receiver_id
})
if(code == 200){
this.groupInfo = data
}
},
2024-12-24 08:14:21 +00:00
// 推送对话记录
addDialogueRecord(record) {
// TOOD 需要通过 sequence 排序,保证消息一致性
// this.records.splice(index, 0, record)
this.records.push(record)
},
// 更新对话记录
updateDialogueRecord(params) {
const { msg_id = '' } = params
const item = this.records.find((item) => item.msg_id === msg_id)
item && Object.assign(item, params)
},
// 批量删除对话记录
batchDelDialogueRecord(msgIds = []) {
msgIds.forEach((msgid) => {
const index = this.records.findIndex((item) => item.msg_id === msgid)
if (index >= 0) this.records.splice(index, 1)
})
},
// 自增好友键盘输入事件
triggerKeyboard() {
this.keyboard = true
clearTimeout(keyboardTimeout)
keyboardTimeout = setTimeout(() => (this.keyboard = false), 2000)
},
setUnreadBubble(value) {
if (value === 0) {
this.unreadBubble = 0
} else {
this.unreadBubble++
}
},
// 关闭多选模式
closeMultiSelect() {
this.isOpenMultiSelect = false
for (const item of this.selectItems) {
if (item.isCheck) {
item.isCheck = false
}
}
},
// 删除聊天记录
ApiDeleteRecord(msgIds = []) {
ServeRemoveRecords({
talk_type: this.talk.talk_type,
receiver_id: this.talk.receiver_id,
msg_ids: msgIds
}).then((res) => {
if (res.code == 200) {
this.batchDelDialogueRecord(msgIds)
} else {
window['$message'].warning(res.message)
}
})
},
// 撤销聊天记录
ApiRevokeRecord(msg_id = '') {
ServeRevokeRecords({ msg_id }).then((res) => {
if (res.code == 200) {
this.updateDialogueRecord({ msg_id, is_revoke: 1 })
} else {
window['$message'].warning(res.message)
}
})
},
// 转发聊天记录
ApiForwardRecord(options) {
let data = {
type: 'forward',
receiver: {
talk_type: this.talk.talk_type,
receiver_id: this.talk.receiver_id
},
...options
}
ServePublishMessage(data).then((res) => {
if (res.code == 200) {
this.closeMultiSelect()
}
})
},
ApiCollectImage(options) {
const { msg_id } = options
ServeCollectEmoticon({ msg_id }).then(() => {
useEditorStore().loadUserEmoticon()
window['$message'] && window['$message'].success('收藏成功')
})
},
// 更新视频上传进度
updateUploadProgress(uploadId, percentage) {
const record = this.records.find(item =>
item.extra && item.extra.is_uploading && item.extra.upload_id === uploadId
)
if (record) {
record.extra.percentage = percentage
}
},
// 视频上传完成后更新消息
completeUpload(uploadId, videoInfo) {
const record = this.records.find(item =>
item.extra && item.extra.is_uploading && item.extra.upload_id === uploadId
)
if (record) {
record.extra.is_uploading = false
record.extra.url = videoInfo.url
// record.extra.cover = videoInfo.cover
}
2024-12-24 08:14:21 +00:00
}
}
})