123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769 |
- 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 ({ commit, state }, params) {
- API.group.getGroupInfo2({ group_id: state.groupId }, info => {
- if (info.data.code === 0) {
- let data = info.data.data
- let pinMsg = data.pinMsg
- let group = data.group
- let members = data.members
- let eosInfo = data.eosInfo
- let isJoin = data.members.some((item) => {
- return state.userId == item.user_id
- })
- let _members = {}
- pinMsg && (pinMsg.visible = true)
- 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: data.group.member_num,
- userInfo: data.userInfo,
- groupNotice: group.group_notice,
- url: group.url,
- inviteUrl: group.invite_url,
- sessionInfo: data.sessionInfo || {
- is_mute: 0,
- is_pin: 0,
- pin_time_int: 0
- },
- isJoin,
- coverPhoto: group.cover_photo,
- adminList: data.adminList,
- blockList: data.blockList,
- pinMsg: pinMsg || {},
- creator: group.creator,
- eosInfo: eosInfo
- })
- }
- })
- },
- /**
- * @des 获取最新消息【from indexeddb】【群聊&私聊】
- * @param {Object} store
- * @param {Object} params
- */
- async commonGetNewMsgFromDb (store, params = {}) {
- // 先读取indexDB的数据,来渲染
- let { rootState, state } = store
- const objMessage = new Message()
- let data = await objMessage.getMsg(params.isPrivate ? rootState.curSession : state.groupId)
- setUserOpt('lastShowMsgUid', 0)
- if (data && data.list.length > 0) {
- params.fromdb = true
- actions._renderMsg(store, data, params)
- return true
- } else {
- return false
- }
- },
- /**
- * @des 获取最新消息【不需要登录】【群聊&私聊】
- * @param {Object} store
- * @param {Object} params
- */
- async commonGetNewMsg (store, params = {}) {
- let { rootState, state } = store
- let lastSession = rootState.curSession
- let msg
- // 然后再请求网上的数据,来渲染
- if (params.isPrivate) {
- msg = await API.person.getNewMsg({
- session_id: rootState.curSession,
- client_hash: state.endHash
- }).catch(() => {})
- } else {
- msg = await API.group.getNewMsg({
- group_id: state.groupId,
- client_hash: state.endHash
- }).catch(() => {})
- }
- // 若请求回来数据不在当前会话,则弃掉
- if (lastSession != rootState.curSession) return []
- if (msg && msg.data.code === 0 && msg.data.data.list.length > 0) {
- params.fromdb = false
- actions._renderMsg(store, msg.data.data, params)
- }
- return msg.data
- },
- /**
- * @des 获取历史消息【不需要登录】【群聊&私聊】
- * @param {Object} store
- * @param {Object} params
- */
- async commonGetHistoryMsg (store, params = {}) {
- let { commit, state, rootState } = store
- let his = localStorage.getItem(params.hash) // 先从本地缓存中获取记录
- let cacheData = {}
- let status = '' // 请求状态
- if (his && state.useCache) {
- cacheData = JSON.parse(his)
- } else {
- // 本地缓存中没有记录,从接口获取
- let msg
- if (params.isPrivate) {
- msg = await API.person
- .getHistoryMsg({
- session_id: rootState.curSession,
- client_hash: state.startHash
- })
- .catch(() => {})
- } else {
- 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) {
- cacheData = msg.data.data
- }
- }
- if (cacheData.list && cacheData.list.length > 0) {
- commit('setHash', {
- startHash: cacheData.list[0].hash
- })
- params.fromHistory = true
- this._renderMsg(store, cacheData, params)
- status = 'done'
- } else {
- commit('setHash', {
- startHash: null
- })
- status = 'end'
- }
- return status
- },
- /**
- * 发送消息【群聊&私聊】
- * @param {Object} data
- * @param {Object} params
- */
- commonDoSendMsg ({ dispatch, commit, state, rootState }, params = {}) {
- return new Promise(async (resolve, reject) => {
- let res
- if (params.isPrivate) {
- res = await API.person.sendMsg({
- session_id: rootState.curSession,
- msg_type: params.type,
- msg: params.msg
- })
- } else {
- res = await API.group.sendMsg({
- group_id: state.groupId,
- msg_type: params.type,
- msg: params.msg
- }).catch(err => {
- if (params.createTime) {
- dealErrorMsg(state, params.createTime)
- }
- reject(err)
- })
- }
- let data = res.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)
- }
- }
- })
- },
- /**
- * @des 消息渲染
- * @param {Boolean} params.isPrivate 是否私聊
- * @param {Boolean} params.fromdb 是否来自indexdb
- * @param {Boolean} params.fromHistory 是否来自历史记录
- */
- _renderMsg ({ commit, state, rootState }, data, params) {
- let list = []
- // 更新聊天userMap
- commit('setGroupMembers', Object.assign(data.userMap, state.members))
- // 解密数据&&计算头像信息
- let lastShowMsgUid = params.fromHistory ? 0 : (getUserOpt('lastShowMsgUid') || 0)
- data.list.forEach(n => {
- let member = state.members[n.from]
- if (!member) return
- // 退群消息只能显示给管理员/自己
- if (n.msg_type == 5 && n.ext_info && n.ext_info.event_type == 'leave_group') {
- if (rootState.userId != n.from && !state.adminList.some(item => item == rootState.userId)) {
- return
- }
- }
- // 解密数据
- if (n.msg_type == 4) {
- // 针对红包类型
- n.msg = typeof n.msg == 'string' ? JSON.parse(decryptoMsg(n.msg)) : n.msg
- } else {
- n.msg = decryptoMsg(n.msg)
- }
- // 显示信息
- list.push({
- name: member.nick_name || member.user_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
- })
- lastShowMsgUid = n.msg_type == 5 ? 0 : n.from
- })
- if (params.fromHistory) {
- // 历史记录
- commit('addHistoryList', list)
- } else {
- // 最新聊天
- setUserOpt('lastShowMsgUid', lastShowMsgUid)
- if (state.chatList.length) {
- commit('setHash', {
- endHash: list[list.length - 1] ? list[list.length - 1].hash : ''
- })
- } else {
- 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: params.fromdb } : { list: list, fromdb: params.fromdb }
- commit('addChatItem', itemData)
- }
- },
- /**
- * @des 群聊 获取最新消息【from indexeddb】
- * @param {Object} store
- * @param {Object} params
- */
- async getNewMsgFromDb (store, params = {}) {
- params.isPrivate = false
- return actions.commonGetNewMsgFromDb(store, params)
- },
- /**
- * @des 群聊 获取最新消息【不需要登录】
- * @param {Object} store
- * @param {Object} params
- */
- async getNewMsg (store, params = {}) {
- params.isPrivate = false
- return actions.commonGetNewMsg(store, params)
- },
- async getPrivateNewMsgFromDb (store, params = {}) {
- params.isPrivate = true
- return actions.commonGetNewMsgFromDb(store, params)
- },
- /**
- * @des 私聊 获取最新消息【不需要登录】
- * @param {Object} store
- * @param {Object} params
- */
- async getPrivateNewMsg (store, params = {}) {
- params.isPrivate = true
- return actions.commonGetNewMsg(store, params)
- },
- /**
- * @des 群聊 获取历史消息【不需要登录】
- * @param {Object} store
- * @param {Object} params
- */
- async getHistoryMsg (store, params = {}) {
- return actions.commonGetHistoryMsg(store, params)
- },
- /**
- * @des 私聊 获取历史消息【不需要登录】
- * @param {Object} store
- * @param {Object} params
- */
- async getPrivateHistoryMsg (store, params = {}) {
- params.isPrivate = true
- return actions.commonGetHistoryMsg(store, params)
- },
- /**
- * 发送群聊消息
- * @param {Object} data
- * @param {Object} params
- */
- doSendMsg (store, params = {}) {
- params.isPrivate = false
- return actions.commonDoSendMsg(store, params)
- },
- /**
- * 发送聊天文件
- * @param {Object} data
- * @param {Object} params
- */
- async doSendFile ({ 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 (store, params = {}) {
- params.isPrivate = true
- return actions.commonDoSendMsg(store, params)
- },
- /**
- * 链接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' && data.group_id == state.groupId) {
- if (data.user_info.user_id == rootState.userId) return // 本人-不走这个ws
- // 本人退出刷新群信息
- if (data.user_id == rootState.userId) {
- dispatch('getGroupInfo')
- } else {
- commit('updateMembersArray', {
- type: 'del',
- userInfo: data.user_info
- })
- }
- }
- if (data.type === 'join' && data.group_id == state.groupId) {
- 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' && data.group_id == state.groupId) {
- commit('updateGroupPinMsg', data.pinMsg)
- }
- if (data.type === 'unpin_msg' && data.group_id == state.groupId) {
- 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}
- */
- doRepealGroupMsg ({ dispatch, commit, state }, params = {}) {
- try {
- 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
|