diff --git a/src/renderer/src/components/ChatPanel.vue b/src/renderer/src/components/ChatPanel.vue index 0261da1..112f248 100644 --- a/src/renderer/src/components/ChatPanel.vue +++ b/src/renderer/src/components/ChatPanel.vue @@ -503,6 +503,18 @@ async function toggleTts(): Promise { } else if (store.rawAnswer && !store.querying) { // 答案已显示完毕时打开 TTS,立即从头播 ttsPlayer.speakWithAnnouncement(store.rawAnswer) + } else if (store.querying) { + // 提问还在流式生成中途打开 TTS:ttsPlayer 内部的 rawText 此前因为 + // enabled=false 一直没有累积(append() 一开头就 return),直接等后续 + // onDelta 的话只会从"此刻之后的新增量"开始朗读,把已经显示在屏幕上但 + // 开 TTS 之前生成的那部分正文漏掉。这里先播"开始播报"提示音(跟正常 + // 提问开始时一致),再用 append() 把已生成的全文"补喂"一遍,相当于 + // 告诉播放器"这就是从头到现在的内容",让它从头开始排队朗读;之后 + // onDelta 送来的增量会在此基础上正常追加,衔接不会重复。此刻还没有 + // 任何输出(刚发问、第一个 delta 还没到)时 append 传空字符串会被 + // append() 内部的 if (!text) return 挡掉,不会误触发。 + ttsPlayer.announceStart() + ttsPlayer.append(store.rawAnswer) } }