From a8f7ffed6100c047acd33e8dff14ad7057413c9e Mon Sep 17 00:00:00 2001 From: lq Date: Tue, 30 Dec 2025 10:04:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B8=B8=E7=94=A8=E6=96=B9=E3=80=81?= =?UTF-8?q?=E6=82=A3=E8=80=85=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/chat/composables/useWebSocket.ts | 84 ++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/apps/web-antd/src/views/business/chat/composables/useWebSocket.ts b/apps/web-antd/src/views/business/chat/composables/useWebSocket.ts index 4ab429c1..f39d86c7 100644 --- a/apps/web-antd/src/views/business/chat/composables/useWebSocket.ts +++ b/apps/web-antd/src/views/business/chat/composables/useWebSocket.ts @@ -1,5 +1,7 @@ import { onMounted, onUnmounted, ref } from 'vue'; +import { useAccessStore } from '@vben/stores'; + import { getWebSocketUrl } from '#/util/tool'; import { useChatStore } from '../stores/chat'; @@ -8,6 +10,11 @@ import { useUserStore } from '../stores/user'; export function useWebSocket() { const userStore = useUserStore(); const chatStore = useChatStore(); + const accessStore = useAccessStore(); + + // 认证状态 + const isAuthenticated = ref(false); + const cachedToken = ref(null); const socket = ref(); const isConnected = ref(false); @@ -58,6 +65,36 @@ export function useWebSocket() { const data = JSON.parse(event.data); console.log('收到WebSocket消息:', data); + // 处理认证响应 + if (data.auth_status !== undefined) { + if (data.auth_status === 'success') { + console.log('WebSocket认证成功'); + isAuthenticated.value = true; + } else if (data.auth_status === 'failed') { + console.error('WebSocket认证失败:', data.message); + isAuthenticated.value = false; + cachedToken.value = null; + } else if (data.auth_status === 'token_expired') { + console.warn('Token已过期,需要重新认证'); + isAuthenticated.value = false; + cachedToken.value = null; + // 尝试重新绑定 + if (userStore.currentUser?.doctor_id) { + bindUser(userStore.currentUser.doctor_id); + } + } + return; + } + + // 处理clientId响应,进行用户绑定 + if (data.clientId) { + console.log('收到clientId,准备绑定用户'); + if (userStore.currentUser?.doctor_id) { + bindUser(userStore.currentUser.doctor_id); + } + return; + } + // 优先处理通话信令(无论是否在当前聊天窗口) if (data.call_id && data.call_status) { handleCallSignal(data); @@ -104,25 +141,66 @@ export function useWebSocket() { chatStore.handleCallSignal(data); }; + /** + * 获取当前用户的token + */ + const getToken = (): string | null => { + // 优先使用缓存的token + if (cachedToken.value) { + return cachedToken.value; + } + // 从accessStore获取token + let token = accessStore.accessToken; + if (token) { + // 移除Bearer前缀(如果有) + token = token.replace('Bearer ', ''); + cachedToken.value = token; + } + return token || null; + }; + + /** + * 绑定用户(携带token进行认证) + */ const bindUser = (userId) => { if (!isConnected.value || !userId) return; + const token = getToken(); + if (!token) { + console.error('绑定用户失败:token不存在'); + return false; + } + const bindMessage = { request_type: 'bind', user_type: 'doctor', sender_user_id: `doctor-${userId}`, + token: token, }; - send(bindMessage); + return send(bindMessage); }; - const send = (message) => { + /** + * 发送消息(自动携带token) + * @param message 消息对象 + * @param requireAuth 是否需要认证(默认true) + */ + const send = (message: any, requireAuth = true) => { if (!isConnected.value || !socket.value) { console.error('WebSocket未连接,无法发送消息'); return false; } try { + // 如果需要认证且消息中没有token,自动添加token + if (requireAuth && !message.token && message.request_type !== 'ping') { + const token = getToken(); + if (token) { + message.token = token; + } + } + socket.value.send(JSON.stringify(message)); console.log('发送消息:', message); return true; @@ -180,6 +258,7 @@ export function useWebSocket() { socket, isConnected, isConnecting, + isAuthenticated, connectWebSocket, disconnect, send, @@ -187,5 +266,6 @@ export function useWebSocket() { sendCallSignal, bindUser, generateCallId, + getToken, }; }