From 43ac988fc96d075e5af534664be5bd934df1221d Mon Sep 17 00:00:00 2001 From: jinhhanhan <1683105490@qq.com> Date: Wed, 21 Jan 2026 16:54:43 +0800 Subject: [PATCH] =?UTF-8?q?chore=EF=BC=9Aws=E9=80=9A=E4=BF=A1=E6=88=90?= =?UTF-8?q?=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/js/ai-service.js | 142 ++++++++++++++++++++++++++------------ common/js/golbalConfig.js | 4 ++ 2 files changed, 100 insertions(+), 46 deletions(-) diff --git a/common/js/ai-service.js b/common/js/ai-service.js index 88c4dff..d6c211a 100644 --- a/common/js/ai-service.js +++ b/common/js/ai-service.js @@ -61,54 +61,104 @@ export default { * 流式消息入口(自动适配平台) */ async sendStreamMessage(message, onChunk, onComplete) { - // #ifdef MP-WEIXIN - // 微信小程序:降级为普通请求 + 前端打字模拟 - try { - const result = await this.sendMessage(message); - const content = result.content || ''; - const conversationId = result.conversationId || ''; - - // 保存会话ID(确保连续对话) - if (conversationId) { - this.setConversationId(conversationId); - } - - // 模拟打字效果 - let index = 0; - const chunkSize = 2; // 每次显示2个字符 - return new Promise((resolve) => { - const timer = setInterval(() => { - if (index < content.length) { - const chunk = content.substring(index, index + chunkSize); - index += chunkSize; - if (onChunk) onChunk(chunk); - } else { - clearInterval(timer); - if (onComplete) { - onComplete({ - content: content, - conversation_id: conversationId - }); - } - resolve({ content, conversation_id: conversationId }); - } - }, 80); // 打字速度:80ms/次 + // #ifdef MP-WEIXIN + return new Promise((resolve, reject) => { + const socketTask = wx.connectSocket({ + url: 'wss://dev.aigc-quickapp.com/ws/aikefu', + header: { + } }); - } catch (error) { - console.error('小程序流式消息降级失败:', error); - if (onComplete) { - onComplete({ error: error.message || '发送失败' }); - } - throw error; - } + + let content = ''; + let conversationId = ''; + let isAuthenticated = false; + + // 连接成功 + socketTask.onOpen(() => { + console.log('WebSocket 连接成功,开始认证...'); + // 第一步:发送 auth 认证 + socketTask.send({ + data: JSON.stringify({ + action: 'auth', + uniacid: store.state.uniacid || '1', + token: store.state.token || 'test_token', + user_id: store.state.memberInfo?.id || 'anonymous' + }) + }); + }); + + // 接收消息 + socketTask.onMessage((res) => { + try { + const data = JSON.parse(res.data); + console.log('收到 WebSocket 消息:', data); + + // 处理认证响应 + if (data.type === 'auth_success') { + console.log('认证成功,发送聊天消息...'); + isAuthenticated = true; + socketTask.send({ + data: JSON.stringify({ + action: 'chat', + uniacid: store.state.uniacid || '1', + query: message, + user_id: store.state.memberInfo?.id || 'anonymous', + conversation_id: this.getConversationId() || '' + }) + }); + } else if (data.type === 'auth_failed') { + const errorMsg = '认证失败,请重新登录'; + console.error(errorMsg, data); + reject(new Error(errorMsg)); + if (onComplete) onComplete({ error: errorMsg }); + socketTask.close(); + } + // 处理聊天流式响应 + else if (data.action === 'chat_response') { + if (data.type === 'chunk') { + const text = data.content || ''; + content += text; + if (onChunk) onChunk(text); + } else if (data.type === 'end') { + conversationId = data.conversation_id || ''; + if (conversationId) { + this.setConversationId(conversationId); + } + if (onComplete) { + onComplete({ content, conversation_id: conversationId }); + } + resolve({ content, conversation_id: conversationId }); + socketTask.close(); + } + } + } catch (e) { + console.error('WebSocket 消息解析失败:', e, '原始数据:', res.data); + } + }); + + // 连接错误 + socketTask.onError((err) => { + const errorMsg = 'WebSocket 连接失败'; + console.error(errorMsg, err); + reject(new Error(errorMsg)); + if (onComplete) onComplete({ error: errorMsg }); + }); + + // 连接关闭 + socketTask.onClose(() => { + console.log('WebSocket 连接已关闭'); + }); + const timeout = setTimeout(() => { + if (!isAuthenticated || content === '') { + console.warn('WebSocket 超时,强制关闭'); + socketTask.close(); + reject(new Error('AI服务响应超时')); + if (onComplete) onComplete({ error: 'AI服务响应超时' }); + } + }, 10000); + }); // #endif - - // #ifdef H5 - // H5:使用真实流式(EventSource / Fetch) - return this.sendHttpStream(message, onChunk, onComplete); - // #endif - }, - +}, /** * HTTP 流式请求(仅 H5 使用) */ diff --git a/common/js/golbalConfig.js b/common/js/golbalConfig.js index d412a07..25d0b96 100644 --- a/common/js/golbalConfig.js +++ b/common/js/golbalConfig.js @@ -65,6 +65,10 @@ export default { componentRefresh() { return this.$store.state.componentRefresh; }, + // AI客服配置 + globalAIKefuConfig() { + return this.$store.state.globalAIKefuConfig; + }, // 客服配置 servicerConfig() { return this.$store.state.servicerConfig;