import API from '@/api' import { getWsUrl } from '@/util/contract.js' import WsManager from '@/util/wsManager.js' import { decryptoMsg, dealErrorMsg, noticeManager, getUserOpt, setUserOpt } from '@/util/util.js' import axios from 'axios' import Message from '@/store/db/Message.js' var socket = null const actions = { /** * @des 获取群基础信息 * @param {Object} store * @param {Object} params */ async getGroupInfo ({ dispatch, commit, state }, params) { API.group.getGroupInfo2({ group_id: state.groupId }, info => { if (info.data.code === 0) { let adminList = info.data.data.adminList let blockList = info.data.data.blockList let pinMsg = info.data.data.pinMsg let group = info.data.data.group let members = info.data.data.members let membersNum = info.data.data.group.member_num let userInfo = info.data.data.userInfo let sessionInfo = info.data.data.sessionInfo let isJoin = info.data.data.members.some((item) => { return state.userId == item.user_id }) let eosInfo = info.data.data.eosInfo pinMsg && (pinMsg.visible = true) let _members = {} members.forEach(n => { if (!n.user_id) return _members[n.user_id] = n }) commit('setGroupInfo', { userCounts: members.length, groupName: group.group_title, shareName: group.group_name, members: _members, membersArray: members, membersNum: membersNum, userInfo, groupNotice: group.group_notice, url: group.url, inviteUrl: group.invite_url, sessionInfo: sessionInfo || { is_mute: 0, is_pin: 0, pin_time_int: 0 }, isJoin, coverPhoto: group.cover_photo, adminList: adminList, blockList: blockList, pinMsg: pinMsg || {}, creator: group.creator, eosInfo: eosInfo }) } }) }, /** * @des 群聊 获取最新消息【from indexeddb】 * @param {Object} store * @param {Object} params */ async getNewMsgFromDb (store, params = {}) { // 先读取indexDB的数据,来渲染 let { state, commit } = store let { groupId } = state const objMessage = new Message() let data = await objMessage.getMsg(state.groupId) setUserOpt('lastShowMsgUid', 0) if (groupId === state.groupId && data && data.list.length > 0) { params.fromdb = true actions._renderGroupMsg(store, data, params) commit('setGroupMembers', Object.assign(data.userMap, state.members)) return true } else { return false } }, /** * @des 群聊 获取最新消息【不需要登录】 * @param {Object} store * @param {Object} params */ async getNewMsg (store, params = {}) { let { state, commit } = store let { groupId, endHash } = state // 然后再请求网上的数据,来渲染 let msg = await API.group.getNewMsg({ group_id: groupId, client_hash: endHash }).catch(() => {}) if (groupId === state.groupId && msg.data.code === 0 && msg.data.data.list.length > 0) { params.fromdb = false commit('setGroupMembers', Object.assign(msg.data.data.userMap, state.members)) actions._renderGroupMsg(store, msg.data.data, params) } return 'done' }, _renderGroupMsg ({ dispatch, commit, state }, data, params) { let list = [] // 解密数据&&计算头像信息 let lastShowMsgUid = getUserOpt('lastShowMsgUid') || 0 data.list.forEach(n => { let member = data.userMap[n.from] || {} if (!member) return // 显示信息 list.push({ name: member.nick_name || 'unknown', content: n.msg, userId: n.from, timestamp: n.create_time_int, avatar: member.cover_photo || '', hash: n.hash, type: n.from == state.userId ? 'me' : 'you', msg_type: n.msg_type, ext: n.ext ? n.ext : null, ext_info: n.ext_info ? n.ext_info : null, isShowFullInfo: n.from != lastShowMsgUid }) if (n.msg_type == 5) lastShowMsgUid = 0 lastShowMsgUid = n.msg_type == 5 ? 0 : n.from }) setUserOpt('lastShowMsgUid', lastShowMsgUid) commit('updateMembers', data.userMap) // if (state.chatList.length) { // commit('setHash', { // endHash: list[list.length - 1].hash, // startHash: list[0].hash // }) // } else { // commit('setHash', { // endHash: list[list.length - 1].hash, // startHash: list[0].hash // }) // } commit('setHash', { endHash: list[list.length - 1] ? list[list.length - 1].hash : '', startHash: list[0] ? list[0].hash : '' }) let itemData = params.newMsg ? { list: list, newMsg: params.newMsg, fromdb: false } : { list: list, fromdb: params.fromdb } commit('addChatItem', itemData) }, async getPrivateNewMsgFromDb (store, params = {}) { let { rootState, state, commit } = store let { curSession } = rootState const objMessage = new Message() let data = await objMessage.getMsg(curSession) setUserOpt('lastShowMsgUid', 0) if (curSession === rootState.curSession && data && data.list.length > 0) { actions._renderPrivateMsg(store, data, params) commit('setGroupMembers', Object.assign(data.userMap, state.members)) return true } else { return false } }, /** * @des 私聊 获取最新消息【不需要登录】 * @param {Object} store * @param {Object} params */ async getPrivateNewMsg (store, params = {}) { let { state, rootState } = store let { curSession } = rootState let msg = await API.person.getNewMsg({ session_id: curSession, client_hash: state.endHash }).catch(() => {}) // 有聊天记录 // if (msg.data.code === 0 && msg.data.data.list.length > 0) { // 没有聊天记录也要渲染,不然没设置member if (curSession === rootState.curSession && msg.data.code === 0) { actions._renderPrivateMsg(store, msg.data.data, params) } return msg.data }, _renderPrivateMsg ({ dispatch, commit, state, rootState }, data, params) { let list = [] // 更新members信息 let members = data.userMap commit('updateGroup', { key: 'members', data: members }) for (let k in members) { if (k !== rootState.userId) { commit('updateGroup', { key: 'privateName', data: (members[k] && members[k]['nick_name']) || '' }) } } let lastShowMsgUid = getUserOpt('lastShowMsgUid') || 0 data.list.forEach(n => { let member = data.userMap[n.from] if (!member) return list.push({ name: member ? member.nick_name : 'unknown', content: n.msg, userId: n.from, timestamp: n.create_time_int, avatar: member.cover_photo || '', hash: n.hash, type: n.from == rootState.userId ? 'me' : 'you', msg_type: n.msg_type, ext: n.ext ? n.ext : null, ext_info: n.ext_info ? n.ext_info : null, isShowFullInfo: n.from != lastShowMsgUid }) if (n.msg_type == 5) lastShowMsgUid = 0 lastShowMsgUid = n.msg_type == 5 ? 0 : n.from }) setUserOpt('lastShowMsgUid', lastShowMsgUid) if (list.length) { if (state.chatList.length) { commit('setHash', { endHash: list[list.length - 1].hash }) } else { commit('setHash', { endHash: list[0].hash, startHash: list[0].hash }) } let itemData = params.newMsg ? { list: list, newMsg: params.newMsg } : list commit('addChatItem', itemData) } }, /** * @des 群聊 获取历史消息【不需要登录】 * @param {Object} store * @param {Object} params */ async getHistoryMsg ({ dispatch, commit, state, rootState }, params = {}) { let his = localStorage.getItem(params.hash) // 先从本地缓存中获取记录 let dList = [] let status = '' // 请求状态 if (his && state.useCache) { dList = JSON.parse(his) } else { // 本地缓存中没有记录,从接口获取 let msg = await API.group.getHistoryMsg({ group_id: state.groupId, client_hash: state.startHash }).catch(() => {}) if (msg && msg.data.code === 0 && msg.data.data.list.length > 0) { // 重新格式数据 let lastShowMsgUid = 0 msg.data.data.list.forEach(n => { if (n.msg_type == 4) { n.msg = JSON.parse(decryptoMsg(n.msg)) } else { n.msg = decryptoMsg(n.msg) } let member = msg.data.data.userMap[n.from] commit('updateMembers', msg.data.data.userMap) if (!member) return dList.push({ name: member ? member.nick_name : 'unknown', content: n.msg, userId: n.from, timestamp: n.create_time_int, avatar: member ? member.cover_photo : '', hash: n.hash, type: n.from == state.userId ? 'me' : 'you', msg_type: n.msg_type, ext: n.ext ? n.ext : null, isShowFullInfo: n.from != lastShowMsgUid }) if (n.msg_type == 5) lastShowMsgUid = 0 lastShowMsgUid = n.msg_type == 5 ? 0 : n.from }) // 保存到本地缓存中 if (state.useCache) { localStorage.setItem(params.hash, JSON.stringify(dList)) } } } if (dList.length > 0) { commit('setHash', { startHash: dList[0].hash }) commit('addHistoryList', dList) status = 'done' } else { commit('setHash', { startHash: null }) status = 'end' } return status }, /** * @des 私聊 获取历史消息【不需要登录】 * @param {Object} store * @param {Object} params */ async getPrivateHistoryMsg ( { dispatch, commit, state, rootState }, params = {} ) { let his = localStorage.getItem(params.hash) // 先从本地缓存中获取记录 let dList = [] let status = '' // 请求状态 if (his && state.useCache) { dList = JSON.parse(his) } else { // 本地缓存中没有记录,从接口获取 let msg = await API.person .getHistoryMsg({ session_id: rootState.curSession, client_hash: state.startHash }) .catch(() => {}) if (msg.data.code === 0 && msg.data.data.list.length > 0) { // 重新格式数据 let lastShowMsgUid = 0 msg.data.data.list.forEach((n, index) => { n.msg = decryptoMsg(n.msg) let member = msg.data.data.userMap[n.from] dList.push({ name: member ? member.nick_name : 'unknow', content: n.msg, userId: n.from, timestamp: n.create_time_int, avatar: member.cover_photo || '', hash: n.hash, type: n.from == rootState.userId ? 'me' : 'you', msg_type: n.msg_type, ext: n.ext ? n.ext : null, isShowFullInfo: n.from != lastShowMsgUid }) if (n.msg_type == 5) lastShowMsgUid = 0 lastShowMsgUid = n.msg_type == 5 ? 0 : n.from }) // 保存到本地缓存中 if (state.useCache) { localStorage.setItem(params.hash, JSON.stringify(dList)) } } } if (dList.length > 0) { commit('setHash', { startHash: dList[0].hash }) commit('addHistoryList', dList) status = 'done' } else { commit('setHash', { startHash: null }) status = 'end' } return status }, /** * 发送群聊消息 * @param {Object} data * @param {Object} params */ doSendMsg ({ dispatch, commit, state }, params = {}) { return new Promise((resolve, reject) => { API.group.sendMsg({ group_id: state.groupId, msg_type: params.type, msg: params.msg }).then(({ data }) => { if (data.code === 0) { if (params.createTime) { let createTime = params.createTime data.data.content = decryptoMsg(data.data.content) let list = state.chatList for (let i = list.length - 1; i >= 0; i--) { let listItem = list[i] if (listItem.createTime === createTime) { commit('updataChatItem', { index: i, hash: data.data.hash, isCommfirm: true }) break } } } else { // 针对用户第一次发言 commit('updateMembers', data.data.userMap) data.data.content = decryptoMsg(data.data.content) commit('addChatItem', data.data) } commit('setHash', { endHash: data.data.hash }) commit('updateSessionLastMsgNoDecode', Object.assign(data.data, { group_id: state.groupId })) resolve(data.data) } else { if (params.createTime) { dealErrorMsg(state, params.createTime) } } }).catch(err => { if (params.createTime) { dealErrorMsg(state, params.createTime) } reject(err) }) }) }, /** * 发送聊天文件 * @param {Object} data * @param {Object} params */ async doSendFile ({ dispatch, commit, state, rootState }, params = {}) { return new Promise((resolve, reject) => { let userId = rootState.userId let token = rootState.token let formData = new FormData() formData.append('res', params.res) formData.append('user_id', userId) formData.append('token', token) // 私聊群聊参数调整 if (state.groupId) { formData.append('group_id', state.groupId) } else { let arr = rootState.curSession.split('-') let toUser if (arr[0] == rootState.userId) toUser = arr[1] else toUser = arr[0] formData.append('to_user', toUser) } let sendUrl = state.groupId ? 'group/sendFile' : 'person/sendFile' axios({ url: [API.host, sendUrl].join(''), method: 'post', data: formData, headers: { 'Content-Type': 'multipart/form-data' } }) .then(({ data }) => { if (data.code === 0) { if (params.createTime) { let createTime = params.createTime data.data.content = decryptoMsg(data.data.content) let list = state.chatList list.forEach(item => { if (item.createTime === createTime) { item.res = undefined item.content = data.data.content item.hash = data.data.hash item.loading = false item.fail = false if (!item.ext_info) item.ext_info = {} item.ext_info.cover_url = data.data.ext_info && data.data.ext_info.cover_url } }) } else { // 针对用户第一次发言 commit('updateMembers', data.data.userMap) data.data.content = decryptoMsg(data.data.content) commit('addChatItem', data.data) } commit('setHash', { endHash: data.data.hash }) commit('updateSessionLastMsgNoDecode', Object.assign(data.data, { group_id: state.groupId || rootState.curSession })) resolve(data.data) } else { if (params.createTime) { dealErrorMsg(state, params.createTime) } } }) .catch(err => { if (params.createTime) { dealErrorMsg(state, params.createTime) } reject(err) }) }) }, /** * 发送私聊消息 * @param {Object} data * @param {Object} params */ doSendPrivateMsg ({ dispatch, commit, state, rootState }, params = {}) { return new Promise((resolve, reject) => { API.person.sendMsg({ session_id: rootState.curSession, msg_type: params.type, msg: params.msg }).then(({ data }) => { if (data.code === 0) { if (params.createTime) { let createTime = params.createTime data.data.content = decryptoMsg(data.data.content) let list = state.chatList for (let i = list.length - 1; i >= 0; i--) { let listItem = list[i] if (listItem.createTime === createTime) { commit('updataChatItem', { index: i, hash: data.data.hash, isCommfirm: true }) break } } } else { // 针对用户第一次发言 commit('updateMembers', data.data.userMap) data.data.content = decryptoMsg(data.data.content) commit('addChatItem', data.data) } commit('setHash', { endHash: data.data.hash }) commit('updateSessionLastMsgNoDecode', Object.assign(data.data, { group_id: rootState.curSession })) resolve(data.data) } else { if (params.createTime) { dealErrorMsg(state, params.createTime) } } }).catch(err => { if (params.createTime) { dealErrorMsg(state, params.createTime) } reject(err) }) }) }, /** * 链接websocket * @param {Object} data * @param {Object} params */ initSocket ({ commit, state, rootState, rootGetters, dispatch }, params = {}) { if (!window.WebSocket) { console.error('Error: WebSocket is not supported .') return } let host = `${getWsUrl()}/?user_id=${rootState.userId}&token=${ rootState.token }` if (socket) { socket.destroy() socket = null } socket = new WsManager(host, { autoConnect: true, // 自动连接 reconnection: true, // 断开自动重连 reconnectionDelay: 5000, // 重连间隔时间,单位秒 keepAliveContent: JSON.stringify({ act: 'alive', player: name }) // 心跳包内容 }) socket.on('open', res => {}) socket.on('message', e => { let _data = JSON.parse(e) let channel = _data.channel let data = _data.data let muteList = rootGetters.muteList // 免打扰列表 // 群聊 if (channel.match('chat:group')) { let isMute = muteList.some(v => { return v.session_id == data.group_id }) if (data.type === 'msg') { if (rootState.curSession == data.group_id) { // 当前会话需要加载新消息 dispatch('getNewMsg', { newMsg: true }) if (data.from != rootState.userId) commit('addUnreadNums') } if (!isMute) { noticeManager.showNotification(data) } } if (data.type === 'update') { } if (data.type === 'add_admin') { } if (data.type === 'remove_admin') { } if (data.type === 'repeal') { commit('repealChatItem', data) // 左侧会话 data.msg_type = -1 commit('updateSessionLastmsg', data) } if (data.type === 'block') { commit('updateGroupBlockList', { type: 'add', id: data.to }) } if (data.type === 'unblock') { commit('updateGroupBlockList', { type: 'delete', id: data.to }) } if (data.type === 'leave') { if (data.group_id != state.groupId) return // 不是本群信息-无响应 if (data.user_info.user_id == rootState.userId) return // 本人-不走这个ws // 退群仅通知管理员 // let isAdmin = state.adminList.some(item => { return item == rootState.userId }) // if (isAdmin) { // data.joinMsg = (data.user_info.nick_name || data.user_info.name) + '退出群组' // commit('addChatItem', data) // } // 本人退出刷新群信息 if (data.user_id == rootState.userId) { dispatch('getGroupInfo') } else { commit('updateMembersArray', { type: 'del', userInfo: data.user_info }) } } if (data.type === 'join') { if (data.group_id != state.groupId) return if (data.user_info.user_id == rootState.userId) return data.joinMsg = (data.user_info.nick_name || data.user_info.name) + '加入群组' commit('updateMembers', { [data.user_info.user_id]: data.user_info }) commit('updateMembersArray', { type: 'add', userInfo: data.user_info }) // commit('addChatItem', data) } if (data.type === 'pin_msg') { commit('updateGroupPinMsg', data.pinMsg) } if (data.type === 'unpin_msg') { commit('updateGroupPinMsg', null) } if (data.type === 'new_redpack' && rootState.curSession == data.group_id) { commit('addPacketItem', data) commit('updateSessionLastmsg', data) } if (data.type === 'grab_redpack' && rootState.curSession == data.group_id) { if (data.from == rootState.userId || data.to == rootState.userId) { commit('addPacketTip', data) commit('updateSessionLastmsg', data) } } } // 私聊 if (channel.match('chat:person')) { if (!rootState.curSession) return let curId = +data.to > +data.from ? `${data.from}-${data.to}` : `${data.to}-${data.from}` let isMute = muteList.some(v => { return v.session_id == curId }) if (data.type === 'msg') { if (rootState.curSession == curId) { // 当前会话需要加载新消息 dispatch('getPrivateNewMsg') if (data.from != rootState.userId) commit('addUnreadNums') } // 如果在隐藏tab就需要 通知 if (!isMute) { noticeManager.showNotification(data) } } if (data.type === 'repeal') { commit('repealChatItem', data) let sessionId = data.from > data.to ? `${data.to}-${data.from}` : `${data.from}-${data.to}` data.group_id = sessionId data.msg_type = -1 commit('updateSessionLastmsg', data) } // if (data.type === 'new_redpack' && rootGetters.otherUserId == data.from) { if (data.type === 'new_redpack') { commit('addPacketItem', data) } if (data.type === 'grab_redpack' && rootGetters.otherUserId == data.from) { if (data.from == rootState.userId || data.to == rootState.userId) { commit('addPacketTip', data) } } if (data.type === 'join_group') { commit('updateMembers', { [rootState.userInfo.user_id]: rootState.userInfo }) commit('updateMembersArray', { type: 'add', userInfo: rootState.userInfo }) // commit('addChatItem', data) } if (data.type === 'leave_group') { commit('updateMembersArray', { type: 'del', userInfo: rootState.userInfo }) // commit('addChatItem', data) dispatch('getGroupInfo') } } // 有新session 更新sessionList-自己退群不做处理 let isLeaveGroup = data.msg_type == 5 && data.ext_info.event_type == 'leave_group' if (!isLeaveGroup && (data.type === 'msg' || data.type === 'new_redpack')) { let sessionList = rootState.chat.sessionList let curId if (data.group_id) { curId = data.group_id } else { curId = +data.to > +data.from ? `${data.from}-${data.to}` : `${data.to}-${data.from}` } let isInSession = sessionList.some(v => { return v.session_id == curId }) let baseObj = { session_id: curId, cont: decryptoMsg(data.content), unread: rootState.userId == data.from ? 0 : 1, update_time_int: data.timestamp, timestamp: data.timestamp } if (!isInSession) { if (!data.group_id) { // 私聊要拿对方的头像 API.user.getOtherInfo({ target_id: rootState.userId === data.from ? data.to : data.from }).then(({ data }) => { let obj = { cover_photo: data.data.cover_photo, is_group: '0', name: data.data.nick_name } commit('addSessionItem', Object.assign(obj, baseObj)) }) } else { API.group.getGroupInfo({ group_id: data.group_id }).then(({ data }) => { let group = data.data.group let obj = { cover_photo: group.cover_photo, is_group: '1', is_auth: group.is_auth, name: group.group_title } commit('addSessionItem', Object.assign(obj, baseObj)) }) } } if (data.from != rootState.userId) { commit('setSessionItemUnread', Object.assign({ curSession: rootState.curSession }, baseObj)) } commit('updateSessionLastmsg', Object.assign(data, { sessionId: curId })) } }) }, /** * 撤回消息 * @param {Object} params * {index:number, session_id:string, hash:string} */ async doRepealGroupMsg ({ dispatch, commit, state }, params = {}) { try { await API.group.repealGroupMsg({ group_id: state.groupId, hash: params.hash }) } catch (error) {} }, /** * 封禁群用户 */ async doBlockUser ({ state }, params = {}) { try { await API.group.blockUser({ group_id: state.groupId, block_id: params.id }) } catch (error) {} }, /** * 解禁用户 */ async doUnBlockUser ({ state }, params = {}) { try { await API.group.unblockUser({ group_id: state.groupId, block_id: params.id }) } catch (error) {} }, /** * 更新置顶 */ async doPinMsg ({ state }, params = {}) { try { await API.group.pinMsg({ group_id: state.groupId, hash: params.hash }) } catch (error) {} }, /** * 取消置顶 */ async doUnpinMsg ({ state }, params = {}) { try { await API.group.unpinMsg({ group_id: state.groupId, hash: params.hash }) } catch (error) {} }, /** * 加入群组 */ async joinGroup ({ state, commit }, params = {}) { try { await API.group.joinGroup({ group_id: state.groupId }) commit('updateJoin', true) commit('changeHotGroupStatus', { groupId: state.groupId, isJoin: 1 }) } catch (error) {} } } export default actions