import { getStorageFun, TOKEN_NAME, USER_DATA } from '@/utils/auth.js' import { getCurrentMember } from './api.js' import { KefuSocket } from './kefu-socket.js' export const KEFU_REALTIME_EVENT = 'kefu-realtime-event' export const KEFU_REALTIME_STATUS = 'kefu-realtime-status' let socket = null let connectionParams = null let startingPromise = null function storedMember() { const value = getStorageFun(USER_DATA) if (!value) return null if (typeof value === 'object') return value try { return JSON.parse(value) } catch (error) { return null } } async function resolveMemberId(explicitUserId) { if (explicitUserId) return explicitUserId const cached = storedMember() if (cached && (cached.id || cached.userId)) return cached.id || cached.userId const member = await getCurrentMember() return member && (member.id || member.userId) } function createSocket() { const instance = new KefuSocket({ onStatus(status) { uni.$emit(KEFU_REALTIME_STATUS, status) }, onEvent(event) { uni.$emit(KEFU_REALTIME_EVENT, event) }, }) socket = instance instance.connect(connectionParams) return instance } /** * Start the foreground customer-service connection. Calls are idempotent so * several pages can consume the same stream without opening duplicate sockets. */ export function startKefuRealtime(options = {}) { if (!getStorageFun(TOKEN_NAME)) { resetKefuRealtime() return Promise.resolve(null) } if (startingPromise) return startingPromise startingPromise = resolveMemberId(options.userId) .then((userId) => { if (!userId) return null const nextParams = { userId, mchId: options.mchId || (connectionParams && connectionParams.mchId) || 1002, } const sameMember = connectionParams && String(connectionParams.userId) === String(userId) connectionParams = nextParams if (socket && sameMember) { socket.reconnectNow() return socket } if (socket) socket.close() socket = null return createSocket() }) .catch(() => null) .finally(() => { startingPromise = null }) return startingPromise } export function suspendKefuRealtime() { if (socket) socket.close() socket = null uni.$emit(KEFU_REALTIME_STATUS, 'closed') } export function resumeKefuRealtime() { if (!getStorageFun(TOKEN_NAME)) { resetKefuRealtime() return Promise.resolve(null) } return startKefuRealtime(connectionParams || {}) } export function resetKefuRealtime() { suspendKefuRealtime() connectionParams = null }