From 483b57f6679524ddccff469f89752577303b806b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=98=B1=E8=BE=BE?= Date: Wed, 24 Sep 2025 14:26:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(ai-chat):=20=E5=AE=9E=E7=8E=B0AI=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E5=AF=B9=E8=AF=9D=E4=B8=8E=E4=BC=9A=E8=AF=9D=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E8=AE=B0=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增AI聊天对话接口和会话消息记录查询接口,支持SSE流式响应处理。 在sendMessage组件中集成真实SE调用逻辑,替换原有模拟实现, 并完善conversationId的获取与保存机制。新增sseHelper工具类用于统一处理SSE连接和数据解析。 --- src/api/boe/aiChat.js | 21 +++ src/utils/sseHelper.js | 83 ++++++++++ src/views/portal/case/AICall.vue | 12 +- .../portal/case/components/sendMessage.vue | 151 ++---------------- 4 files changed, 128 insertions(+), 139 deletions(-) create mode 100644 src/api/boe/aiChat.js create mode 100644 src/utils/sseHelper.js diff --git a/src/api/boe/aiChat.js b/src/api/boe/aiChat.js new file mode 100644 index 00000000..d023eef0 --- /dev/null +++ b/src/api/boe/aiChat.js @@ -0,0 +1,21 @@ +import ajax from '@/api/boe/boeApiAjax.js' + +/** + * AI聊天对话接口 + * @param {Object} data - 请求参数 + * @param {string} data.conversationId - 会话ID,如果为空则创建新会话 + * @param {string} data.query - 用户提问内容 + * @returns {Promise} - 返回SSE流 + */ +export function aiChat(data) { + return ajax.postJson('/xboe/m/boe/case/ai/chat', data) +} + +/** + * 查询会话消息记录接口 + * @param {string} conversationId - 会话ID + * @returns {Promise} - 返回会话历史记录 + */ +export function getChatMessages(conversationId) { + return ajax.get('/xboe/m/boe/case/ai/messages?conversationId=' + conversationId) +} \ No newline at end of file diff --git a/src/utils/sseHelper.js b/src/utils/sseHelper.js new file mode 100644 index 00000000..d85bb77d --- /dev/null +++ b/src/utils/sseHelper.js @@ -0,0 +1,83 @@ +/** + * SSE流式数据处理工具 + */ + +/** + * 处理SSE响应数据 + * @param {String} data - SSE响应数据 + * @param {Function} onMessage - 处理消息的回调函数 + * @param {Function} onComplete - 完成时的回调函数 + * @param {Function} onError - 错误处理回调函数 + */ +export function processSSEData(data, onMessage, onComplete, onError) { + try { + const lines = data.split('\n') + for (const line of lines) { + if (line.startsWith('data: ')) { + const jsonData = JSON.parse(line.substring(6)) + onMessage(jsonData) + + // 如果状态为4,表示对话结束 + if (jsonData.data && jsonData.data.status === 4) { + onComplete() + } + } + } + } catch (error) { + console.error('处理SSE数据时出错:', error) + if (onError) { + onError(error) + } + } +} + +/** + * 创建SSE连接 + * @param {String} url - 请求地址 + * @param {Object} data - 请求数据 + * @param {Function} onMessage - 消息处理回调 + * @param {Function} onComplete - 完成回调 + * @param {Function} onError - 错误回调 + * @returns {Promise} - 返回fetch Promise + */ +export function createSSEConnection(url, data, onMessage, onComplete, onError) { + return fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + }).then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const reader = response.body.getReader() + const decoder = new TextDecoder('utf-8') + let buffer = '' + + function read() { + reader.read().then(({ done, value }) => { + if (done) { + if (onComplete) onComplete() + return + } + + buffer += decoder.decode(value, { stream: true }) + processSSEData(buffer, onMessage, onComplete, onError) + + // 继续读取 + read() + }).catch(error => { + console.error('SSE读取错误:', error) + if (onError) onError(error) + }) + } + + // 开始读取数据 + read() + }).catch(error => { + console.error('SSE连接错误:', error) + if (onError) onError(error) + }) +} \ No newline at end of file diff --git a/src/views/portal/case/AICall.vue b/src/views/portal/case/AICall.vue index 8a864967..b67a92b7 100644 --- a/src/views/portal/case/AICall.vue +++ b/src/views/portal/case/AICall.vue @@ -26,7 +26,7 @@
@@ -49,6 +49,7 @@ @new-conversation="startNewConversation" :disabled="isLoading" class="input-area-wrapper" + ref="sendMessage" />
@@ -121,8 +122,13 @@ export default { this.suggestions = arr }, // 处理建议 - sendSuggestions(){ - this.suggestions = [] + sendSuggestions(item){ + // this.suggestions = [] + this.AIContent = item + setTimeout(()=>{ + this.$refs.sendMessage.handleSend() + this.AIContent = '' + },500) }, startNewConversation() { this.messageList = [ diff --git a/src/views/portal/case/components/sendMessage.vue b/src/views/portal/case/components/sendMessage.vue index 7ad9731f..55be4afd 100644 --- a/src/views/portal/case/components/sendMessage.vue +++ b/src/views/portal/case/components/sendMessage.vue @@ -19,7 +19,7 @@