From 4c3e38382731f1cb1ae17a5b9a1c5e2f6bc7f27e Mon Sep 17 00:00:00 2001 From: lq Date: Tue, 30 Dec 2025 10:04:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dwebsocket?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- subPackages/register/register.vue | 22 ++--- utils/ws/websocket.js | 135 +++++++++++++++++++++--------- 2 files changed, 100 insertions(+), 57 deletions(-) diff --git a/subPackages/register/register.vue b/subPackages/register/register.vue index afeb703..2adaa63 100644 --- a/subPackages/register/register.vue +++ b/subPackages/register/register.vue @@ -298,11 +298,11 @@ }); console.log(checkDev('open-im') && that.registList.register_type === 1, 'sssssssssssss') - if (checkDev('open-im') && (that.registList.register_type === 1 || that.registList.register_type === 2)) { - // 传递type参数,根据挂号类型创建对应类型的房间 + if (checkDev('open-im') && that.registList.register_type === 1) { + // 在线咨询:创建type=1的房间 createRoomByDoctorIdApi({ doctor_id: that.currentDoctorId, - type: that.registList.register_type // 1=在线咨询,2=复诊 + type: 1 // 在线咨询 }).then(result => { sendToUserApi({ room_id: result.data.result.room_id, @@ -314,25 +314,13 @@ }), duration: 0 }) - // 发送在线复诊信息 - if (that.registList.register_type === 2) { - that.rInfo.register_id = that.register_id; - sendToUserApi({ - room_id: result.data.result.room_id, - sender_user_id: that.currentUserId, - receiver_user_id: that.currentDoctorId, - message_type: 11, - message_content: that.rInfo, - duration: 0 - }) - } }) } if (res.data.data.is_paid == 1) { - if (that.registList.register_type === 3) { - // 在线复诊流程:创建聊天房间并发送患者就诊经历消息 + if (that.registList.register_type === 2 || that.registList.register_type === 3) { + // 在线复诊/购药流程:创建type=3的聊天房间并发送患者就诊经历消息 that.handleOnlineConsultationAfterPayment(); return; } diff --git a/utils/ws/websocket.js b/utils/ws/websocket.js index bd838a6..b79ec60 100644 --- a/utils/ws/websocket.js +++ b/utils/ws/websocket.js @@ -3,11 +3,32 @@ export class WebSocketManager { this.url = url; this.socket = null; this.isConnected = false; + this.isAuthenticated = false; // 是否已认证 this.reconnectAttempts = 0; this.maxReconnectAttempts = 5; this.reconnectDelay = 1000; this.messageHandlers = []; this.pingInterval = null; + this.cachedToken = null; // 缓存的token + } + + /** + * 获取当前用户的token + * @returns {string|null} + */ + getToken() { + // 优先使用缓存的token + if (this.cachedToken) { + return this.cachedToken; + } + // 从本地存储获取token + let token = uni.getStorageSync('token'); + if (token) { + // 移除Bearer前缀(如果有) + token = token.replace('Bearer ', ''); + this.cachedToken = token; + } + return token || null; } connect() { @@ -62,20 +83,45 @@ export class WebSocketManager { }); } + /** + * 绑定用户(携带token进行认证) + * @param {string} userId 用户ID + */ bindUser(userId) { - this.send({ - type: 'bind', - userId: userId + const token = this.getToken(); + if (!token) { + console.error('绑定用户失败:token不存在'); + return false; + } + return this.send({ + request_type: 'bind', + user_type: 'user', + sender_user_id: userId, + token: token }); } - send(message) { + /** + * 发送消息(自动携带token) + * @param {Object} message 消息对象 + * @param {boolean} requireAuth 是否需要认证(默认true) + * @returns {boolean} 是否发送成功 + */ + send(message, requireAuth = true) { if (!this.isConnected) { console.error('WebSocket未连接'); return false; } try { + // 如果需要认证且消息中没有token,自动添加token + if (requireAuth && !message.token && message.request_type !== 'ping') { + const token = this.getToken(); + if (token) { + message.token = token; + } + } + const messageStr = JSON.stringify(message); this.socket.send({ data: messageStr, @@ -104,18 +150,31 @@ export class WebSocketManager { } } + /** + * 获取用户ID并绑定客户端(携带token) + * @returns {string|null} 用户ID + */ getUserIdAndBindClientId() { const userId = uni.getStorageSync('user_id'); // 实际项目中从存储获取 + const token = this.getToken(); + if (userId == null || userId === 'user-' || userId === '') { - // 等待10秒后获取 + // 等待10秒后重试 setTimeout(() => { this.getUserIdAndBindClientId(); }, 10000) + } else if (!token) { + // token不存在,等待后重试 + console.warn('token不存在,等待后重试绑定'); + setTimeout(() => { + this.getUserIdAndBindClientId(); + }, 5000) } else { const bindMessage = { request_type: 'bind', user_type: 'user', sender_user_id: `user-${userId}`, + token: token }; this.send(bindMessage); } @@ -123,45 +182,41 @@ export class WebSocketManager { } handleMessage(data) { - // 如果对象中有clientId则给websocket发送 + // 处理认证响应 + if (data.auth_status !== undefined) { + if (data.auth_status === 'success') { + console.log('WebSocket认证成功'); + this.isAuthenticated = true; + } else if (data.auth_status === 'failed') { + console.error('WebSocket认证失败:', data.message); + this.isAuthenticated = false; + // 清除缓存的token + this.cachedToken = null; + } else if (data.auth_status === 'token_expired') { + console.warn('Token已过期,需要重新认证'); + this.isAuthenticated = false; + this.cachedToken = null; + // 通知应用层token过期 + uni.$emit('ws-token-expired'); + // 尝试重新绑定 + this.getUserIdAndBindClientId(); + } + return; + } + + // 如果对象中有clientId则给websocket发送绑定请求 if (data.clientId) { - this.getUserIdAndBindClientId(data.clientId); - // const userId = uni.getStorageSync('user_id'); // 实际项目中从存储获取 - // if (userId == null) { - // setTimeout(() => { - // }, 10000) - // } else { - // const bindMessage = { - // request_type: 'bind', - // user_type: 'user', - // sender_user_id: `user-${userId}`, - // }; - // this.send(bindMessage); - // } - } - // 处理聊天消息 - if (data.message_type !== undefined) { - // 将消息转发给聊天管理器 - this.messageHandlers.forEach(handler => { - try { - handler(data); - } catch (e) { - console.error('消息处理出错:', e); - } - }); - } else { - // 其他消息处理 - this.messageHandlers.forEach(handler => { - try { - handler(data); - } catch (e) { - console.error('消息处理出错:', e); - } - }); - } + // 处理聊天消息或其他消息 + this.messageHandlers.forEach(handler => { + try { + handler(data); + } catch (e) { + console.error('消息处理出错:', e); + } + }); } startHeartbeat() {