diff --git a/src/views/Speaking.vue b/src/views/Speaking.vue index 5f28ce6..2016758 100644 --- a/src/views/Speaking.vue +++ b/src/views/Speaking.vue @@ -340,10 +340,14 @@ const sendMessage = async () => { isSending.value = true; // 插入用户消息 - const userMsg = { id: ++msgIdCounter, role: "user", content: text, audioUrl: null, isPlaying: false, isLoading: false }; + const userMsgId = ++msgIdCounter; + const userMsg = { id: userMsgId, role: "user", content: text, audioUrl: null, isPlaying: false, isLoading: false }; messages.value.push(userMsg); await scrollToBottom(); + // 用户消息 TTS(不阻塞主流程) + synthesizeAndPlay(text, userMsgId).catch((e) => console.error("User TTS error:", e)); + // 插入 AI loading 占位 const aiMsgId = ++msgIdCounter; const aiMsg = { id: aiMsgId, role: "assistant", content: "", audioUrl: null, isPlaying: false, isLoading: true }; @@ -701,9 +705,10 @@ onUnmounted(() => { {{ msg.content }} - -
- - 合成中...
@@ -991,6 +995,17 @@ onUnmounted(() => { .tts-hint { font-size: 0.75rem; color: var(--text-secondary); } +/* 用户消息播放按钮右对齐 */ +.user-audio-controls { justify-content: flex-end; } +.user-audio-controls .play-btn { + background: rgba(139,92,246,0.2); + border-color: rgba(139,92,246,0.4); + color: #a78bfa; +} +.user-audio-controls .play-btn:hover { background: rgba(139,92,246,0.35); } +.user-audio-controls .play-btn.playing { background: rgba(139,92,246,0.3); border-color: #a78bfa; } +.user-audio-controls .wave-bars span { background: #a78bfa; } + /* Wave bars animation */ .wave-bars { display: flex;