useIM.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. import { ref, onMounted, onUnmounted, watch } from 'vue';
  2. import { getConversationSync, getMessageSync, getChatKey } from '@/api/common'
  3. import { Base64 } from 'js-base64'
  4. import { useUserStore } from '@/store/user'
  5. import { useLoginType } from '@/store/loginType'
  6. import { useIMStore } from '@/store/im'
  7. // 配置悟空IM
  8. import {
  9. MessageText,
  10. Channel,
  11. WKSDK,
  12. ChannelTypePerson,
  13. // Conversation,
  14. // Message, StreamItem, ChannelTypeGroup, MessageStatus, SyncOptions, MessageExtra, MessageContent
  15. } from "wukongimjssdk"
  16. const HISTORY_QUERY = {
  17. limit: 30,
  18. startMessageSeq: 0,
  19. endMessageSeq: 0,
  20. pullMode: 1
  21. }
  22. const ConnectStatus = {
  23. Disconnect: 0, // 断开连接
  24. Connected: 1, // 连接成功
  25. Connecting: 2, // 连接中
  26. ConnectFail: 3, // 连接错误
  27. ConnectKick: 4, // 连接被踢,服务器要求客户端断开(一般是账号在其他地方登录,被踢)
  28. }
  29. // api 接入
  30. export function useDataSource () {
  31. const userStore = useUserStore()
  32. const loginType = useLoginType()
  33. // 最近会话数据源
  34. if (!WKSDK.shared().config.provider.syncConversationsCallback) {
  35. WKSDK.shared().config.provider.syncConversationsCallback = async () => {
  36. const query = {
  37. msg_count: 100
  38. }
  39. if (loginType.loginType === 'enterprise') {
  40. Object.assign(query, { enterpriseId: userStore.baseInfo.enterpriseId })
  41. }
  42. const resultConversations = []
  43. const resp = await getConversationSync(query)
  44. // console.log(resp)
  45. const conversationList = resp
  46. if (conversationList) {
  47. conversationList.forEach(conversation => {
  48. conversation.channel = new Channel(conversation.channel_id, conversation.channel_type)
  49. conversation.unread = +(conversation.unread || 0)
  50. resultConversations.push(conversation)
  51. })
  52. }
  53. return resultConversations
  54. }
  55. }
  56. if (!WKSDK.shared().config.provider.syncMessagesCallback) {
  57. // 同步频道消息数据源
  58. WKSDK.shared().config.provider.syncMessagesCallback = async function(channel) {
  59. // 后端提供的获取频道消息列表的接口数据 然后构建成 Message对象数组返回
  60. let resultMessages = new Array()
  61. const {
  62. startMessageSeq: start_message_seq,
  63. endMessageSeq: end_message_seq,
  64. limit,
  65. pullMode: pull_mode
  66. } = HISTORY_QUERY
  67. const query = {
  68. channel_id: channel.channelID,
  69. channel_type: channel.channelType,
  70. start_message_seq,
  71. end_message_seq,
  72. limit,
  73. pull_mode,
  74. }
  75. if (loginType.loginType === 'enterprise') {
  76. Object.assign(query, { enterpriseId: userStore.baseInfo.enterpriseId })
  77. }
  78. const resp = await getMessageSync(query)
  79. const messageList = resp && resp["messages"]
  80. if (messageList) {
  81. messageList.forEach((msg) => {
  82. // const message = Convert.toMessage(msg);
  83. // msg.channel = new Channel(msg.channel_id, msg.channel_type)
  84. msg.payload = JSON.parse(Base64.decode(msg.payload))
  85. resultMessages.push(msg);
  86. });
  87. }
  88. const more = resp.more === 1
  89. return {
  90. more,
  91. resultMessages
  92. }
  93. }
  94. }
  95. }
  96. // function toConversation (conversationMap) {
  97. // const conversation = new Conversation()
  98. // conversation.channel = new Channel(conversationMap['channel_id'], conversationMap['channel_type'])
  99. // conversation.unread = conversationMap['unread'] || 0;
  100. // conversation.timestamp = conversationMap['timestamp'] || 0;
  101. // // let recents = conversationMap["recents"];
  102. // // if (recents && recents.length > 0) {
  103. // // const messageModel = toMessage(recents[0]);
  104. // // conversation.lastMessage = messageModel
  105. // // }
  106. // conversation.extra = {}
  107. // return conversation
  108. // }
  109. // function toMessage(msgMap) {
  110. // const message = new Message();
  111. // if (msgMap['message_idstr']) {
  112. // message.messageID = msgMap['message_idstr'];
  113. // }
  114. // // else {
  115. // // message.messageID = new BigNumber(msgMap['message_id']).toString();
  116. // // }
  117. // if (msgMap["header"]) {
  118. // message.header.reddot = msgMap["header"]["red_dot"] === 1 ? true : false
  119. // }
  120. // // if (msgMap["setting"]) {
  121. // // message.setting = Setting.fromUint8(msgMap["setting"])
  122. // // }
  123. // if (msgMap["revoke"]) {
  124. // message.remoteExtra.revoke = msgMap["revoke"] === 1 ? true : false
  125. // }
  126. // if(msgMap["message_extra"]) {
  127. // const messageExtra = msgMap["message_extra"]
  128. // message.remoteExtra = this.toMessageExtra(messageExtra)
  129. // }
  130. // message.clientSeq = msgMap["client_seq"]
  131. // message.channel = new Channel(msgMap['channel_id'], msgMap['channel_type']);
  132. // message.messageSeq = msgMap["message_seq"]
  133. // message.clientMsgNo = msgMap["client_msg_no"]
  134. // message.streamNo = msgMap["stream_no"]
  135. // message.streamFlag = msgMap["stream_flag"]
  136. // message.fromUID = msgMap["from_uid"]
  137. // message.timestamp = msgMap["timestamp"]
  138. // message.status = MessageStatus.Normal
  139. // const contentObj = JSON.parse(Base64.decode(msgMap["payload"]))
  140. // // const contentObj = JSON.parse(decodedBuffer.toString('utf8'))
  141. // let contentType = 0
  142. // if (contentObj) {
  143. // contentType = contentObj.type
  144. // }
  145. // const messageContent = WKSDK.shared().getMessageContent(contentType)
  146. // if (contentObj) {
  147. // messageContent.decode(this.stringToUint8Array(JSON.stringify(contentObj)))
  148. // }
  149. // message.content = messageContent
  150. // message.isDeleted = msgMap["is_deleted"] === 1
  151. // const streamMaps = msgMap["streams"]
  152. // if(streamMaps && streamMaps.length>0) {
  153. // const streams = []
  154. // for (const streamMap of streamMaps) {
  155. // const streamItem = new StreamItem()
  156. // streamItem.clientMsgNo = streamMap["client_msg_no"]
  157. // streamItem.streamSeq = streamMap["stream_seq"]
  158. // streams.push(streamItem)
  159. // }
  160. // message.streams = streams
  161. // }
  162. // return message
  163. // }
  164. async function getKey () {
  165. const userStore = useUserStore()
  166. const loginType = useLoginType()
  167. const keyQuery = {
  168. userId: userStore.userInfo.id
  169. }
  170. if (loginType.loginType === 'enterprise') {
  171. Object.assign(keyQuery, { enterpriseId: userStore.baseInfo.enterpriseId })
  172. }
  173. const { uid, wsUrl, token } = await getChatKey(keyQuery)
  174. return {
  175. uid, wsUrl, token
  176. }
  177. }
  178. export const useIM = async () => {
  179. const IM = useIMStore()
  180. const unreadCount = ref(0)
  181. const connected = ref(0)
  182. // 通过自身userId和企业id获取token和uid
  183. const { uid, wsUrl, token } = await getKey()
  184. IM.setUid(uid)
  185. // 单机模式可以直接设置地址
  186. WKSDK.shared().config.addr = 'ws://' + wsUrl // 默认端口为5200
  187. // 认证信息
  188. WKSDK.shared().config.uid = uid // 用户uid(需要在悟空通讯端注册过)
  189. WKSDK.shared().config.token = token // 用户token (需要在悟空通讯端注册过)
  190. // onMounted(() => {
  191. // console.log('1')
  192. // 连接状态监听
  193. WKSDK.shared().connectManager.addConnectStatusListener(connectStatusListener)
  194. // console.log('2')
  195. // 常规消息监听
  196. WKSDK.shared().chatManager.addMessageListener(messageListen)
  197. // 连接
  198. // console.log('连接')
  199. WKSDK.shared().connectManager.connect()
  200. // })
  201. onUnmounted(() => {
  202. WKSDK.shared().connectManager.removeConnectStatusListener(connectStatusListener)
  203. // 常规消息监听移除
  204. WKSDK.shared().chatManager.removeMessageListener(messageListen)
  205. // 连接状态监听移除
  206. WKSDK.shared().connectManager.disconnect()
  207. })
  208. async function messageListen (message) {
  209. console.log('收到消息', message)
  210. IM.setFromChannel(message.channel.channelID)
  211. const count = WKSDK.shared().conversationManager.getAllUnreadCount()
  212. IM.setNewMsg(count)
  213. unreadCount.value = count
  214. // console.log('未读消息数', count)
  215. // 创建通道
  216. }
  217. async function connectStatusListener (status) {
  218. // console.log('连接状态', status === ConnectStatus.Connected)
  219. connected.value = status === ConnectStatus.Connected
  220. }
  221. return {
  222. unreadCount,
  223. connected
  224. }
  225. }
  226. export function initConnect (callback = () => {}) {
  227. const IM = useIMStore()
  228. const conversationList = ref([])
  229. const messageItems = ref([])
  230. watch(
  231. () => IM.newMsg,
  232. () => {
  233. // 未读消息变化
  234. syncConversation()
  235. // 拉取最新消息 查看是否是自己的数据
  236. },
  237. {
  238. deep: true,
  239. immediate: true
  240. }
  241. )
  242. onMounted(async () => {
  243. // 消息发送状态监听
  244. WKSDK.shared().chatManager.addMessageStatusListener(statusListen)
  245. // 常规消息监听
  246. // WKSDK.shared().chatManager.addMessageListener(messageListen)
  247. })
  248. onUnmounted(() => {
  249. // 消息发送状态监听移除
  250. WKSDK.shared().chatManager.removeMessageStatusListener(statusListen)
  251. // 常规消息监听移除
  252. // WKSDK.shared().chatManager.removeMessageListener(messageListen)
  253. })
  254. // 消息发送状态监听
  255. function statusListen (packet) {
  256. if (packet.reasonCode === 1) {
  257. // 发送成功
  258. console.log('发送成功')
  259. // 添加一组成功数据
  260. callback()
  261. } else {
  262. // 发送失败
  263. console.log('发送失败')
  264. // 添加一组失败数据
  265. // callback()
  266. }
  267. }
  268. // 常规消息监听
  269. // async function messageListen (message) {
  270. // console.log('收到消息', message)
  271. // syncConversation()
  272. // }
  273. // 同步最近会话
  274. async function syncConversation () {
  275. const res = await WKSDK.shared().conversationManager.sync()
  276. conversationList.value = res
  277. return res
  278. // return new Promise((resolve, reject) => {
  279. // WKSDK.shared().conversationManager.sync().then(res => {
  280. // conversationList.value = res
  281. // resolve(res)
  282. // }).catch(error => {
  283. // reject(error)
  284. // })
  285. // })
  286. }
  287. return {
  288. // connected,
  289. conversationList,
  290. messageItems,
  291. // channel
  292. }
  293. }
  294. // export async function getRecentMessages (channel) {
  295. // const { resultMessages, more } = await WKSDK.shared().chatManager.syncMessages(channel, HISTORY_QUERY)
  296. // // console.log(res)
  297. // // return resultMessages.map(_e => {
  298. // // _e.payload = JSON.parse(Base64.decode(_e.payload))
  299. // // return _e
  300. // // })
  301. // }
  302. // 发起聊天
  303. export async function initChart (userId, enterpriseId) {
  304. const channel = ref()
  305. // const list = ref([])
  306. const query = {
  307. userId,
  308. enterpriseId
  309. }
  310. // 创建聊天频道
  311. const { uid } = await getChatKey(query)
  312. const _channel = new Channel(uid, ChannelTypePerson)
  313. channel.value = _channel
  314. const conversation = WKSDK.shared().conversationManager.findConversation(_channel)
  315. if(!conversation) {
  316. // 如果最近会话不存在,则创建一个空的会话
  317. WKSDK.shared().conversationManager.createEmptyConversation(_channel)
  318. }
  319. const res = await getMoreMessages(1, _channel)
  320. return {
  321. channel,
  322. ...res
  323. }
  324. }
  325. // 翻页
  326. export async function getMoreMessages (pageSize, channel) {
  327. const list = ref([])
  328. Object.assign(HISTORY_QUERY, {
  329. startMessageSeq: (pageSize - 1) * HISTORY_QUERY.limit
  330. })
  331. const { resultMessages, more } = await WKSDK.shared().chatManager.syncMessages(channel)
  332. list.value = resultMessages
  333. return {
  334. list,
  335. more
  336. }
  337. }
  338. export function send (text, _channel) {
  339. const _text = new MessageText(text) // 文本消息
  340. console.log('发送', _text, _channel)
  341. WKSDK.shared().chatManager.send(_text, _channel)
  342. }