import { post } from '@/core/http/http-client' import { buildRestPath } from '@/core/config/api-paths' import { STORAGE } from '@/core/constants/storage-keys' import appSettings from '@/core/config/app-settings' /** * GatewayWorker 下发 init 后,把 client_id 绑定到当前登录用户。 * 老工程 store/modules/chat.js case 'init' → POST chat/shake。 */ export async function bindSocketClient(clientId) { if (!clientId) return null try { const { data, raw } = await post(buildRestPath('chat/shake'), { client_id: clientId }) const saved = data != null && data !== '' ? data : (raw?.res?.data ?? raw?.res ?? raw?.data) if (saved != null && saved !== '') { uni.setStorageSync(STORAGE.chatClient, saved) } if (appSettings.debug) console.log('[im] shake ok', { clientId, saved }) return saved } catch (err) { if (appSettings.debug) console.warn('[im] shake failed', err) return null } } export function readStoredClientId() { return uni.getStorageSync(STORAGE.chatClient) || null } const LIVE_INNER_TYPES = [ 'msg', 'coming', 'seek', 'follow', 'like', 'review', 'end', 'tip_done', 'update', 'gift', 'publish', 'publish_done', 'ban' ] /** 识别直播群组推送(兼容 type:live / 顶层 tip_done / 仅带 message.type 的包) */ export function isLiveRoomPacket(packet) { if (!packet || typeof packet !== 'object') return false if (packet.type === 'live') return true // 顶层即直播事件(老工程 mock / 部分网关直推 tip_done) if (LIVE_INNER_TYPES.includes(packet.type)) return true const inner = packet.message if (!inner) return false if (typeof inner === 'object' && LIVE_INNER_TYPES.includes(inner.type)) return true // message 为 JSON 字符串时也要识别 if (typeof inner === 'string') { try { const parsed = JSON.parse(inner) return !!(parsed && LIVE_INNER_TYPES.includes(parsed.type)) } catch (_) { return false } } return false }