im.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { SocketSession } from '@/store/services/socket-session'
  2. import appSettings from '@/core/config/app-settings'
  3. import { bindSocketClient, isLiveRoomPacket } from '@/features/im/socket-bind'
  4. import { setChat } from '@/common/chat-utils.js'
  5. let session = null
  6. function ensureSession(store) {
  7. if (session) return session
  8. session = new SocketSession({
  9. onOpen: () => {
  10. if (store.state && store.state.im) store.state.im.online = true
  11. setTimeout(() => {
  12. if (store.state && store.state.user && store.state.user.isLogin) {
  13. store.dispatch('im/fetchInbox').catch(() => {})
  14. }
  15. }, 300)
  16. setTimeout(() => {
  17. uni.$emit('im:connected')
  18. uni.$emit('websocket:connected')
  19. }, 500)
  20. },
  21. onMessage: (msg) => store.dispatch('im/dispatchPacket', msg),
  22. onClose: () => { if (store.state && store.state.im) store.state.im.online = false },
  23. onError: () => { if (store.state && store.state.im) store.state.im.online = false }
  24. })
  25. return session
  26. }
  27. export default {
  28. namespaced: true,
  29. state: {
  30. online: false,
  31. badge: 0,
  32. inbox: [],
  33. halted: false
  34. },
  35. mutations: {
  36. setBadge(state, n) {
  37. state.badge = n
  38. },
  39. setInbox(state, list) {
  40. state.inbox = list || []
  41. }
  42. },
  43. actions: {
  44. resume({ state }) {
  45. if (state.halted) {
  46. state.halted = false
  47. ensureSession(this).allowReconnect = true
  48. }
  49. ensureSession(this).open()
  50. },
  51. pause({ state }, permanent = false) {
  52. const sock = ensureSession(this)
  53. if (permanent) {
  54. state.halted = true
  55. sock.allowReconnect = false
  56. }
  57. sock.pause(!permanent)
  58. },
  59. async bindClient(_, clientId) {
  60. await bindSocketClient(clientId)
  61. },
  62. dispatchPacket({ dispatch, rootState }, message) {
  63. let packet
  64. try {
  65. packet = JSON.parse(message.data)
  66. } catch (_) {
  67. if (appSettings.debug) console.log('[im] non-json packet ignored')
  68. return
  69. }
  70. uni.$emit('im:packet', packet)
  71. switch (packet?.type) {
  72. case 'ping':
  73. ensureSession(this).send({ type: 'pong' })
  74. return
  75. case 'init':
  76. dispatch('bindClient', packet.client_id).catch(() => {})
  77. return
  78. case 'chat': {
  79. // 落本地缓存 + 更新会话列表(对齐 88live chat/onMessage)
  80. try {
  81. setChat(packet, 'receive')
  82. } catch (_) {}
  83. const form = packet.form || {}
  84. dispatch(
  85. 'chat/update',
  86. {
  87. type: 'chat',
  88. data: packet,
  89. shop: {
  90. id: form.shop_id,
  91. user_id: form.id,
  92. name: form.name,
  93. avatar: form.avatar
  94. }
  95. },
  96. { root: true }
  97. ).catch(() => {})
  98. uni.$emit('im:chat', packet)
  99. uni.$emit('onMessage', packet)
  100. return
  101. }
  102. case 'order':
  103. dispatch('chat/storage', { type: 'order' }, { root: true }).catch(() => {})
  104. uni.$emit('im:order', packet)
  105. return
  106. case 'notice':
  107. dispatch('chat/storage', { type: 'notice' }, { root: true }).catch(() => {})
  108. uni.$emit('im:notice', packet)
  109. return
  110. case 'service':
  111. uni.$emit('onService', packet)
  112. return
  113. case 'live':
  114. uni.$emit('onLiveMessage', packet)
  115. return
  116. case 'tip_done':
  117. case 'end':
  118. case 'gift':
  119. uni.$emit('onLiveMessage', packet)
  120. return
  121. default:
  122. break
  123. }
  124. if (isLiveRoomPacket(packet)) {
  125. uni.$emit('onLiveMessage', packet)
  126. }
  127. },
  128. async fetchInbox({ dispatch }) {
  129. await dispatch('chat/get', null, { root: true })
  130. }
  131. }
  132. }