From 7de0da21048ac0678dc45f79d3a6649bde61f5d1 Mon Sep 17 00:00:00 2001 From: Chen Li <422043296@qq.com> Date: Wed, 20 Aug 2025 09:56:41 +0800 Subject: [PATCH] fix image http --- lib/services/chat_sse_service.dart | 76 ++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 20 deletions(-) diff --git a/lib/services/chat_sse_service.dart b/lib/services/chat_sse_service.dart index d39454a..c95680b 100644 --- a/lib/services/chat_sse_service.dart +++ b/lib/services/chat_sse_service.dart @@ -35,7 +35,59 @@ class ChatSseService { print('初始化用户ID: $_cachedUserId'); } String responseText = ''; - String tempText = ''; + StringBuffer buffer = StringBuffer(); + // 英文分句符 + final enEnders = RegExp(r'[.!?]'); + // 中文分句符 + final zhEnders = RegExp(r'[。!?]'); + // 专有名词保护 + String protectIDUNYX(String text) => text.replaceAll('ID.UNYX', 'ID_UNYX'); + String restoreIDUNYX(String text) => text.replaceAll('ID_UNYX', 'ID.UNYX'); + Future processBuffer(bool isChinese) async { + String txt = buffer.toString(); + // 先过滤 markdown 图片语法 + int imgStart = txt.indexOf('!['); + while (imgStart != -1) { + int imgEnd = txt.indexOf(')', imgStart); + if (imgEnd == -1) { + // 图片语法未闭合,缓存剩余部分 + buffer.clear(); + buffer.write(txt.substring(imgStart)); + return; + } + // 移除图片语法 + txt = txt.substring(0, imgStart) + txt.substring(imgEnd + 1); + imgStart = txt.indexOf('!['); + } + // 彻底移除 markdown 有序/无序列表序号(如 1.、2.、-、*、+) + txt = txt.replaceAll(RegExp(r'(^|\n)[ \t]*[0-9]+\.[ \t]*'), '\n'); + txt = txt.replaceAll(RegExp(r'(^|\n)[ \t]*[-\*\+][ \t]+'), '\n'); + // 分句符 + RegExp enders = isChinese ? zhEnders : enEnders; + int lastEnd = 0; + // 本地缓存句子 + List sentences = []; + for (final match in enders.allMatches(txt)) { + int endIndex = match.end; + String sentence = txt.substring(lastEnd, endIndex).trim(); + if (sentence.isNotEmpty) { + sentences.add(sentence); + } + lastEnd = endIndex; + } + // 只在达到完整句子时调用 TtsUtil.send + for (final s in sentences) { + String ttsStr=CommonUtil.cleanText(s, true); + // print("发送数据到TTS: $ttsStr"); + TtsUtil.send(ttsStr); + } + // 缓存剩余不完整部分 + String remain = txt.substring(lastEnd).trim(); + buffer.clear(); + if (remain.isNotEmpty) { + buffer.write(remain); + } + } _currentClient = HttpClient(); try { final chatUri = Uri.parse('http://143.64.185.20:18606/chat'); @@ -74,27 +126,12 @@ class ChatSseService { } if (jsonData['event'].toString().contains('message')) { final textChunk = - jsonData.containsKey('answer') ? jsonData['answer'] : ''; + jsonData.containsKey('answer') ? jsonData['answer'] : ''; if (_isAborted) { break; } - tempText += textChunk; - if (tempText.contains("ID.")) { - tempText = tempText.replaceAllMapped( - RegExp(r'ID\.', caseSensitive: false), (m) => 'ID '); - } - int endIndex = _getCompleteTextEndIndex(tempText); - String completeText = CommonUtil.cleanText(tempText.substring(0, endIndex).trim(), true); - if (completeText.isNotEmpty) { - if (_isFirstData && _startTtsFuture != null) { - await _startTtsFuture; - _isFirstData = false; - } - completeText += isChinese ? ',' : ','; - print("----------------------Send text: " + completeText); - TtsUtil.send(completeText); - } - tempText = tempText.substring(endIndex).trim(); + buffer.write(textChunk); + await processBuffer(isChinese); responseText += textChunk; onStreamResponse(messageId, responseText, false); } @@ -109,7 +146,6 @@ class ChatSseService { } catch (e) { // todo } finally { - print("------------------------------finally"); resetRequest(); } }