From e9cf65a41c99b116709ed3289c6b5bb387da6009 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 9 Jun 2026 11:42:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tongji/composables/useDietAi.js | 2 + .../tongji/composables/useSpeechToText.js | 60 +++++++++++++++++-- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/TUICallKit-Vue3/tongji/composables/useDietAi.js b/TUICallKit-Vue3/tongji/composables/useDietAi.js index 6256bc34..477836a7 100644 --- a/TUICallKit-Vue3/tongji/composables/useDietAi.js +++ b/TUICallKit-Vue3/tongji/composables/useDietAi.js @@ -207,6 +207,8 @@ export function useDietAi(proxy, { diagnosisId, showUserToast, formatUserMessage return } if (!diagnosisId.value) return + // 发送后立即清空输入框 + dietAiAskText.value = '' dietAiAsking.value = true dietAiAskResult.value = { advice: '', level: '', level_label: '', portion: '', food: '' } try { diff --git a/TUICallKit-Vue3/tongji/composables/useSpeechToText.js b/TUICallKit-Vue3/tongji/composables/useSpeechToText.js index fa79fde2..ba943edd 100644 --- a/TUICallKit-Vue3/tongji/composables/useSpeechToText.js +++ b/TUICallKit-Vue3/tongji/composables/useSpeechToText.js @@ -18,6 +18,10 @@ export function useSpeechToText({ onResult, showToast } = {}) { let holdSessionId = 0 let startRequested = false let recordAuthorized = null + // WechatSI 录音管理器是全局单例:跨页面/快速点按可能残留会话, + // 用以下两个标记把 start/stop 串行化,避免 "please stop after start" + let managerRecording = false + let pendingStartSession = 0 function notify(msg) { if (!msg) return @@ -43,7 +47,7 @@ export function useSpeechToText({ onResult, showToast } = {}) { function stopListening() { // #ifdef MP-WEIXIN - if (wxRecordManager && (sttListening.value || startRequested)) { + if (wxRecordManager && (sttListening.value || startRequested || managerRecording)) { try { wxRecordManager.stop() } catch (e) {} @@ -95,22 +99,42 @@ export function useSpeechToText({ onResult, showToast } = {}) { // #endif } - function startWechatRecord(session) { - // #ifdef MP-WEIXIN + // #ifdef MP-WEIXIN + function actuallyStartWechat(session) { if (!wxRecordManager || session !== holdSessionId || !sttHolding.value) { return } try { startRequested = true + managerRecording = true wxRecordManager.start({ duration: 60000, lang: 'zh_CN' }) } catch (e) { startRequested = false + managerRecording = false sttHolding.value = false notify('无法开始录音') } + } + // #endif + + function startWechatRecord(session) { + // #ifdef MP-WEIXIN + if (!wxRecordManager || session !== holdSessionId || !sttHolding.value) { + return + } + // 上一段会话还没结束(含全局单例残留):先停止并排队, + // 待 onStop 回调后再真正开始,避免 "please stop after start" + if (managerRecording || startRequested) { + pendingStartSession = session + try { + wxRecordManager.stop() + } catch (e) {} + return + } + actuallyStartWechat(session) // #endif } @@ -161,11 +185,13 @@ export function useSpeechToText({ onResult, showToast } = {}) { /** 松手结束:手指抬起 */ function endHoldSpeech() { - if (!sttHolding.value && !sttListening.value && !startRequested) { + if (!sttHolding.value && !sttListening.value && !startRequested && !managerRecording) { return } sttHolding.value = false - if (sttListening.value || startRequested) { + // 松手后不再补开排队的录音 + pendingStartSession = 0 + if (sttListening.value || startRequested || managerRecording) { stopListening() return } @@ -180,6 +206,7 @@ export function useSpeechToText({ onResult, showToast } = {}) { sttSupported.value = !!wxRecordManager wxRecordManager.onStart = () => { + managerRecording = true if (!sttHolding.value) { try { wxRecordManager.stop() @@ -190,15 +217,35 @@ export function useSpeechToText({ onResult, showToast } = {}) { sttListening.value = true } wxRecordManager.onStop = (res) => { + managerRecording = false sttListening.value = false startRequested = false + // 有排队的开始请求(残留会话已停止 / 用户仍按住):现在再真正开始 + if (pendingStartSession && pendingStartSession === holdSessionId && sttHolding.value) { + const s = pendingStartSession + pendingStartSession = 0 + actuallyStartWechat(s) + return + } + pendingStartSession = 0 emitResult(res?.result) } wxRecordManager.onError = (res) => { + managerRecording = false sttListening.value = false startRequested = false + const msg = (res && res.msg) || '' + // 上一段未停止就再次 start 触发:停止后若仍按住则自动重试,不打扰用户 + if (/please stop after start/i.test(msg)) { + try { + wxRecordManager.stop() + } catch (e) {} + pendingStartSession = sttHolding.value ? holdSessionId : 0 + return + } + pendingStartSession = 0 sttHolding.value = false - notify(res?.msg || '语音识别失败') + notify(msg || '语音识别失败') } } catch (e) { console.warn('WechatSI record recognition not available', e) @@ -246,6 +293,7 @@ export function useSpeechToText({ onResult, showToast } = {}) { onUnmounted(() => { sttHolding.value = false holdSessionId += 1 + pendingStartSession = 0 stopListening() })