From fbed692c7b38ebee9dfc4debc51ed21179965a72 Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Tue, 19 May 2026 15:44:28 +0800 Subject: [PATCH] 1 --- common/ieApi.js | 70 ++++++++++++++++++ common/ieSocket.js | 174 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 common/ieApi.js create mode 100644 common/ieSocket.js diff --git a/common/ieApi.js b/common/ieApi.js new file mode 100644 index 0000000..4136004 --- /dev/null +++ b/common/ieApi.js @@ -0,0 +1,70 @@ +import tui from './httpRequest' + +function unwrap(res) { + if (!res) return null + if (res.success === false) { + uni.showToast({ title: res.message || '请求失败', icon: 'none' }) + return null + } + return res.result !== undefined ? res.result : res +} + +export function ieHome() { + return tui.request('/app/ie/home', 'GET', {}, false, false, true).then(unwrap) +} + +export function updateIeStatus(data) { + return tui.request('/app/ie/status', 'POST', data, false, false, true).then(unwrap) +} + +export function getIeProfile() { + return tui.request('/app/ie/profile', 'GET', {}, false, false, true).then(unwrap) +} + +export function getIeUserProfile(targetUserId) { + return tui.request(`/app/ie/profiles/${targetUserId}`, 'GET', {}, false, false, true).then(unwrap) +} + +export function saveIeProfile(data) { + return tui.request('/app/ie/profile', 'POST', data, false, false, false).then(unwrap) +} + +export function startIeMatch(data) { + return tui.request('/app/ie/match/start', 'POST', data, false, false, false).then(unwrap) +} + +export function sendIePresence(roomId, data) { + return tui.request(`/app/ie/rooms/${roomId}/presence`, 'POST', data, false, false, true).then(unwrap) +} + +export function finishIeRoom(roomId) { + return tui.request(`/app/ie/rooms/${roomId}/finish`, 'POST', {}, false, false, true).then(unwrap) +} + +export function reportIeRoom(roomId, data) { + return tui.request(`/app/ie/rooms/${roomId}/report`, 'POST', data, false, false, true).then(unwrap) +} + +export function blockIeUser(blockedUserId, reason = '') { + return tui.request(`/app/ie/block/${blockedUserId}`, 'POST', { reason }, false, true, true).then(unwrap) +} + +export function fetchIeOffline() { + return tui.request('/app/ie/offline', 'GET', {}, false, false, true).then(unwrap) +} + +export function pageIeMessages(roomId, pageNumber = 1, pageSize = 20) { + return tui.request(`/app/ie/rooms/${roomId}/messages/page`, 'GET', { pageNumber, pageSize }, false, true, true).then(unwrap) +} + +export function sendIeMessage(roomId, data) { + return tui.request(`/app/ie/rooms/${roomId}/messages`, 'POST', data, false, false, false).then(unwrap) +} + +export function pageIeRecords(pageNumber = 1, pageSize = 10) { + return tui.request('/app/ie/records/page', 'GET', { pageNumber, pageSize }, false, true, true).then(unwrap) +} + +export function pageIeReports(pageNumber = 1, pageSize = 10) { + return tui.request('/app/ie/reports/page', 'GET', { pageNumber, pageSize }, false, true, true).then(unwrap) +} diff --git a/common/ieSocket.js b/common/ieSocket.js new file mode 100644 index 0000000..3eacf19 --- /dev/null +++ b/common/ieSocket.js @@ -0,0 +1,174 @@ +import tui from './httpRequest' + +const socket = { + connected: false, + task: null, + heartbeatTimer: null, + subscriptions: {}, + connecting: false, + messageHandlers: [], + ackHandlers: [], + presenceHandlers: [], + roomEndHandlers: [], + offlineHandlers: [] +} + +function wsUrl() { + return tui.interfaceUrl().replace(/^http/, 'ws') + '/ws/websocket' +} + +function frame(command, headers = {}, body = '') { + const lines = [command] + Object.keys(headers).forEach(key => { + lines.push(`${key}:${headers[key]}`) + }) + lines.push('') + lines.push(body) + return lines.join('\n') + '\u0000' +} + +function parseFrame(raw) { + const text = raw.replace(/\u0000/g, '') + const splitIndex = text.indexOf('\n\n') + const head = splitIndex >= 0 ? text.slice(0, splitIndex) : text + const body = splitIndex >= 0 ? text.slice(splitIndex + 2) : '' + const lines = head.split('\n') + const command = lines.shift() + const headers = {} + lines.forEach(line => { + const index = line.indexOf(':') + if (index > -1) headers[line.slice(0, index)] = line.slice(index + 1) + }) + return { command, headers, body } +} + +function emit(list, payload) { + list.forEach(handler => { + try { handler(payload) } catch (e) { console.warn('ie socket handler error', e) } + }) +} + +function send(destination, body = {}) { + if (!socket.connected || !socket.task) return false + socket.task.send({ + data: frame('SEND', { + destination, + 'content-type': 'application/json' + }, JSON.stringify(body)) + }) + return true +} + +function subscribe(destination, id) { + socket.task.send({ + data: frame('SUBSCRIBE', { id, destination, ack: 'auto' }) + }) +} + +function subscribeRoom(roomId) { + if (!socket.connected || !socket.task || !roomId) return false + const id = 'ie-room-' + roomId + if (socket.subscriptions[id]) return true + socket.subscriptions[id] = true + subscribe('/topic/ie/room/' + roomId, id) + return true +} + +function bindSubscriptions() { + subscribe('/user/queue/ie/ack', 'ie-ack') + subscribe('/user/queue/ie/message', 'ie-message') + subscribe('/user/queue/ie/presence', 'ie-presence') + subscribe('/user/queue/ie/room-end', 'ie-room-end') + subscribe('/user/queue/ie/offline', 'ie-offline') + send('/app/ie/connect') +} + +function handleMessage(raw) { + if (raw === 'h') return + const data = parseFrame(raw) + if (data.command === 'CONNECTED') { + socket.connected = true + bindSubscriptions() + startHeartbeat() + return + } + if (data.command !== 'MESSAGE') return + let payload = data.body + try { payload = JSON.parse(data.body) } catch (e) {} + const dest = data.headers.destination || '' + if (dest.indexOf('/queue/ie/ack') > -1) emit(socket.ackHandlers, payload) + if (dest.indexOf('/queue/ie/message') > -1 || dest.indexOf('/topic/ie/room/') > -1) emit(socket.messageHandlers, payload) + if (dest.indexOf('/queue/ie/presence') > -1) emit(socket.presenceHandlers, payload) + if (dest.indexOf('/queue/ie/room-end') > -1) emit(socket.roomEndHandlers, payload) + if (dest.indexOf('/queue/ie/offline') > -1) emit(socket.offlineHandlers, payload) +} + +function startHeartbeat() { + clearInterval(socket.heartbeatTimer) + socket.heartbeatTimer = setInterval(() => { + send('/app/ie/heartbeat') + }, 25000) +} + +function connect() { + if (socket.connected || socket.connecting) return Promise.resolve() + socket.connecting = true + return new Promise((resolve, reject) => { + socket.task = uni.connectSocket({ + url: wsUrl(), + header: { accessToken: tui.getToken() }, + success: resolve, + fail: reject + }) + socket.task.onOpen(() => { + socket.connecting = false + socket.task.send({ + data: frame('CONNECT', { + 'accept-version': '1.2', + 'heart-beat': '10000,10000', + accessToken: tui.getToken() + }) + }) + }) + socket.task.onMessage(res => handleMessage(res.data || '')) + socket.task.onClose(() => { + socket.connected = false + socket.connecting = false + clearInterval(socket.heartbeatTimer) + }) + socket.task.onError(() => { + socket.connected = false + socket.connecting = false + clearInterval(socket.heartbeatTimer) + }) + }) +} + +function close() { + clearInterval(socket.heartbeatTimer) + if (socket.task) socket.task.close() + socket.connected = false + socket.task = null +} + +function resetHandlers() { + socket.messageHandlers = [] + socket.ackHandlers = [] + socket.presenceHandlers = [] + socket.roomEndHandlers = [] + socket.offlineHandlers = [] +} + +export default { + connect, + close, + resetHandlers, + subscribeRoom, + sendMessage(data) { return send('/app/ie/message', data) }, + sendPresence(data) { return send('/app/ie/presence', data) }, + onAck(handler) { socket.ackHandlers.push(handler) }, + onMessage(handler) { socket.messageHandlers.push(handler) }, + onPresence(handler) { socket.presenceHandlers.push(handler) }, + onRoomEnd(handler) { socket.roomEndHandlers.push(handler) }, + onOffline(handler) { socket.offlineHandlers.push(handler) } +}