opt:语音控制功能-第一次联调测试修改

This commit is contained in:
zhaoyf
2026-04-22 10:47:24 +08:00
parent 5d83cceca5
commit bced456945
8 changed files with 178 additions and 130 deletions

View File

@@ -133,10 +133,18 @@
<span>正在录音... {{ recordingDuration }}"</span>
</div>
<!-- 识别中提示 -->
<div v-if="isTranscribing" class="transcribing-hint">
<div class="transcribing-spinner">
<i class="el-icon-loading" />
</div>
<span>正在识别录音内容...</span>
</div>
<!-- 录音按钮 -->
<div
class="record-button"
:class="{ 'recording': isRecording, 'disabled': !isConnected || isProcessing }"
:class="{ 'recording': isRecording, 'disabled': !isConnected || isProcessing || isTranscribing }"
@mousedown="startRecording"
@mouseup="stopRecording"
@mouseleave="isRecording && stopRecording()"
@@ -240,7 +248,7 @@ export default {
this.isConnected = false
},
// 处理WebSocket消息
// 处理WebSocket消息 - 只处理user和system两种类型
handleWebSocketMessage(data) {
// 判断数据类型
if (data instanceof ArrayBuffer || data instanceof Blob) {
@@ -252,14 +260,21 @@ export default {
const message = JSON.parse(data)
console.log('收到WebSocket消息:', message)
if (message.type === 'error') {
this.handleError(message.message || '识别失败')
} else if (message.type === 'transcription') {
// 语音识别结果
this.handleTranscriptionResult(message)
} else if (message.type === 'response') {
// 系统文本回复
this.handleSystemTextResponse(message)
// 只处理user和system两种类型
if (message.type === 'user') {
// 用户识别结果消息
this.handleUserMessage(message)
} else if (message.type === 'system') {
// 系统回复消息
this.handleSystemMessage(message)
} else if (message.type === 'error') {
// 错误消息作为系统消息显示
this.addMessage({
role: 'system',
type: 'text',
content: message.message || '处理失败',
timestamp: Date.now()
})
}
} catch (e) {
console.error('解析WebSocket消息失败:', e)
@@ -267,9 +282,9 @@ export default {
}
},
// 处理语音识别结果
handleTranscriptionResult(message) {
const text = message.text || message.transcript || ''
// 处理用户消息(语音识别结果
handleUserMessage(message) {
const text = message.message
if (!text) return
this.isTranscribing = false
@@ -284,6 +299,19 @@ export default {
})
},
// 处理系统消息
handleSystemMessage(message) {
this.isProcessing = false
// 添加系统消息
this.addMessage({
role: 'system',
type: 'text',
content: message.message,
timestamp: Date.now()
})
},
// 确认消息 - 用户点击确认按钮后执行
async confirmMessage(message) {
if (!message || !message.content) return
@@ -294,14 +322,16 @@ export default {
// 执行confirm函数
try {
const res = await confirm(message.content)
const res = await confirm({
text: message.content
})
this.isProcessing = false
// 添加系统回复消息
this.addMessage({
role: 'system',
type: 'text',
content: res.data || '收到您的消息',
content: res.text,
timestamp: Date.now()
})
} catch (error) {
@@ -328,18 +358,7 @@ export default {
this.scrollToBottom()
},
// 处理系统文本回复
handleSystemTextResponse(message) {
this.isProcessing = false
this.addMessage({
role: 'system',
type: 'text',
content: message.text || message.content || '收到您的消息',
timestamp: Date.now()
})
},
// 处理系统语音回复
// 处理系统语音回复(二进制数据)
async handleSystemVoiceResponse(audioData) {
try {
// 创建音频URL
@@ -360,7 +379,7 @@ export default {
role: 'system',
type: 'voice',
audioUrl: audioUrl,
duration: '3"', // 这里应该根据实际音频时长计算
duration: '3"',
timestamp: Date.now()
}
this.addMessage(message)
@@ -372,27 +391,7 @@ export default {
}
},
// 处理错误
handleError(message) {
this.isProcessing = false
this.isTranscribing = false
this.addMessage({
role: 'system',
type: 'text',
content: message || '服务出现错误',
timestamp: Date.now()
})
// 更新最后一条用户消息状态
// const lastUserMessage = this.messages.filter(m => m.role === 'user').pop()
// if (lastUserMessage) {
// lastUserMessage.isTranscribing = false
// lastUserMessage.content = message
// lastUserMessage.type = 'text'
// }
//
// this.$message.error(message)
},
// 添加消息
addMessage(message) {
@@ -1006,31 +1005,51 @@ export default {
border-top: 1px solid #ebeef5;
background: #fff;
.recording-hint {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
color: #F56C6C;
font-size: 14px;
.recording-wave {
.recording-hint {
display: flex;
align-items: center;
margin-right: 8px;
justify-content: center;
margin-bottom: 10px;
color: #F56C6C;
font-size: 14px;
span {
width: 4px;
height: 20px;
background: #F56C6C;
margin: 0 2px;
border-radius: 2px;
animation: waveAnimation 0.5s ease-in-out infinite;
.recording-wave {
display: flex;
align-items: center;
margin-right: 8px;
span {
width: 4px;
height: 20px;
background: #F56C6C;
margin: 0 2px;
border-radius: 2px;
animation: waveAnimation 0.5s ease-in-out infinite;
}
}
}
}
.record-button {
.transcribing-hint {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px;
color: #409EFF;
font-size: 14px;
.transcribing-spinner {
display: flex;
align-items: center;
margin-right: 8px;
i {
font-size: 18px;
animation: rotating 1s linear infinite;
}
}
}
.record-button {
display: flex;
align-items: center;
justify-content: center;