diff --git a/common/js/ai-service.js b/common/js/ai-service.js index 2fea18a..e46355f 100644 --- a/common/js/ai-service.js +++ b/common/js/ai-service.js @@ -308,6 +308,7 @@ export default { method: 'POST', headers: { 'Content-Type': 'application/json', + 'Accept': 'text/event-stream', }, body: JSON.stringify({ uniacid: store.state.uniacid || '1', @@ -321,27 +322,60 @@ export default { const reader = response.body.getReader() const decoder = new TextDecoder() let content = '' + let buffer = '' + + // 处理流式数据 + function processStreamData(buffer, callback) { + const lines = buffer.split('\n'); + buffer = lines.pop() || ''; // 最后一行可能不完整 + + lines.forEach(line => { + line = line.trim(); + if (!line) return; + + // 解析 SSE 格式 + if (line.startsWith('data:')) { + const dataPart = line.slice(5).trim(); + if (dataPart) { + try { + const data = JSON.parse(dataPart); + + if (data.event === 'message') { + callback(data.answer || ''); + } + + if (data.conversation_id) { + conversationId = data.conversation_id; + } + + if (data.event === 'message_end') { + // 对话完成 + console.log('对话完成'); + } + } catch (error) { + console.error('解析流式数据失败:', error); + } + } + } + }); + + return buffer; + } while (true) { const { done, value } = await reader.read() if (done) break - const chunk = decoder.decode(value) - const lines = chunk.split('\n') - - for (const line of lines) { - if (line.startsWith('data: ')) { - try { - const data = JSON.parse(line.slice(6)) - if (data.event === 'text_message' && data.text) { - content += data.text - if (onChunk) onChunk(data.text) - } - } catch (e) { - // 忽略解析错误 - } - } - } + buffer += decoder.decode(value, { stream: true }); + + // 处理接收到的数据 + buffer = processStreamData(buffer, (newData) => { + if (newData) { + // 更新 AI 消息 + content += newData; + if (onChunk) onChunk(newData); + } + }); } if (onComplete) onComplete(content)