import { ref, onMounted, onUnmounted, watch } from 'vue'; import { getConversationSync, getMessageSync, getChatKey, setUnread, deleteConversation } from '@/api/common' import { Base64 } from 'js-base64' import { useUserStore } from '@/store/user' import { useLoginType } from '@/store/loginType' import { useIMStore } from '@/store/im' // 配置悟空IM import { MessageText, Channel, WKSDK, ChannelTypePerson, // Conversation, MessageContent, // Message, StreamItem, ChannelTypeGroup, MessageStatus, SyncOptions, MessageExtra, MessageContent } from "wukongimjssdk" // 注册消息体 class ObjectContent extends MessageContent { constructor(text) { super(); this.content = text; } get conversationDigest() { // 这里需要实现具体的逻辑 return this.content } get contentType() { // 这里需要实现具体的逻辑 return 101; // 示例实现 } decodeJSON(content) { this.content = content.text; } encodeJSON() { return { content: this.content }; } } // 注册101类型为面试 WKSDK.shared().register(101, () => new ObjectContent()) const HISTORY_QUERY = { limit: 30, startMessageSeq: 0, endMessageSeq: 0, pullMode: 1 } const ConnectStatus = { Disconnect: 0, // 断开连接 Connected: 1, // 连接成功 Connecting: 2, // 连接中 ConnectFail: 3, // 连接错误 ConnectKick: 4, // 连接被踢,服务器要求客户端断开(一般是账号在其他地方登录,被踢) } // api 接入 export function useDataSource () { const userStore = useUserStore() const loginType = useLoginType() // 最近会话数据源 WKSDK.shared().config.provider.syncConversationsCallback = async () => { const query = { msg_count: 100 } if (loginType.loginType === 'enterprise') { Object.assign(query, { enterpriseId: userStore.baseInfo.enterpriseId }) } const resultConversations = [] const resp = await getConversationSync(query) // console.log(resp) const conversationList = resp if (conversationList) { conversationList.forEach(conversation => { conversation.channel = new Channel(conversation.channel_id, conversation.channel_type) conversation.unread = +(conversation.unread || 0) resultConversations.push(conversation) }) } return resultConversations } // 同步频道消息数据源 WKSDK.shared().config.provider.syncMessagesCallback = async function(channel) { // 后端提供的获取频道消息列表的接口数据 然后构建成 Message对象数组返回 let resultMessages = new Array() const { startMessageSeq: start_message_seq, endMessageSeq: end_message_seq, limit, pullMode: pull_mode } = HISTORY_QUERY const query = { channel_id: channel.channelID, channel_type: channel.channelType, start_message_seq, end_message_seq, limit, pull_mode, } if (loginType.loginType === 'enterprise') { Object.assign(query, { enterpriseId: userStore.baseInfo.enterpriseId }) } const resp = await getMessageSync(query) const messageList = resp && resp["messages"] if (messageList) { messageList.forEach((msg) => { // const message = Convert.toMessage(msg); // msg.channel = new Channel(msg.channel_id, msg.channel_type) msg.payload = JSON.parse(Base64.decode(msg.payload)) if (msg.payload.type === 101) { msg.payload.content = JSON.parse(msg.payload.content ?? '{}') } resultMessages.push(msg); }); } console.log(resultMessages) const more = resp.more === 1 return { more, resultMessages } } } async function getKey () { const userStore = useUserStore() const loginType = useLoginType() const keyQuery = { userId: userStore.userInfo.id } if (loginType.loginType === 'enterprise') { Object.assign(keyQuery, { enterpriseId: userStore.baseInfo.enterpriseId }) } const { uid, wsUrl, token } = await getChatKey(keyQuery) return { uid, wsUrl, token } } export const useIM = () => { useDataSource() const key = ref(0) const IM = useIMStore() onMounted( async () => { // 通过自身userId和企业id获取token和uid const { uid, wsUrl, token } = await getKey() IM.setUid(uid) // 单机模式可以直接设置地址 WKSDK.shared().config.addr = 'ws://' + wsUrl // 默认端口为5200 // 认证信息 WKSDK.shared().config.uid = uid // 用户uid(需要在悟空通讯端注册过) WKSDK.shared().config.token = token // 用户token (需要在悟空通讯端注册过) // 连接状态监听 WKSDK.shared().connectManager.addConnectStatusListener(connectStatusListener) // 常规消息监听 WKSDK.shared().chatManager.addMessageListener(messageListen) // 连接 WKSDK.shared().connectManager.connect() }) onUnmounted(() => { WKSDK.shared().connectManager.removeConnectStatusListener(connectStatusListener) // 常规消息监听移除 WKSDK.shared().chatManager.removeMessageListener(messageListen) // 连接状态监听移除 WKSDK.shared().connectManager.disconnect() }) async function messageListen (message) { console.log('收到消息', message) IM.setFromChannel(message.channel.channelID) setUnreadCount() } async function connectStatusListener (status) { // console.log('连接状态', status === ConnectStatus.Connected) // 连接成功 获取点击数 const connected = status === ConnectStatus.Connected IM.setConnected(connected) if (connected) { // 必须同步最近会话才能获取未读总数 await syncConversation() setUnreadCount() } } function setUnreadCount () { const count = WKSDK.shared().conversationManager.getAllUnreadCount() key.value++ IM.setNewMsg(key.value) IM.setUnreadCount(count) console.log('未读消息总数', count) } } export function initConnect (callback = () => {}) { useDataSource() const IM = useIMStore() const conversationList = ref([]) const messageItems = ref([]) watch( () => IM.newMsg, async () => { // 未读消息变化 updateConversation() // 拉取最新消息 查看是否是自己的数据 }, { deep: true, immediate: true } ) onMounted(async () => { // 消息发送状态监听 WKSDK.shared().chatManager.addMessageStatusListener(statusListen) // 常规消息监听 // WKSDK.shared().chatManager.addMessageListener(messageListen) }) onUnmounted(() => { // 消息发送状态监听移除 WKSDK.shared().chatManager.removeMessageStatusListener(statusListen) // 常规消息监听移除 // WKSDK.shared().chatManager.removeMessageListener(messageListen) }) // 消息发送状态监听 function statusListen (packet) { if (packet.reasonCode === 1) { // 发送成功 console.log('发送成功') // 添加一组成功数据 callback(true) } else { // 发送失败 console.log('发送失败') // 添加一组失败数据 callback(false) } } async function updateConversation () { const res = await syncConversation() conversationList.value = res } function updateUnreadCount () { const count = WKSDK.shared().conversationManager.getAllUnreadCount() IM.setUnreadCount(count) } async function deleteConversations (channel, enterpriseId) { const query = { channel_id: channel.channelID, channel_type: channel.channelType, enterpriseId } await deleteConversation(query) } async function resetUnread (channel, enterpriseId) { const query = { channel_id: channel.channelID, channel_type: channel.channelType, enterpriseId, unread: 0 } const res = await setUnread(query) return res } return { resetUnread, deleteConversations, updateConversation, updateUnreadCount, conversationList, messageItems, // channel } } // 同步最近会话 async function syncConversation () { const res = await WKSDK.shared().conversationManager.sync() return res } // 发起聊天 export async function initChart (userId, enterpriseId) { const channel = ref() // const list = ref([]) const query = { userId, enterpriseId } // 创建聊天频道 const { uid } = await getChatKey(query) const _channel = new Channel(uid, ChannelTypePerson) channel.value = _channel const conversation = WKSDK.shared().conversationManager.findConversation(_channel) if(!conversation) { // 如果最近会话不存在,则创建一个空的会话 WKSDK.shared().conversationManager.createEmptyConversation(_channel) } const res = await getMoreMessages(1, _channel) return { channel, ...res } } // 翻页 export async function getMoreMessages (pageSize, channel) { const list = ref([]) Object.assign(HISTORY_QUERY, { startMessageSeq: (pageSize - 1) * HISTORY_QUERY.limit }) const { resultMessages, more } = await WKSDK.shared().chatManager.syncMessages(channel) list.value = resultMessages return { list, more } } /** * * @param {*} text * @param {*} _channel * @param { Number } type : 101 面试主体 * @returns */ export function send (text, _channel, type) { let _text if (type === 101) { _text = new ObjectContent(text) WKSDK.shared().chatManager.send(_text, _channel) console.log(_text) return } _text = new MessageText(text) console.log(_text) WKSDK.shared().chatManager.send(_text, _channel) } // 对话开场白 export async function prologue ({userId, enterpriseId, text}) { const { channel } = await checkConversation(userId, enterpriseId) send(text, channel) } // 检测是否存在频道 export async function checkConversation (userId, enterpriseId) { const query = { userId, enterpriseId } // 创建聊天频道 const { uid } = await getChatKey(query) const _channel = new Channel(uid, ChannelTypePerson) const conversation = WKSDK.shared().conversationManager.findConversation(_channel) if(!conversation) { // 如果最近会话不存在,则创建一个空的会话 WKSDK.shared().conversationManager.createEmptyConversation(_channel) } return { channel: _channel } }