actions.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. import API from '@/api'
  2. import { getWsUrl } from '@/util/contract.js'
  3. import WsManager from '@/util/wsManager.js'
  4. import {
  5. decryptoMsg,
  6. dealErrorMsg,
  7. noticeManager
  8. } from '@/util/util.js'
  9. import axios from 'axios'
  10. import Message from '@/store/db/Message.js'
  11. var socket = null
  12. const actions = {
  13. /**
  14. * @des 获取群基础信息
  15. * @param {Object} store
  16. * @param {Object} params
  17. */
  18. async getGroupInfo ({ dispatch, commit, state }, params) {
  19. API.group.getGroupInfo2({ group_id: state.groupId }, info => {
  20. if (info.data.code === 0) {
  21. let adminList = info.data.data.adminList
  22. let blockList = info.data.data.blockList
  23. let pinMsg = info.data.data.pinMsg
  24. let group = info.data.data.group
  25. let members = info.data.data.members
  26. let membersNum = info.data.data.group.member_num
  27. let userInfo = info.data.data.userInfo
  28. let sessionInfo = info.data.data.sessionInfo
  29. let isJoin = !!info.data.data.sessionInfo
  30. let eosInfo = info.data.data.eosInfo
  31. pinMsg && (pinMsg.visible = true)
  32. let _members = {}
  33. members.forEach(n => {
  34. _members[n.user_id] = n
  35. })
  36. commit('setGroupInfo', {
  37. userCounts: members.length,
  38. groupName: group.group_title,
  39. shareName: group.group_name,
  40. members: _members,
  41. membersArray: members,
  42. membersNum: membersNum,
  43. userInfo,
  44. groupNotice: group.group_notice,
  45. inviteUrl: group.invite_url,
  46. sessionInfo,
  47. isJoin,
  48. coverPhoto: group.cover_photo,
  49. adminList: adminList,
  50. blockList: blockList,
  51. pinMsg: pinMsg,
  52. creator: group.creator,
  53. eosInfo: eosInfo
  54. })
  55. }
  56. })
  57. },
  58. /**
  59. * @des 群聊 获取最新消息【不需要登录】
  60. * @param {Object} store
  61. * @param {Object} params
  62. */
  63. async getNewMsg (store, params = {}) {
  64. // 先读取indexDB的数据,来渲染
  65. let { state } = store
  66. const objMessage = new Message()
  67. let data = await objMessage.getMsg(state.groupId)
  68. if (data.list.length > 0) {
  69. actions._renderGroupMsg(store, data, params)
  70. }
  71. // 然后再请求网上的数据,来渲染
  72. let msg = await API.group.getNewMsg({
  73. group_id: state.groupId,
  74. client_hash: state.endHash
  75. }).catch(() => {})
  76. if (msg.data.code === 0 && msg.data.data.list.length > 0) {
  77. actions._renderGroupMsg(store, msg.data.data, params)
  78. }
  79. return 'done'
  80. },
  81. _renderGroupMsg ({ dispatch, commit, state }, data, params) {
  82. let list = []
  83. data.list.forEach(n => {
  84. let member = data.userMap[n.from]
  85. if (!member) return
  86. list.push({
  87. name: member ? member.nick_name : 'unknown',
  88. content: n.msg,
  89. userId: n.from,
  90. timestamp: n.create_time_int,
  91. avatar: member ? member.cover_photo : '',
  92. hash: n.hash,
  93. type: n.from == state.userId ? 'me' : 'you',
  94. msg_type: n.msg_type,
  95. ext: n.ext ? n.ext : null
  96. })
  97. })
  98. commit('updateMembers', data.userMap)
  99. if (state.chatList.length) {
  100. commit('setHash', {
  101. endHash: list[list.length - 1].hash
  102. })
  103. } else {
  104. commit('setHash', {
  105. endHash: list[list.length - 1].hash,
  106. startHash: list[0].hash
  107. })
  108. }
  109. let itemData = params.newMsg ? { list: list, newMsg: params.newMsg } : list
  110. commit('addChatItem', itemData)
  111. },
  112. /**
  113. * @des 私聊 获取最新消息【不需要登录】
  114. * @param {Object} store
  115. * @param {Object} params
  116. */
  117. async getPrivateNewMsg (store, params = {}) {
  118. let { state, rootState } = store
  119. const objMessage = new Message()
  120. let data = await objMessage.getMsg(rootState.curSession)
  121. if (data.list.length > 0) {
  122. actions._renderPrivateMsg(store, data, params)
  123. }
  124. let msg = await API.person.getNewMsg({
  125. session_id: rootState.curSession,
  126. client_hash: state.endHash
  127. }).catch(() => {})
  128. // 有聊天记录
  129. if (msg.data.code === 0 && msg.data.data.list.length > 0) {
  130. actions._renderPrivateMsg(store, msg.data.data, params)
  131. }
  132. return 'done'
  133. },
  134. _renderPrivateMsg ({ dispatch, commit, state, rootState }, data, params) {
  135. let list = []
  136. // 更新members信息
  137. let members = data.userMap
  138. commit('updateGroup', {
  139. key: 'members',
  140. data: members
  141. })
  142. for (let k in members) {
  143. if (k !== rootState.userId) {
  144. commit('updateGroup', {
  145. key: 'privateName',
  146. data: members[k]['nick_name']
  147. })
  148. }
  149. }
  150. data.list.forEach(n => {
  151. let member = data.userMap[n.from]
  152. list.push({
  153. name: member ? member.nick_name : 'unknown',
  154. content: n.msg,
  155. userId: n.from,
  156. timestamp: n.create_time_int,
  157. avatar: member.cover_photo || '',
  158. hash: n.hash,
  159. type: n.from == rootState.userId ? 'me' : 'you',
  160. msg_type: n.msg_type,
  161. ext: n.ext ? n.ext : null
  162. })
  163. })
  164. if (state.chatList.length) {
  165. commit('setHash', {
  166. endHash: list[list.length - 1].hash
  167. })
  168. } else {
  169. commit('setHash', {
  170. endHash: list[list.length - 1].hash,
  171. startHash: list[0].hash
  172. })
  173. }
  174. let itemData = params.newMsg ? { list: list, newMsg: params.newMsg } : list
  175. commit('addChatItem', itemData)
  176. },
  177. /**
  178. * @des 群聊 获取历史消息【不需要登录】
  179. * @param {Object} store
  180. * @param {Object} params
  181. */
  182. async getHistoryMsg ({ dispatch, commit, state }, params = {}) {
  183. let his = localStorage.getItem(params.hash) // 先从本地缓存中获取记录
  184. let dList = []
  185. let status = '' // 请求状态
  186. if (his && state.useCache) {
  187. dList = JSON.parse(his)
  188. } else {
  189. // 本地缓存中没有记录,从接口获取
  190. let msg = await API.group
  191. .getHistoryMsg({
  192. group_id: state.groupId,
  193. client_hash: state.startHash
  194. })
  195. .catch(() => {})
  196. if (msg && msg.data.code === 0 && msg.data.data.list.length > 0) {
  197. // 重新格式数据
  198. msg.data.data.list.forEach(n => {
  199. if (n.msg_type == 4) {
  200. n.msg = JSON.parse(decryptoMsg(n.msg))
  201. } else {
  202. n.msg = decryptoMsg(n.msg)
  203. }
  204. let member = msg.data.data.userMap[n.from]
  205. commit('updateMembers', msg.data.data.userMap)
  206. if (!member) return
  207. dList.push({
  208. name: member ? member.nick_name : 'unknown',
  209. content: n.msg,
  210. userId: n.from,
  211. timestamp: n.create_time_int,
  212. avatar: member ? member.cover_photo : '',
  213. hash: n.hash,
  214. type: n.from == state.userId ? 'me' : 'you',
  215. msg_type: n.msg_type,
  216. ext: n.ext ? n.ext : null
  217. })
  218. })
  219. // 保存到本地缓存中
  220. if (state.useCache) {
  221. localStorage.setItem(params.hash, JSON.stringify(dList))
  222. }
  223. }
  224. }
  225. if (dList.length > 0) {
  226. commit('setHash', {
  227. startHash: dList[0].hash
  228. })
  229. commit('addHistoryList', dList)
  230. status = 'done'
  231. } else {
  232. commit('setHash', {
  233. startHash: null
  234. })
  235. status = 'end'
  236. }
  237. return status
  238. },
  239. /**
  240. * @des 私聊 获取历史消息【不需要登录】
  241. * @param {Object} store
  242. * @param {Object} params
  243. */
  244. async getPrivateHistoryMsg (
  245. { dispatch, commit, state, rootState },
  246. params = {}
  247. ) {
  248. let his = localStorage.getItem(params.hash) // 先从本地缓存中获取记录
  249. let dList = []
  250. let status = '' // 请求状态
  251. if (his && state.useCache) {
  252. dList = JSON.parse(his)
  253. } else {
  254. // 本地缓存中没有记录,从接口获取
  255. let msg = await API.person
  256. .getHistoryMsg({
  257. session_id: rootState.curSession,
  258. client_hash: state.startHash
  259. })
  260. .catch(() => {})
  261. if (msg.data.code === 0 && msg.data.data.list.length > 0) {
  262. // 重新格式数据
  263. msg.data.data.list.forEach(n => {
  264. n.msg = decryptoMsg(n.msg)
  265. let member = msg.data.data.userMap[n.from]
  266. dList.push({
  267. name: member ? member.nick_name : 'unknow',
  268. content: n.msg,
  269. userId: n.from,
  270. timestamp: n.create_time_int,
  271. avatar: member.cover_photo || '',
  272. hash: n.hash,
  273. type: n.from == rootState.userId ? 'me' : 'you',
  274. msg_type: n.msg_type,
  275. ext: n.ext ? n.ext : null
  276. })
  277. })
  278. // 保存到本地缓存中
  279. if (state.useCache) {
  280. localStorage.setItem(params.hash, JSON.stringify(dList))
  281. }
  282. }
  283. }
  284. if (dList.length > 0) {
  285. commit('setHash', {
  286. startHash: dList[0].hash
  287. })
  288. commit('addHistoryList', dList)
  289. status = 'done'
  290. } else {
  291. commit('setHash', {
  292. startHash: null
  293. })
  294. status = 'end'
  295. }
  296. return status
  297. },
  298. /**
  299. * 发送群聊消息
  300. * @param {Object} data
  301. * @param {Object} params
  302. */
  303. doSendMsg ({ dispatch, commit, state }, params = {}) {
  304. return new Promise((resolve, reject) => {
  305. API.group
  306. .sendMsg({
  307. group_id: state.groupId,
  308. msg_type: params.type,
  309. msg: params.msg
  310. })
  311. .then(({ data }) => {
  312. if (data.code === 0) {
  313. if (params.createTime) {
  314. let createTime = params.createTime
  315. data.data.content = decryptoMsg(data.data.content)
  316. let list = state.chatList
  317. for (let i = list.length - 1; i >= 0; i--) {
  318. let listItem = list[i]
  319. if (listItem.createTime === createTime) {
  320. listItem.hash = data.data.hash
  321. listItem.loading = false
  322. }
  323. }
  324. } else {
  325. // 针对用户第一次发言
  326. commit('updateMembers', data.data.userMap)
  327. data.data.content = decryptoMsg(data.data.content)
  328. commit('addChatItem', data.data)
  329. }
  330. commit('setHash', {
  331. endHash: data.data.hash
  332. })
  333. resolve(data.data)
  334. } else {
  335. if (params.createTime) {
  336. dealErrorMsg(state, params.createTime)
  337. }
  338. }
  339. })
  340. .catch(err => {
  341. if (params.createTime) {
  342. dealErrorMsg(state, params.createTime)
  343. }
  344. reject(err)
  345. })
  346. })
  347. },
  348. /**
  349. * 发送聊天文件
  350. * @param {Object} data
  351. * @param {Object} params
  352. */
  353. async doSendFile ({ dispatch, commit, state, rootState }, params = {}) {
  354. return new Promise((resolve, reject) => {
  355. let userId = rootState.userId
  356. let token = rootState.token
  357. let formData = new FormData()
  358. formData.append('group_id', state.groupId)
  359. formData.append('res', params.res)
  360. formData.append('user_id', userId)
  361. formData.append('token', token)
  362. axios({
  363. url: API.host + 'group/sendFile',
  364. method: 'post',
  365. data: formData,
  366. headers: { 'Content-Type': 'multipart/form-data' }
  367. })
  368. .then(({ data }) => {
  369. if (data.code === 0) {
  370. if (params.createTime) {
  371. let createTime = params.createTime
  372. data.data.content = decryptoMsg(data.data.content)
  373. let list = state.chatList
  374. list.forEach(item => {
  375. if (item.createTime === createTime) {
  376. item.res = undefined
  377. item.content = data.data.content
  378. item.hash = data.data.hash
  379. item.loading = false
  380. item.fail = false
  381. }
  382. })
  383. } else {
  384. // 针对用户第一次发言
  385. commit('updateMembers', data.data.userMap)
  386. data.data.content = decryptoMsg(data.data.content)
  387. commit('addChatItem', data.data)
  388. }
  389. commit('setHash', {
  390. endHash: data.data.hash
  391. })
  392. resolve(data.data)
  393. } else {
  394. if (params.createTime) {
  395. dealErrorMsg(state, params.createTime)
  396. }
  397. }
  398. })
  399. .catch(err => {
  400. if (params.createTime) {
  401. dealErrorMsg(state, params.createTime)
  402. }
  403. reject(err)
  404. })
  405. })
  406. },
  407. /**
  408. * 发送私聊消息
  409. * @param {Object} data
  410. * @param {Object} params
  411. */
  412. doSendPrivateMsg ({ dispatch, commit, state, rootState }, params = {}) {
  413. return new Promise((resolve, reject) => {
  414. API.person
  415. .sendMsg({
  416. session_id: rootState.curSession,
  417. msg_type: params.type,
  418. msg: params.msg
  419. })
  420. .then(({ data }) => {
  421. if (data.code === 0) {
  422. if (params.createTime) {
  423. let createTime = params.createTime
  424. data.data.content = decryptoMsg(data.data.content)
  425. let list = state.chatList
  426. for (let i = list.length - 1; i >= 0; i--) {
  427. let listItem = list[i]
  428. if (listItem.createTime === createTime) {
  429. listItem.hash = data.data.hash
  430. listItem.loading = false
  431. }
  432. }
  433. } else {
  434. // 针对用户第一次发言
  435. commit('updateMembers', data.data.userMap)
  436. data.data.content = decryptoMsg(data.data.content)
  437. commit('addChatItem', data.data)
  438. }
  439. commit('setHash', {
  440. endHash: data.data.hash
  441. })
  442. resolve(data.data)
  443. } else {
  444. if (params.createTime) {
  445. dealErrorMsg(state, params.createTime)
  446. }
  447. }
  448. })
  449. .catch(err => {
  450. if (params.createTime) {
  451. dealErrorMsg(state, params.createTime)
  452. }
  453. reject(err)
  454. })
  455. })
  456. },
  457. /**
  458. * 链接websocket
  459. * @param {Object} data
  460. * @param {Object} params
  461. */
  462. initSocket ({ commit, state, rootState, rootGetters, dispatch }, params = {}) {
  463. if (!window.WebSocket) {
  464. console.error('Error: WebSocket is not supported .')
  465. return
  466. }
  467. let host = `${getWsUrl()}/?user_id=${rootState.userId}&token=${
  468. rootState.token
  469. }`
  470. if (socket) {
  471. socket.destroy()
  472. socket = null
  473. }
  474. socket = new WsManager(host, {
  475. autoConnect: true, // 自动连接
  476. reconnection: true, // 断开自动重连
  477. reconnectionDelay: 5000, // 重连间隔时间,单位秒
  478. keepAliveContent: JSON.stringify({ act: 'alive', player: name }) // 心跳包内容
  479. })
  480. socket.on('open', res => {})
  481. socket.on('message', e => {
  482. let _data = JSON.parse(e)
  483. let channel = _data.channel
  484. let data = _data.data
  485. let muteList = rootGetters.muteList // 免打扰列表
  486. // 群聊
  487. if (channel.match('chat:group')) {
  488. let isMute = muteList.some(v => {
  489. return v.session_id == data.group_id
  490. })
  491. if (data.type === 'msg' && data.from !== rootState.userId) {
  492. // 用户打开当前群
  493. if (rootState.curSession === data.group_id) {
  494. dispatch('getNewMsg', { newMsg: true })
  495. commit('addUnreadNums')
  496. noticeManager.changeTitle()
  497. } else {
  498. if (!isMute) {
  499. noticeManager.showNotification(data)
  500. noticeManager.changeTitle()
  501. }
  502. }
  503. }
  504. if (data.type === 'leave') {
  505. }
  506. if (data.type === 'update') {
  507. }
  508. if (data.type === 'add_admin') {
  509. }
  510. if (data.type === 'remove_admin') {
  511. }
  512. if (data.type === 'repeal') {
  513. commit('repealChatItem', data)
  514. }
  515. if (data.type === 'block') {
  516. commit('updateGroupBlockList', {
  517. type: 'add',
  518. id: data.to
  519. })
  520. }
  521. if (data.type === 'unblock') {
  522. commit('updateGroupBlockList', {
  523. type: 'delete',
  524. id: data.to
  525. })
  526. }
  527. if (data.type === 'join') {
  528. commit('updateMembers', data.user_info)
  529. }
  530. if (data.type === 'pin_msg') {
  531. commit('updateGroupPinMsg', data.pinMsg)
  532. }
  533. if (data.type === 'unpin_msg') {
  534. commit('updateGroupPinMsg', null)
  535. }
  536. if (data.type === 'new_redpack' && rootState.curSession == data.group_id) {
  537. commit('addPacketItem', data)
  538. }
  539. if (data.type === 'grab_redpack' && rootState.curSession == data.group_id) {
  540. if (data.from == rootState.userId || data.to == rootState.userId) {
  541. commit('addPacketTip', data)
  542. }
  543. }
  544. }
  545. // 私聊
  546. if (channel.match('chat:person')) {
  547. if (!rootState.curSession) return
  548. let curId = +data.to > +data.from ? `${data.from}-${data.to}` : `${data.to}-${data.from}`
  549. let isMute = muteList.some(v => {
  550. return v.session_id == curId
  551. })
  552. if (data.type === 'msg') {
  553. // 用户打开当前聊天
  554. if (rootGetters.otherUserId == data.from) {
  555. dispatch('getPrivateNewMsg')
  556. commit('addUnreadNums')
  557. noticeManager.changeTitle()
  558. } else {
  559. if (!isMute) {
  560. noticeManager.showNotification(data)
  561. noticeManager.changeTitle()
  562. }
  563. }
  564. }
  565. if (data.type === 'repeal') {
  566. commit('repealChatItem', data.data)
  567. }
  568. if (data.type === 'new_redpack' && rootGetters.otherUserId == data.from) {
  569. commit('addPacketItem', data)
  570. }
  571. if (data.type === 'grab_redpack' && rootGetters.otherUserId == data.from) {
  572. if (data.from == rootState.userId || data.to == rootState.userId) {
  573. commit('addPacketTip', data)
  574. }
  575. }
  576. }
  577. // 有新session 更新sessionList
  578. if (data.type === 'msg' || data.type === 'new_redpack') {
  579. let sessionList = rootState.chat.sessionList
  580. let curId
  581. let content = data.content
  582. if (data.group_id) {
  583. curId = data.group_id
  584. } else {
  585. curId = +data.to > +data.from ? `${data.from}-${data.to}` : `${data.to}-${data.from}`
  586. }
  587. let isInSession = sessionList.some(v => {
  588. return v.session_id == curId
  589. })
  590. if (!isInSession) {
  591. if (!data.group_id) {
  592. API.user.getOtherInfo({
  593. target_id: data.from
  594. }).then(({ data }) => {
  595. let obj = {
  596. cover_photo: data.data.cover_photo,
  597. is_group: '0',
  598. name: data.data.nick_name,
  599. session_id: curId,
  600. unread: 1,
  601. content: content
  602. }
  603. commit('addSessionItem', obj)
  604. })
  605. } else {
  606. API.group.getGroupInfo({
  607. group_id: data.group_id
  608. }).then(({ data }) => {
  609. let group = data.data.group
  610. let obj = {
  611. cover_photo: group.cover_photo,
  612. is_group: '1',
  613. name: group.group_name,
  614. session_id: curId,
  615. unread: 1,
  616. content: content
  617. }
  618. commit('addSessionItem', obj)
  619. })
  620. }
  621. }
  622. commit('setSessionItemUnread', {
  623. unread: 1,
  624. cont: decryptoMsg(content),
  625. session_id: curId,
  626. curSession: rootState.curSession
  627. })
  628. }
  629. })
  630. },
  631. /**
  632. * 撤回消息
  633. * @param {Object} params
  634. * {index:number, session_id:string, hash:string}
  635. */
  636. async doRepealGroupMsg ({ dispatch, commit, state }, params = {}) {
  637. try {
  638. await API.group.repealGroupMsg({
  639. group_id: state.groupId,
  640. hash: params.hash
  641. })
  642. } catch (error) {}
  643. },
  644. /**
  645. * 封禁群用户
  646. */
  647. async doBlockUser ({ state }, params = {}) {
  648. try {
  649. await API.group.blockUser({
  650. group_id: state.groupId,
  651. block_id: params.id
  652. })
  653. } catch (error) {}
  654. },
  655. /**
  656. * 解禁用户
  657. */
  658. async doUnBlockUser ({ state }, params = {}) {
  659. try {
  660. await API.group.unblockUser({
  661. group_id: state.groupId,
  662. block_id: params.id
  663. })
  664. } catch (error) {}
  665. },
  666. /**
  667. * 更新置顶
  668. */
  669. async doPinMsg ({ state }, params = {}) {
  670. try {
  671. await API.group.pinMsg({
  672. group_id: state.groupId,
  673. hash: params.hash
  674. })
  675. } catch (error) {}
  676. },
  677. /**
  678. * 取消置顶
  679. */
  680. async doUnpinMsg ({ state }, params = {}) {
  681. try {
  682. await API.group.unpinMsg({
  683. group_id: state.groupId,
  684. hash: params.hash
  685. })
  686. } catch (error) {}
  687. },
  688. /**
  689. * 加入群组
  690. */
  691. async joinGroup ({ state, commit }, params = {}) {
  692. try {
  693. await API.group.joinGroup({
  694. group_id: state.groupId
  695. })
  696. commit('updateJoin', true)
  697. } catch (error) {}
  698. }
  699. }
  700. export default actions