feat: 用户语音消息支持点击播放

This commit is contained in:
2026-04-21 18:45:42 +08:00
parent 04e8405558
commit 0dced68876
2 changed files with 78 additions and 7 deletions

Binary file not shown.

View File

@@ -196,6 +196,40 @@
line-height: 1.5;
}
.audio-content {
display: flex;
align-items: center;
}
.play-btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 15px;
border-radius: 20px;
border: none;
background: rgba(255,255,255,0.2);
cursor: pointer;
transition: all 0.2s;
font-size: 14px;
}
.play-btn:hover {
background: rgba(255,255,255,0.3);
}
.play-btn.playing {
background: rgba(255,255,255,0.4);
}
.play-icon {
font-size: 16px;
}
.duration {
color: rgba(255,255,255,0.8);
}
.loading {
display: flex;
justify-content: center;
@@ -470,6 +504,9 @@
try {
showLoading();
// 计算音频时长
const duration = Math.round(recordedBuffers.reduce((acc, buf) => acc + buf.length, 0) / 16000);
const formData = new FormData();
formData.append('audio', audioBlob, 'recording.wav');
if (conversationId) {
@@ -489,8 +526,8 @@
const data = await resp.json();
conversationId = data.conversation_id;
// 显示消息
addMessage('user', '🎵 语音消息');
// 显示消息(带音频播放)
addMessage('user', audioBlob, duration);
addMessage('assistant', data.reply);
recordStatus.textContent = '点击按钮开始录音';
@@ -503,7 +540,7 @@
}
// 添加消息
function addMessage(role, content) {
function addMessage(role, content, audioDuration = null) {
// 移除提示
const hint = chatSection.querySelector('.hint');
if (hint) hint.remove();
@@ -514,16 +551,50 @@
const msg = document.createElement('div');
msg.className = `message ${role}`;
// 用户消息可能是音频
if (role === 'user' && content instanceof Blob) {
const audioUrl = URL.createObjectURL(content);
const durationText = audioDuration ? `${audioDuration}s` : '';
msg.innerHTML = `
<div class="role">我</div>
<div class="content audio-content">
<button class="play-btn" onclick="playAudio('${audioUrl}', this)">
<span class="play-icon">▶️</span>
<span class="duration">${durationText}</span>
</button>
</div>
`;
} else {
msg.innerHTML = `
<div class="role">${role === 'user' ? '我' : 'AI'}</div>
<div class="content">${content}</div>
`;
}
chatSection.appendChild(msg);
// 滚动到底部
chatSection.scrollTop = chatSection.scrollHeight;
}
// 播放音频
function playAudio(audioUrl, btn) {
const audio = new Audio(audioUrl);
const icon = btn.querySelector('.play-icon');
audio.onplay = () => {
icon.textContent = '🔊';
btn.classList.add('playing');
};
audio.onended = () => {
icon.textContent = '▶️';
btn.classList.remove('playing');
};
audio.play();
}
// 显示加载
function showLoading() {
const hint = chatSection.querySelector('.hint');