From dde2895f13489e5dd12ab8c4371ea46058173a1b Mon Sep 17 00:00:00 2001 From: taiyi Date: Sun, 12 Apr 2026 19:06:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=AD=E9=9F=B3=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E5=92=8C=E5=AE=9E=E6=97=B6=E8=81=8A=E5=88=87=E5=85=A5?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/ChatView.vue | 61 +++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/frontend/src/views/ChatView.vue b/frontend/src/views/ChatView.vue index 6fed18d..f332bd6 100644 --- a/frontend/src/views/ChatView.vue +++ b/frontend/src/views/ChatView.vue @@ -43,7 +43,7 @@
@@ -1263,7 +1263,51 @@ export default { localStorage.setItem('selectedPet', JSON.stringify(pet)) } - const selectPet = (pet) => { + const refreshActiveVoiceModeWithCurrentPet = async () => { + // 切换主角后,重建当前语音会话,确保音色/人设使用新主角配置 + if (chatMode.value === 'call' && isInCall.value) { + chatStore.exitRealtimeCallMode() + stopCallTimer() + + const callConfig = { + speaker: currentPet.value?.volcano_voice_id || 'zh_female_vv_jupiter_bigtts', + model: currentPet.value?.volcano_model_version || 'O', + bot_name: currentPet.value?.volcano_bot_name || currentPet.value?.name || 'AI助手', + system_role: currentPet.value?.volcano_system_role || currentPet.value?.global_prompt || '你是一个友善的AI助手,用简洁自然的语言和用户交流。', + character_manifest: currentPet.value?.volcano_character_manifest || '', + speaking_style: '语气自然亲切,回复简洁', + hello_text: `你好!我是${currentPet.value?.volcano_bot_name || currentPet.value?.name || 'AI助手'},有什么可以帮助你的吗?` + } + + const success = await chatStore.enterRealtimeCallMode(callConfig) + if (success) { + isInCall.value = true + startCallTimer() + await startRecording() + } else { + await switchToTextMode() + ElMessage.warning('已切换主角,但实时通话重连失败,已回到文字模式') + } + return + } + + if (chatMode.value === 'voice') { + chatStore.exitVoiceChatMode() + await chatStore.connectVoiceWebSocket() + await new Promise(resolve => setTimeout(resolve, 300)) + + await chatStore.startVoiceSession({ + speaker: currentPet.value?.volcano_voice_id || 'zh_female_vv_jupiter_bigtts', + model: currentPet.value?.volcano_model_version || 'O', + bot_name: currentPet.value?.volcano_bot_name || currentPet.value?.name || 'AI助手', + system_role: currentPet.value?.volcano_system_role || currentPet.value?.global_prompt || '', + character_manifest: currentPet.value?.volcano_character_manifest || '', + input_mod: 'keep_alive' + }) + } + } + + const selectPet = async (pet) => { currentPet.value = pet const petBinding = backgroundPets.value.find(binding => binding.pet.id === pet.id) if (petBinding) { @@ -1283,7 +1327,14 @@ export default { selectedHistoryPetId.value = pet.id } saveChatConfig() - ElMessage.success(`已切换到${pet.name}`) + + try { + await refreshActiveVoiceModeWithCurrentPet() + ElMessage.success(`已切换到${pet.name}`) + } catch (err) { + console.error('切换主角后重建语音会话失败:', err) + ElMessage.warning(`已切换到${pet.name},但语音会话重建失败`) + } } const togglePetSelector = () => { @@ -1346,11 +1397,15 @@ export default { await stopRecording() } if (chatMode.value === 'voice') { + // 退出语音模式时主动销毁会话,避免下次进入沿用旧主角音色 + chatStore.exitVoiceChatMode() await switchToTextMode() } else { try { const hasPermission = await chatStore.requestMicrophonePermission() if (hasPermission) { + // 进入语音模式前先清理历史语音会话,确保按当前主角重新建会话 + chatStore.exitVoiceChatMode() chatMode.value = 'voice' } } catch (error) {