|
@@ -0,0 +1,428 @@
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+import { ref, onMounted, onUnmounted, watch } from 'vue';
|
|
|
|
+import { getConversationSync, getMessageSync, getChatKey, setUnread, deleteConversation } from '@/api/common'
|
|
|
|
+import { Base64 } from 'js-base64'
|
|
|
|
+
|
|
|
|
+import { userStore } from '@/store/user'
|
|
|
|
+import { useIMStore } from '@/store/im'
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 配置悟空IM
|
|
|
|
+import {
|
|
|
|
+ MessageText,
|
|
|
|
+ Channel,
|
|
|
|
+ WKSDK,
|
|
|
|
+ ChannelTypePerson,
|
|
|
|
+ MessageContent,
|
|
|
|
+} from "wukongimjssdk"
|
|
|
|
+
|
|
|
|
+// 默认招呼语
|
|
|
|
+export const defaultText = '您好,关注到您发布该职位信息,请问有机会与您进一步沟通吗?'
|
|
|
|
+
|
|
|
|
+// 企业默认招呼语
|
|
|
|
+// export const defaultTextEnt = '您好,我们正在寻找充满激情、勇于挑战的您,快来和我聊一聊吧~'
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+const { ObjectContent } = initRegister(101)
|
|
|
|
+const { ObjectContent: ObjectContent2 } = initRegister(102)
|
|
|
|
+const { ObjectContent: ObjectContent3 } = initRegister(103)
|
|
|
|
+const { ObjectContent: ObjectContent4 } = initRegister(104)
|
|
|
|
+const { ObjectContent: ObjectContent5 } = initRegister(105) // 发送简历
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+const contentType = {
|
|
|
|
+ 101: ObjectContent,
|
|
|
|
+ 102: ObjectContent2,
|
|
|
|
+ 103: ObjectContent3,
|
|
|
|
+ 104: ObjectContent4,
|
|
|
|
+ 105: ObjectContent5, // 发送简历
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 注册消息体
|
|
|
|
+function initRegister (type) {
|
|
|
|
+ class ObjectContent extends MessageContent {
|
|
|
|
+ constructor(text) {
|
|
|
|
+ super();
|
|
|
|
+ this.content = text
|
|
|
|
+ }
|
|
|
|
+ get conversationDigest() {
|
|
|
|
+ // 这里需要实现具体的逻辑
|
|
|
|
+ return this.content
|
|
|
|
+ }
|
|
|
|
+ get contentType() {
|
|
|
|
+ // 这里需要实现具体的逻辑
|
|
|
|
+ return type; // 示例实现
|
|
|
|
+ }
|
|
|
|
+ decodeJSON(content) {
|
|
|
|
+ this.content = content.text;
|
|
|
|
+ }
|
|
|
|
+ encodeJSON() {
|
|
|
|
+ return {
|
|
|
|
+ content: this.content
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 注册101类型为面试
|
|
|
|
+ WKSDK.shared().register(type, () => new ObjectContent())
|
|
|
|
+ return {
|
|
|
|
+ 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 () {
|
|
|
|
+ // 最近会话数据源
|
|
|
|
+ WKSDK.shared().config.provider.syncConversationsCallback = async () => {
|
|
|
|
+ const query = {
|
|
|
|
+ msg_count: 1
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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 (contentType[msg.payload.type]) {
|
|
|
|
+ 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 useUserStore = userStore()
|
|
|
|
+
|
|
|
|
+ const keyQuery = {
|
|
|
|
+ userId: useUserStore.accountInfo.userId
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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 = 'wss://' + 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
|
|
|
|
+ */
|
|
|
|
+ // 发送职位使用101
|
|
|
|
+export function send (text, _channel, type) {
|
|
|
|
+ let _text
|
|
|
|
+ if (contentType[type]) {
|
|
|
|
+ _text = new contentType[type](text)
|
|
|
|
+ WKSDK.shared().chatManager.send(_text, _channel)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // if (type === 101) {
|
|
|
|
+ // _text = new ObjectContent(text)
|
|
|
|
+ // WKSDK.shared().chatManager.send(_text, _channel)
|
|
|
|
+ // // console.log(_text)
|
|
|
|
+ // return
|
|
|
|
+ // }
|
|
|
|
+ // if (type === 102) {
|
|
|
|
+ // _text = new ObjectContent2(text)
|
|
|
|
+ // WKSDK.shared().chatManager.send(_text, _channel)
|
|
|
|
+ // // console.log(_text)
|
|
|
|
+ // return
|
|
|
|
+ // }
|
|
|
|
+ // // 求职者拒绝面试邀请
|
|
|
|
+ // if (type === 103) {
|
|
|
|
+ // _text = new ObjectContent3(text)
|
|
|
|
+ // WKSDK.shared().chatManager.send(_text, _channel)
|
|
|
|
+ // return
|
|
|
|
+ // }
|
|
|
|
+ // // 求职者接受面试邀请
|
|
|
|
+ // if (type === 104) {
|
|
|
|
+ // _text = new ObjectContent4(text)
|
|
|
|
+ // WKSDK.shared().chatManager.send(_text, _channel)
|
|
|
|
+ // return
|
|
|
|
+ // }
|
|
|
|
+ _text = new MessageText(text)
|
|
|
|
+ // console.log(_text)
|
|
|
|
+ WKSDK.shared().chatManager.send(_text, _channel)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 对话开场白 用户 to 企业
|
|
|
|
+export async function prologue ({userId, enterpriseId, text}) {
|
|
|
|
+ const { channel } = await checkConversation(userId, enterpriseId)
|
|
|
|
+ send(text, channel, 102)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 企业 to 用户
|
|
|
|
+export async function talkToUser ({userId, text}) {
|
|
|
|
+ const { channel, isNewTalk } = await checkConversation(userId)
|
|
|
|
+ if (!isNewTalk) 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)
|
|
|
|
+ const isNewTalk = ref(false)
|
|
|
|
+ if(!conversation) {
|
|
|
|
+ // 如果最近会话不存在,则创建一个空的会话
|
|
|
|
+ WKSDK.shared().conversationManager.createEmptyConversation(_channel)
|
|
|
|
+ isNewTalk.value = true
|
|
|
|
+ }
|
|
|
|
+ return {
|
|
|
|
+ channel: _channel,
|
|
|
|
+ isNewTalk: isNewTalk.value
|
|
|
|
+ }
|
|
|
|
+}
|