%% 方案A — 坐席端 Web Speech API 实时转写时序图 sequenceDiagram participant U as 坐席 participant RB as ReplyBox.vue participant USR as useSpeechRecognition participant SR as SpeechRecognition Note over U,SR: 阶段1:初始化 RB->>USR: useSpeechRecognition('zh-CN') USR->>USR: 检查 window.SpeechRecognition || webkitSpeechRecognition alt 浏览器不支持 USR-->>RB: state.isSupported = false RB->>RB: 语音按钮显示为禁用/隐藏 else 浏览器支持 USR->>USR: state.isSupported = true end Note over U,SR: 阶段2:开始识别 U->>RB: 点击语音按钮 🎤 RB->>USR: start() USR->>SR: new SpeechRecognition() USR->>SR: lang='zh-CN', continuous=true, interimResults=true USR->>SR: 注册 onresult / onerror / onend 回调 USR->>SR: start() SR-->>USR: onstart 触发 USR-->>RB: state.isListening = true RB->>RB: 按钮变红 + textarea 显示光标 + 提示"正在聆听..." Note over U,SR: 阶段3:实时转写(边说边出字) U->>SR: 说话:"帮我查一下" SR-->>USR: onresult(event) — interimResults (isFinal=false) USR->>USR: state.interimText = "帮我查一下" USR-->>RB: 实时更新 textarea(灰色临时文字) RB->>RB: inputText.value = finalText + interimText U->>SR: 继续说话:"帮我查一下密码" SR-->>USR: onresult(event) — final result (isFinal=true) USR->>USR: state.finalText += "帮我查一下密码" USR-->>RB: 确定文字追加到 textarea RB->>RB: inputText.value = finalText Note over U,SR: 阶段4:停止识别 U->>RB: 再次点击语音按钮 RB->>USR: stop() USR->>SR: stop() SR-->>USR: onend 触发 USR-->>RB: state.isListening = false RB->>RB: 按钮恢复 + textarea 保持已识别文字 Note over U,SR: 异常分支 alt 识别出错 SR-->>USR: onerror(event) — error='not-allowed' USR-->>RB: showToast("麦克风权限被拒绝") end alt 用户长时间不说话 SR-->>USR: onend 自动触发(超时停止) USR-->>RB: state.isListening = false end