diff --git a/.gitignore b/.gitignore
index 84db5d5..1ce4fd3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -72,4 +72,5 @@ coverage/
# UniApp specific
unpackage/
dist/
-.history/
\ No newline at end of file
+.history/
+purple-energy-visualizer/
\ No newline at end of file
diff --git a/package.json b/package.json
index 7459470..51f305b 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
"@dcloudio/uni-quickapp-webview": "3.0.0-4060420250429001",
"ant-design-vue": "^4.2.6",
"pinia": "^2.1.7",
+ "three": "^0.181.2",
"vue": "^3.4.21",
"vue-i18n": "^9.1.9"
},
diff --git a/src/components/ChatBox.vue b/src/components/ChatBox.vue
index c101c9c..72d0656 100644
--- a/src/components/ChatBox.vue
+++ b/src/components/ChatBox.vue
@@ -27,9 +27,53 @@
+
+
+
+
+
+
+
+
+
+
+ {{ voiceStateText }}
+
+
+
+
+
+
+
+
+
+ {{ voiceHintText }}
+
+
+
+ {{ isVoiceRecording ? '⏹' : '🎙️' }}
+ {{ isVoiceRecording ? '停止并发送' : '开始录音' }}
+
+
+
+
+ ⏳
+ {{ voiceState === 'thinking' ? '处理中...' : '回复中...' }}
+
+
+
+
+
+ {{ isVoiceMode ? '💬' : '🎧' }}
+
+
{
return template?.templateName || '默认智能体';
});
+// 🎧 语音模式状态文本
+const voiceStateText = computed(() => {
+ const stateMap = {
+ idle: '准备就绪',
+ listening: '正在倾听...',
+ thinking: '思考中...',
+ speaking: '回复中...'
+ };
+ return stateMap[voiceState.value] || '准备就绪';
+});
+
+// 🎧 语音模式提示文本
+const voiceHintText = computed(() => {
+ const hintMap = {
+ idle: '点击下方按钮开始录音',
+ listening: '说完后再次点击按钮发送',
+ thinking: 'AI 正在思考你的问题...',
+ speaking: 'AI 正在回复...'
+ };
+ return hintMap[voiceState.value] || '点击下方按钮开始录音';
+});
+
+// 🎧 语音按钮文本
+const voiceButtonText = computed(() => {
+ if (voiceState === 'idle' && !isVoiceRecording.value) {
+ return '开始录音';
+ } else if (voiceState === 'listening' || isVoiceRecording.value) {
+ return '停止并发送';
+ }
+ return '处理中...';
+});
+
// 处理头像URL
const processedAvatar = computed(() => {
return getResourceUrl(currentCharacter.value.avatar);
@@ -488,11 +574,21 @@ const initRecorder = () => {
recorderManager.value = uni.getRecorderManager();
recorderManager.value.onStart(() => {
+ console.log('录音开始');
});
recorderManager.value.onStop((res) => {
- if (!isRecordingCancelled.value) {
- handleVoiceMessage(res.tempFilePath);
+ // 判断是语音模式还是普通录音模式
+ if (isVoiceMode.value) {
+ // 语音模式:处理语音对话
+ if (isVoiceRecording.value) {
+ handleVoiceModeMessage(res.tempFilePath);
+ }
+ } else {
+ // 普通录音模式:原有逻辑
+ if (!isRecordingCancelled.value) {
+ handleVoiceMessage(res.tempFilePath);
+ }
}
});
@@ -502,6 +598,8 @@ const initRecorder = () => {
icon: 'none'
});
isActuallyRecording.value = false;
+ isVoiceRecording.value = false;
+ voiceState.value = 'idle';
});
// #endif
};
@@ -1162,6 +1260,261 @@ const clearContext = async () => {
}
});
};
+
+// 🎧 切换语音模式
+const toggleVoiceMode = () => {
+ isVoiceMode.value = !isVoiceMode.value;
+
+ if (isVoiceMode.value) {
+ // 进入语音模式
+ voiceState.value = 'idle';
+ uni.showToast({
+ title: '已切换到语音模式',
+ icon: 'none',
+ duration: 1500
+ });
+ } else {
+ // 退出语音模式
+ voiceState.value = 'idle';
+ uni.showToast({
+ title: '已切换到文本模式',
+ icon: 'none',
+ duration: 1500
+ });
+ }
+};
+
+// 🎧 切换录音状态(开始/停止录音)
+const toggleVoiceRecording = async () => {
+ if (voiceState.value === 'thinking' || voiceState.value === 'speaking') {
+ uni.showToast({
+ title: 'AI正在处理中,请稍候',
+ icon: 'none'
+ });
+ return;
+ }
+
+ if (!isVoiceRecording.value) {
+ // 开始录音
+ startVoiceRecording();
+ } else {
+ // 停止录音并发送
+ await stopVoiceRecordingAndSend();
+ }
+};
+
+// 🎧 开始录音
+const startVoiceRecording = () => {
+ // #ifdef MP-WEIXIN
+ uni.authorize({
+ scope: 'scope.record',
+ success: () => {
+ isVoiceRecording.value = true;
+ voiceState.value = 'listening';
+
+ recorderManager.value.start({
+ duration: 60000, // 最长60秒
+ sampleRate: 16000,
+ numberOfChannels: 1,
+ encodeBitRate: 96000,
+ format: 'aac' // AAC 格式(需要 ffmpeg 转换)
+ });
+
+ uni.showToast({
+ title: '开始录音',
+ icon: 'none',
+ duration: 1000
+ });
+ },
+ fail: () => {
+ uni.showModal({
+ title: '需要录音权限',
+ content: '请在设置中开启录音权限',
+ showCancel: false
+ });
+ }
+ });
+ // #endif
+
+ // #ifndef MP-WEIXIN
+ uni.showToast({
+ title: '语音功能仅支持微信小程序',
+ icon: 'none'
+ });
+ // #endif
+};
+
+// 🎧 停止录音并发送
+const stopVoiceRecordingAndSend = async () => {
+ // #ifdef MP-WEIXIN
+ recorderManager.value.stop();
+ // 停止后会触发 onStop 回调,在那里处理录音文件
+ // #endif
+
+ // #ifndef MP-WEIXIN
+ uni.showToast({
+ title: '语音功能仅支持微信小程序',
+ icon: 'none'
+ });
+ isVoiceRecording.value = false;
+ voiceState.value = 'idle';
+ // #endif
+};
+
+// 🎧 处理语音模式的录音消息
+const handleVoiceModeMessage = async (filePath) => {
+ isVoiceRecording.value = false;
+ voiceState.value = 'thinking';
+
+ try {
+ console.log('🎧 语音模式:开始处理录音文件', filePath);
+
+ // 调用后端voice-chat接口
+ const result = await voiceAPI.voiceChat(filePath, {
+ sessionId: conversationId.value, // 使用当前会话ID保持上下文
+ modelId: currentCharacter.value.modelId || 10,
+ templateId: currentCharacter.value.templateId || currentCharacter.value.roleId || 6,
+ ttsConfigId: currentCharacter.value.ttsId || null,
+ sttConfigId: currentCharacter.value.sttId || null,
+ useFunctionCall: false
+ });
+
+ if (result.success && result.data) {
+ const { sttResult, llmResult, ttsResult } = result.data;
+
+ console.log('🎧 STT识别结果:', sttResult?.text);
+ console.log('🎧 AI回复文本:', llmResult?.response);
+ console.log('🎧 TTS音频:', ttsResult?.audioBase64 ? '已获取' : '未获取');
+
+ // 切换到说话状态
+ voiceState.value = 'speaking';
+
+ // 播放AI返回的语音
+ if (ttsResult && ttsResult.audioBase64) {
+ // 如果有audioBase64,播放Base64音频
+ await playVoiceFromBase64(ttsResult.audioBase64, llmResult?.response);
+ } else if (ttsResult && ttsResult.audioPath) {
+ // 如果有audioPath,播放路径音频
+ const audioUrl = getResourceUrl(ttsResult.audioPath);
+ await playVoiceResponse(llmResult?.response, audioUrl);
+ } else {
+ // 没有音频,只显示文本
+ uni.showToast({
+ title: llmResult?.response || 'AI已回复',
+ icon: 'none',
+ duration: 2000
+ });
+ await sleep(2000);
+ }
+
+ // 可选:将对话记录到聊天列表
+ if (sttResult?.text) {
+ addMessage('user', sttResult.text);
+ }
+ if (llmResult?.response) {
+ const cleanedResponse = cleanText(llmResult.response);
+ await addSegmentedAIResponse(cleanedResponse);
+ }
+
+ } else {
+ // API调用失败
+ throw new Error(result.error?.message || '语音处理失败');
+ }
+
+ // 回到待机状态
+ voiceState.value = 'idle';
+
+ } catch (error) {
+ console.error('🎧 语音处理失败:', error);
+ voiceState.value = 'idle';
+
+ uni.showToast({
+ title: '语音处理失败: ' + (error.message || '未知错误'),
+ icon: 'none',
+ duration: 2000
+ });
+ }
+};
+
+// 🎧 播放Base64编码的音频
+const playVoiceFromBase64 = async (audioBase64, text = '') => {
+ return new Promise((resolve, reject) => {
+ // #ifdef MP-WEIXIN
+ try {
+ // 将Base64转换为临时文件
+ const fs = uni.getFileSystemManager();
+ const filePath = `${wx.env.USER_DATA_PATH}/voice_temp_${Date.now()}.wav`;
+
+ // 写入文件
+ fs.writeFile({
+ filePath: filePath,
+ data: audioBase64,
+ encoding: 'base64',
+ success: () => {
+ console.log('🎧 Base64音频已转换为文件:', filePath);
+
+ // 播放音频
+ if (audioContext.value) {
+ audioContext.value.destroy();
+ }
+
+ audioContext.value = uni.createInnerAudioContext();
+ audioContext.value.src = filePath;
+
+ audioContext.value.onPlay(() => {
+ console.log('🎧 开始播放AI语音');
+ });
+
+ audioContext.value.onEnded(() => {
+ console.log('🎧 AI语音播放完成');
+ resolve();
+ });
+
+ audioContext.value.onError((err) => {
+ console.error('🎧 语音播放失败:', err);
+ reject(err);
+ });
+
+ audioContext.value.play();
+ },
+ fail: (err) => {
+ console.error('🎧 Base64转文件失败:', err);
+ reject(err);
+ }
+ });
+ } catch (error) {
+ console.error('🎧 播放Base64音频异常:', error);
+ reject(error);
+ }
+ // #endif
+
+ // #ifndef MP-WEIXIN
+ uni.showToast({
+ title: '语音播放仅支持微信小程序',
+ icon: 'none'
+ });
+ resolve();
+ // #endif
+ });
+};
+
+// 🎧 取消录音
+const cancelVoiceRecording = () => {
+ if (!isVoiceRecording.value) return;
+
+ // #ifdef MP-WEIXIN
+ recorderManager.value.stop();
+ // #endif
+
+ isVoiceRecording.value = false;
+ voiceState.value = 'idle';
+
+ uni.showToast({
+ title: '已取消录音',
+ icon: 'none',
+ duration: 1000
+ });
+};
@@ -1863,4 +2216,296 @@ page {
color: #1a0b2e;
font-weight: bold;
}
+
+/* 🎧 语音模式切换按钮 */
+.voice-mode-toggle {
+ width: 56rpx;
+ height: 56rpx;
+ border-radius: 50%;
+ background: rgba(249, 224, 118, 0.15);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.3s;
+ flex-shrink: 0;
+}
+
+.voice-mode-toggle:active {
+ background: rgba(249, 224, 118, 0.3);
+ transform: scale(0.95);
+}
+
+.voice-mode-toggle .icon {
+ font-size: 28rpx;
+}
+
+/* 🎧 语音对话模式容器 */
+.voice-mode-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 48rpx 32rpx;
+}
+
+.voice-mode-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 48rpx;
+ width: 100%;
+}
+
+/* 🎧 语音模式头像 */
+.voice-avatar-wrapper {
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.voice-avatar {
+ width: 240rpx;
+ height: 240rpx;
+ border-radius: 50%;
+ border: 6rpx solid rgba(249, 224, 118, 0.3);
+ box-shadow: 0 8rpx 32rpx rgba(249, 224, 118, 0.3);
+ position: relative;
+ z-index: 2;
+}
+
+.avatar-glow {
+ position: absolute;
+ width: 280rpx;
+ height: 280rpx;
+ border-radius: 50%;
+ background: radial-gradient(circle, rgba(249, 224, 118, 0.3) 0%, transparent 70%);
+ z-index: 1;
+}
+
+.avatar-glow.listening {
+ animation: pulse-glow 2s infinite;
+ background: radial-gradient(circle, rgba(76, 175, 80, 0.4) 0%, transparent 70%);
+}
+
+.avatar-glow.thinking {
+ animation: pulse-glow 1.5s infinite;
+ background: radial-gradient(circle, rgba(33, 150, 243, 0.4) 0%, transparent 70%);
+}
+
+.avatar-glow.speaking {
+ animation: pulse-glow 1s infinite;
+ background: radial-gradient(circle, rgba(249, 224, 118, 0.5) 0%, transparent 70%);
+}
+
+@keyframes pulse-glow {
+ 0%, 100% {
+ transform: scale(1);
+ opacity: 0.6;
+ }
+ 50% {
+ transform: scale(1.1);
+ opacity: 1;
+ }
+}
+
+/* 🎧 状态文本 */
+.voice-state-text {
+ font-size: 36rpx;
+ font-weight: 600;
+ color: #f9e076;
+ text-shadow: 0 0 20rpx rgba(249, 224, 118, 0.5);
+ letter-spacing: 2rpx;
+}
+
+/* 🎧 声波动画容器 */
+.sound-wave-container {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 160rpx;
+}
+
+.sound-wave {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6rpx;
+ height: 100%;
+}
+
+.wave-bar {
+ width: 6rpx;
+ background: linear-gradient(180deg, #f9e076 0%, #f5d042 100%);
+ border-radius: 3rpx;
+ height: 20rpx;
+ opacity: 0.3;
+ transition: all 0.3s;
+}
+
+/* 🎧 倾听状态 */
+.sound-wave.listening .wave-bar {
+ animation: wave-listening 1.2s infinite ease-in-out;
+ background: linear-gradient(180deg, #4caf50 0%, #45a049 100%);
+ opacity: 0.8;
+}
+
+@keyframes wave-listening {
+ 0%, 100% {
+ height: 30rpx;
+ }
+ 50% {
+ height: 80rpx;
+ }
+}
+
+/* 🎧 思考状态 */
+.sound-wave.thinking .wave-bar {
+ animation: wave-thinking 2s infinite ease-in-out;
+ background: linear-gradient(180deg, #2196f3 0%, #1976d2 100%);
+ opacity: 0.7;
+}
+
+@keyframes wave-thinking {
+ 0%, 100% {
+ height: 20rpx;
+ opacity: 0.3;
+ }
+ 50% {
+ height: 50rpx;
+ opacity: 0.9;
+ }
+}
+
+/* 🎧 说话状态 */
+.sound-wave.speaking .wave-bar {
+ animation: wave-speaking 0.8s infinite ease-in-out;
+ background: linear-gradient(180deg, #f9e076 0%, #f5d042 100%);
+ opacity: 1;
+}
+
+@keyframes wave-speaking {
+ 0%, 100% {
+ height: 40rpx;
+ }
+ 50% {
+ height: 100rpx;
+ }
+}
+
+/* 每个波形条使用不同的延迟创造连续效果 */
+.sound-wave .wave-bar:nth-child(1) { animation-delay: 0s; }
+.sound-wave .wave-bar:nth-child(2) { animation-delay: 0.05s; }
+.sound-wave .wave-bar:nth-child(3) { animation-delay: 0.1s; }
+.sound-wave .wave-bar:nth-child(4) { animation-delay: 0.15s; }
+.sound-wave .wave-bar:nth-child(5) { animation-delay: 0.2s; }
+.sound-wave .wave-bar:nth-child(6) { animation-delay: 0.25s; }
+.sound-wave .wave-bar:nth-child(7) { animation-delay: 0.3s; }
+.sound-wave .wave-bar:nth-child(8) { animation-delay: 0.35s; }
+.sound-wave .wave-bar:nth-child(9) { animation-delay: 0.4s; }
+.sound-wave .wave-bar:nth-child(10) { animation-delay: 0.45s; }
+
+/* 🎧 提示文本 */
+.voice-hint-text {
+ font-size: 28rpx;
+ color: rgba(249, 224, 118, 0.7);
+ text-align: center;
+ line-height: 1.6;
+}
+
+/* 🎧 录音控制按钮 */
+.voice-record-btn {
+ width: 280rpx;
+ height: 280rpx;
+ border-radius: 50%;
+ background: linear-gradient(135deg, #f9e076 0%, #f5d042 100%);
+ box-shadow: 0 12rpx 48rpx rgba(249, 224, 118, 0.5), 0 0 80rpx rgba(249, 224, 118, 0.3);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 12rpx;
+ transition: all 0.3s;
+ margin-top: 32rpx;
+}
+
+.voice-record-btn:active {
+ transform: scale(0.95);
+ box-shadow: 0 8rpx 32rpx rgba(249, 224, 118, 0.4), 0 0 60rpx rgba(249, 224, 118, 0.2);
+}
+
+/* 录音中状态 */
+.voice-record-btn.recording {
+ background: linear-gradient(135deg, rgba(244, 67, 54, 0.9) 0%, rgba(211, 47, 47, 0.9) 100%);
+ box-shadow: 0 12rpx 48rpx rgba(244, 67, 54, 0.5), 0 0 80rpx rgba(244, 67, 54, 0.3);
+ animation: pulse-recording-btn 1.5s infinite;
+}
+
+@keyframes pulse-recording-btn {
+ 0%, 100% {
+ transform: scale(1);
+ }
+ 50% {
+ transform: scale(1.05);
+ }
+}
+
+.voice-record-icon {
+ font-size: 72rpx;
+ filter: drop-shadow(0 4rpx 8rpx rgba(26, 11, 46, 0.3));
+}
+
+.voice-record-btn.recording .voice-record-icon {
+ color: #fff;
+ filter: drop-shadow(0 4rpx 8rpx rgba(0, 0, 0, 0.3));
+}
+
+.voice-record-text {
+ font-size: 32rpx;
+ font-weight: 600;
+ color: #1a0b2e;
+ letter-spacing: 2rpx;
+}
+
+.voice-record-btn.recording .voice-record-text {
+ color: #fff;
+}
+
+/* 🎧 处理中状态按钮 */
+.voice-processing-btn {
+ width: 280rpx;
+ height: 280rpx;
+ border-radius: 50%;
+ background: linear-gradient(135deg, rgba(249, 224, 118, 0.3) 0%, rgba(249, 224, 118, 0.15) 100%);
+ border: 4rpx solid rgba(249, 224, 118, 0.5);
+ box-shadow: 0 8rpx 32rpx rgba(249, 224, 118, 0.3);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 12rpx;
+ margin-top: 32rpx;
+ opacity: 0.8;
+}
+
+.voice-processing-icon {
+ font-size: 72rpx;
+ animation: rotate-processing 2s linear infinite;
+}
+
+@keyframes rotate-processing {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+.voice-processing-text {
+ font-size: 28rpx;
+ font-weight: 600;
+ color: #f9e076;
+ letter-spacing: 2rpx;
+}
diff --git a/src/utils/api.js b/src/utils/api.js
index 69d589e..e3bb97b 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -565,6 +565,29 @@ export const voiceAPI = {
authHeader = loginStatus.token.startsWith('Bearer ') ? loginStatus.token : 'Bearer ' + loginStatus.token;
}
+ // 构建formData,支持更多参数
+ const formData = {
+ modelId: options.modelId || null,
+ templateId: options.templateId || null,
+ voiceStyle: options.voiceStyle || 'default'
+ };
+
+ // 添加可选参数
+ if (options.sessionId) {
+ formData.sessionId = options.sessionId;
+ }
+ if (options.ttsConfigId) {
+ formData.ttsConfigId = options.ttsConfigId;
+ }
+ if (options.sttConfigId) {
+ formData.sttConfigId = options.sttConfigId;
+ }
+ if (options.useFunctionCall !== undefined) {
+ formData.useFunctionCall = options.useFunctionCall;
+ }
+
+ console.log('语音对话参数:', formData);
+
return new Promise((resolve) => {
uni.uploadFile({
url: getApiUrl(API_CONFIG.ENDPOINTS.VOICE_CHAT),
@@ -573,11 +596,7 @@ export const voiceAPI = {
header: authHeader ? {
'Authorization': authHeader
} : {},
- formData: {
- modelId: options.modelId || null,
- templateId: options.templateId || null,
- voiceStyle: options.voiceStyle || 'default'
- },
+ formData: formData,
success: (res) => {
console.log('语音对话上传成功:', res);
@@ -586,41 +605,46 @@ export const voiceAPI = {
console.log('语音对话响应数据:', data);
if (data.code === 200) {
- // 根据后端实际返回结构提取字段
+ // 返回完整的data对象,包括sttResult、llmResult、ttsResult
+ const responseData = data.data || {};
+
+ // 兼容旧格式:提取关键字段
let aiResponse = null;
let userText = null;
let audioUrl = null;
+ let audioBase64 = null;
// 从 data.llmResult.response 提取AI回复
- if (data.data && data.data.llmResult && data.data.llmResult.response) {
- aiResponse = data.data.llmResult.response;
+ if (responseData.llmResult && responseData.llmResult.response) {
+ aiResponse = responseData.llmResult.response;
}
// 从 data.sttResult.text 提取用户文本(语音转文字)
- if (data.data && data.data.sttResult && data.data.sttResult.text) {
- userText = data.data.sttResult.text;
+ if (responseData.sttResult && responseData.sttResult.text) {
+ userText = responseData.sttResult.text;
}
- // 从 data.ttsResult.audioPath 提取音频路径
- if (data.data && data.data.ttsResult && data.data.ttsResult.audioPath) {
- audioUrl = data.data.ttsResult.audioPath;
+ // 从 data.ttsResult 提取音频
+ if (responseData.ttsResult) {
+ audioUrl = responseData.ttsResult.audioPath;
+ audioBase64 = responseData.ttsResult.audioBase64;
}
// 备用字段提取(保持向后兼容)
if (!aiResponse) {
if (data.response && typeof data.response === 'string') {
aiResponse = data.response;
- } else if (data.data && data.data.response) {
- aiResponse = data.data.response;
+ } else if (responseData.response) {
+ aiResponse = responseData.response;
}
}
if (!userText) {
- userText = data.userText || data.data?.userText || data.data?.text || data.data?.user_text || data.data?.recognizedText || data.data?.transcription;
+ userText = data.userText || responseData.userText || responseData.text || responseData.user_text || responseData.recognizedText || responseData.transcription;
}
- if (!audioUrl) {
- audioUrl = data.audioPath || data.audioUrl || data.data?.audioUrl || data.data?.url || data.data?.audio_url || data.data?.speechUrl || data.data?.ttsUrl || data.data?.audioPath;
+ if (!audioUrl && !audioBase64) {
+ audioUrl = data.audioPath || data.audioUrl || responseData.audioUrl || responseData.url || responseData.audio_url || responseData.speechUrl || responseData.ttsUrl || responseData.audioPath;
}
// 清理AI回复文本
@@ -631,9 +655,16 @@ export const voiceAPI = {
resolve({
success: true,
data: {
+ // 兼容旧接口
userText: userText,
aiResponse: cleanedAiResponse,
- audioUrl: audioUrl
+ audioUrl: audioUrl,
+ // 新增完整数据结构
+ sttResult: responseData.sttResult || { text: userText },
+ llmResult: responseData.llmResult || { response: cleanedAiResponse, inputText: userText },
+ ttsResult: responseData.ttsResult || { audioPath: audioUrl, audioBase64: audioBase64 },
+ sessionId: responseData.sessionId || null,
+ timestamp: responseData.timestamp || Date.now()
}
});
} else {
diff --git a/src/utils/config.js b/src/utils/config.js
index c800673..c0f0596 100644
--- a/src/utils/config.js
+++ b/src/utils/config.js
@@ -1,7 +1,7 @@
// API配置统一管理
export const API_CONFIG = {
// 基础API地址
- BASE_URL: 'https://api.aixsy.com.cn',
+ BASE_URL: 'http://192.168.3.13:8091',
// 其他服务地址(如果需要)
WEB_URL: 'https://www.aixsy.com.cn',