|
@@ -2027,16 +2027,28 @@ export const ChatBotPage = () => {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!isConnected) {
|
|
|
|
|
- antMessage.warning('语音服务正在重连,请稍后再试');
|
|
|
|
|
|
|
+ // 🔥 改进:允许在连接建立过程中开始录音
|
|
|
|
|
+ // 1. 如果 WebSocket 不存在,说明还未初始化,提示等待
|
|
|
|
|
+ // 2. 如果 WebSocket 存在,检查是否正在连接中或已就绪
|
|
|
|
|
+ // 3. 如果正在连接中(CONNECTING)或已就绪(OPEN),允许开始录音,消息会被缓冲
|
|
|
|
|
+ // 4. 这样用户无感知,业务也能正常运行
|
|
|
|
|
+ if (!wsRef.current) {
|
|
|
|
|
+ antMessage.warning('语音服务初始化中,请稍后重试');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!wsRef.current?.isReady()) {
|
|
|
|
|
- antMessage.warning('语音服务正在恢复,请稍后重试');
|
|
|
|
|
|
|
+ // 检查 WebSocket 状态:如果正在连接中或已就绪,允许开始录音
|
|
|
|
|
+ const isConnecting = wsRef.current.isConnecting();
|
|
|
|
|
+ const isReady = wsRef.current.isReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果既不在连接中,也不已就绪,且 isConnected 为 false,说明连接失败
|
|
|
|
|
+ if (!isConnecting && !isReady && !isConnected) {
|
|
|
|
|
+ antMessage.warning('语音服务正在重连,请稍后再试');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 如果正在连接中或已就绪,允许开始录音(消息会被缓冲)
|
|
|
|
|
+
|
|
|
// 保存旧请求ID(用于取消和过滤旧消息)
|
|
// 保存旧请求ID(用于取消和过滤旧消息)
|
|
|
const oldRequestId = currentRequestId;
|
|
const oldRequestId = currentRequestId;
|
|
|
const wasPlaying = currentState === 'playing' || currentState === 'sending';
|
|
const wasPlaying = currentState === 'playing' || currentState === 'sending';
|
|
@@ -2109,13 +2121,14 @@ export const ChatBotPage = () => {
|
|
|
setRecognizedText('');
|
|
setRecognizedText('');
|
|
|
|
|
|
|
|
// 准备移动端音频(在设置状态之后,避免阻塞状态更新)
|
|
// 准备移动端音频(在设置状态之后,避免阻塞状态更新)
|
|
|
|
|
+ // 🔥 改进:静默准备音频环境,不显示提示,用户无感知
|
|
|
if (isMobileDevice() && !mobileAudioPreparedRef.current) {
|
|
if (isMobileDevice() && !mobileAudioPreparedRef.current) {
|
|
|
// 异步准备,不阻塞录音开始
|
|
// 异步准备,不阻塞录音开始
|
|
|
prepareMobileAudio()
|
|
prepareMobileAudio()
|
|
|
.then(() => {
|
|
.then(() => {
|
|
|
requestVolumeControl();
|
|
requestVolumeControl();
|
|
|
mobileAudioPreparedRef.current = true;
|
|
mobileAudioPreparedRef.current = true;
|
|
|
- antMessage.info('请确保设备音量已调高');
|
|
|
|
|
|
|
+ // 移除提示,让用户无感知,业务功能正常(prepareMobileAudio 和 requestVolumeControl 仍会执行)
|
|
|
})
|
|
})
|
|
|
.catch(() => {
|
|
.catch(() => {
|
|
|
// 准备移动端音频失败,静默处理
|
|
// 准备移动端音频失败,静默处理
|
|
@@ -2175,8 +2188,13 @@ export const ChatBotPage = () => {
|
|
|
|
|
|
|
|
stopRecordingTimer();
|
|
stopRecordingTimer();
|
|
|
|
|
|
|
|
- if (!isConnected) {
|
|
|
|
|
- antMessage.error('语音服务未连接,请重新录音发送');
|
|
|
|
|
|
|
+ // 🔥 改进:允许在连接建立过程中发送录音
|
|
|
|
|
+ // 1. 如果 WebSocket 不存在,说明还未初始化,提示错误
|
|
|
|
|
+ // 2. 如果 WebSocket 存在,检查是否正在连接中或已就绪
|
|
|
|
|
+ // 3. 如果正在连接中(CONNECTING)或已就绪(OPEN),允许发送,消息会被缓冲
|
|
|
|
|
+ // 4. 这样用户无感知,业务也能正常运行
|
|
|
|
|
+ if (!wsRef.current) {
|
|
|
|
|
+ antMessage.error('语音服务初始化中,请重新录音发送');
|
|
|
recorderRef.current?.stop();
|
|
recorderRef.current?.stop();
|
|
|
resetFrequencyVisualization();
|
|
resetFrequencyVisualization();
|
|
|
// 清理情绪 GIF 切换定时器
|
|
// 清理情绪 GIF 切换定时器
|
|
@@ -2186,13 +2204,18 @@ export const ChatBotPage = () => {
|
|
|
}
|
|
}
|
|
|
// 恢复默认头像 GIF
|
|
// 恢复默认头像 GIF
|
|
|
showDefaultGif();
|
|
showDefaultGif();
|
|
|
- performanceLogger.clearRequest(currentRequestId, 'websocket_disconnected_before_send');
|
|
|
|
|
|
|
+ performanceLogger.clearRequest(currentRequestId, 'websocket_unready_before_send');
|
|
|
reset();
|
|
reset();
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!wsRef.current?.isReady()) {
|
|
|
|
|
- antMessage.error('语音服务尚未准备完成,请重新录音发送');
|
|
|
|
|
|
|
+ // 检查 WebSocket 状态:如果正在连接中或已就绪,允许发送
|
|
|
|
|
+ const isConnecting = wsRef.current.isConnecting();
|
|
|
|
|
+ const isReady = wsRef.current.isReady();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果既不在连接中,也不已就绪,且 isConnected 为 false,说明连接失败
|
|
|
|
|
+ if (!isConnecting && !isReady && !isConnected) {
|
|
|
|
|
+ antMessage.error('语音服务未连接,请重新录音发送');
|
|
|
recorderRef.current?.stop();
|
|
recorderRef.current?.stop();
|
|
|
resetFrequencyVisualization();
|
|
resetFrequencyVisualization();
|
|
|
// 清理情绪 GIF 切换定时器
|
|
// 清理情绪 GIF 切换定时器
|
|
@@ -2202,10 +2225,12 @@ export const ChatBotPage = () => {
|
|
|
}
|
|
}
|
|
|
// 恢复默认头像 GIF
|
|
// 恢复默认头像 GIF
|
|
|
showDefaultGif();
|
|
showDefaultGif();
|
|
|
- performanceLogger.clearRequest(currentRequestId, 'websocket_unready_before_send');
|
|
|
|
|
|
|
+ performanceLogger.clearRequest(currentRequestId, 'websocket_disconnected_before_send');
|
|
|
reset();
|
|
reset();
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 如果正在连接中或已就绪,允许发送(消息会被缓冲)
|
|
|
|
|
|
|
|
timingRef.current.recordEnd = Date.now();
|
|
timingRef.current.recordEnd = Date.now();
|
|
|
sendTimeRef.current = Date.now();
|
|
sendTimeRef.current = Date.now();
|