diff --git a/src/renderer/src/components/ChatPanel.vue b/src/renderer/src/components/ChatPanel.vue index 4eef92d..832a0c7 100644 --- a/src/renderer/src/components/ChatPanel.vue +++ b/src/renderer/src/components/ChatPanel.vue @@ -869,7 +869,7 @@ onUnmounted(() => { .q-input { width: 100%; box-sizing: border-box; - height: 96px; min-height: 0; + height: 96px; min-height: 0; max-height: 96px; border: 2px solid var(--line-2); border-radius: var(--radius); padding: 16px 20px; font-family: inherit; font-size: 20px; line-height: 1.5; resize: none; diff --git a/src/renderer/src/utils/tts.ts b/src/renderer/src/utils/tts.ts index b9c21f0..5f29ce7 100644 --- a/src/renderer/src/utils/tts.ts +++ b/src/renderer/src/utils/tts.ts @@ -152,9 +152,12 @@ export class TtsPlayer { const pending = this.computePendingDelta(plain) if (!pending) return - // 直接用当前未朗读的纯文本替换缓冲区,避免旧 buffer 因格式被二次清洗而变得陈旧/重复 + // pending 是相对 lastSpokenPlain 的增量(已排除重复),累加进缓冲区而不是替换—— + // 替换会丢失上一次 append() 里 processBuffer() 还没来得及提取成句子的剩余文本 + // (比如队列满了暂停提取,或者还没遇到句尾标点),高频小增量调用下会导致正文 + // 大量丢字,只有 flush() 时残留的最后一小段才会被朗读。 this.lastSpokenPlain = plain - this.buffer = pending + this.buffer += pending this.recordAppend(pending.length) this.processBuffer() }