From 6c36fe778d0c822b85b8f25fceb9cbe1a110d1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=8B=E6=9D=B0?= Date: Thu, 26 Jun 2025 14:49:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E4=BA=86=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E5=88=B0=E8=A7=86=E5=8F=A3=E6=92=AD=E6=94=BE=E9=9F=B3=E9=A2=91?= =?UTF-8?q?=E7=9A=84=E9=80=BB=E8=BE=91=EF=BC=8C=E5=8A=A0=E8=BD=BD=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E7=9B=B4=E6=8E=A5=E6=92=AD=E6=94=BE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/AiEmotion.vue | 103 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 24 deletions(-) diff --git a/src/views/AiEmotion.vue b/src/views/AiEmotion.vue index effd93e..9dbc062 100644 --- a/src/views/AiEmotion.vue +++ b/src/views/AiEmotion.vue @@ -28,7 +28,7 @@
-
AI小财神正在分析中,请稍候...
+
AI小财神正在加载图表数据和音频内容,请稍候...
@@ -320,8 +320,7 @@ const parsedConclusion = computed(() => { // 监听当前股票变化,重新渲染图表 watch(currentStock, (newStock) => { if (newStock && newStock.apiData) { - isPageLoaded.value = true; - isLoading.value = false; // 数据加载完成,关闭加载状态 + // 页面加载状态现在由 handleSendMessage 统一控制 // 停止当前播放的音频 stopAudio(); // 清理正在进行的打字机效果定时器 @@ -390,10 +389,12 @@ watch(currentStock, (newStock) => { }; } - nextTick(() => { - renderCharts(newStock.apiData); - console.log('0000000000000000000000000', newStock.apiData) - // 检查场景应用部分是否已经在视口中,如果是则立即触发效果 + // 只有在页面已加载的情况下才渲染图表 + if (isPageLoaded.value) { + nextTick(() => { + renderCharts(newStock.apiData); + console.log('图表数据已准备完成,开始渲染:', newStock.apiData) + // 检查场景应用部分是否已经在视口中,如果是则立即触发效果 setTimeout(() => { if (scenarioApplicationRef.value && parsedConclusion.value) { const stockCode = newStock.stockInfo?.code || newStock.stockInfo?.symbol; @@ -463,9 +464,12 @@ watch(currentStock, (newStock) => { } } }, 500); // 延迟500ms确保数据完全加载 - }); + }); + } else { + console.log('页面尚未加载完成,等待数据加载完成后再渲染图表'); + } } else { - isPageLoaded.value = false; + console.log('股票数据不存在或API数据未加载'); } }, { immediate: true }); @@ -495,22 +499,20 @@ watch(parsedConclusion, (newConclusion) => { audioUrl.value = voiceUrl; console.log('音频URL已准备,检查是否需要立即触发效果'); - // 音频准备好后,检查场景应用部分是否已经在视口中 + // 音频准备好后,如果页面已加载则立即触发效果 nextTick(() => { setTimeout(() => { - if (scenarioApplicationRef.value && currentStock.value?.stockInfo) { + if (currentStock.value?.stockInfo && isPageLoaded.value) { const stockCode = currentStock.value.stockInfo.code || currentStock.value.stockInfo.symbol; - const rect = scenarioApplicationRef.value.getBoundingClientRect(); - const isInViewport = rect.top < window.innerHeight && rect.bottom > 0; - if (isInViewport && parsedConclusion.value && stockCode) { + if (parsedConclusion.value && stockCode) { // 如果该股票已经显示过,不需要再处理 if (stockTypewriterShown.value.has(stockCode)) { return; } // 该股票第一次:播放音频和打字机效果 - console.log('该股票第一次音频准备完成且场景应用部分在视口中,立即触发效果'); + console.log('音频准备完成且页面已加载,立即触发效果'); hasTriggeredTypewriter.value = true; hasTriggeredAudio.value = true; @@ -785,6 +787,11 @@ async function handleSendMessage(input) { return; } + // 用户输入不为空,立即触发图片旋转逻辑,隐藏历史数据 + isRotating.value = true; + const previousMessages = [...messages.value]; // 保存历史消息 + messages.value = []; // 清空历史数据 + // 检查用户是否有使用次数(检查是否有任何权限) const hasPermission = userStore.brainPerssion || userStore.swordPerssion || userStore.pricePerssion || userStore.timePerssion || @@ -796,6 +803,9 @@ async function handleSendMessage(input) { messages.value.push(userMessage); const aiMessage = reactive({ sender: 'ai', text: '您当前没有可用次数,请联系客服或购买服务包。' }); messages.value.push(aiMessage); + // 停止图片旋转,恢复历史数据 + isRotating.value = false; + messages.value = [...previousMessages, ...messages.value]; return; } @@ -827,15 +837,15 @@ async function handleSendMessage(input) { // 检查用户输入是否合法 if (!parsedData || !parsedData.market || !parsedData.code) { - // 输入不合法,返回refuse信息,不进行后续处理 + // 输入不合法,返回refuse信息,停止图片旋转,恢复历史数据 const aiMessage = reactive({ sender: 'ai', text: processRefuseMessage(parsedData.refuse) }); messages.value.push(aiMessage); + isRotating.value = false; + messages.value = [...previousMessages, ...messages.value]; return; } - // 输入合法,开始显示等待提示和后续处理 - // 触发图片旋转 - isRotating.value = true; + // 输入合法,继续执行后续处理 // 设置加载状态,隐藏图表页面 isLoading.value = true; @@ -863,16 +873,57 @@ async function handleSendMessage(input) { const conclusionResponse = await conclusionResult.json(); console.log("第二个工作流接口返回数据:", conclusionResponse); - // 将结论数据存储到响应式变量和store中 - if (conclusionResponse && conclusionResponse.data) { + // 检查所有数据是否都加载成功 + if (conclusionResponse && conclusionResponse.data && fetchDataResult) { + // 将结论数据存储到响应式变量和store中 conclusionData.value = conclusionResponse.data; // 将结论数据存储到store中的当前激活股票 emotionStore.updateActiveStockConclusion(conclusionResponse.data); + + // 所有数据加载完成,关闭加载状态,显示页面 + isLoading.value = false; + isPageLoaded.value = true; + + console.log('所有数据加载完成,开始渲染页面'); + + // 确保页面状态更新后触发图表渲染和音频文本 + nextTick(() => { + if (currentStock.value && currentStock.value.apiData) { + renderCharts(currentStock.value.apiData); + console.log('数据加载完成后开始渲染图表'); + + // 数据加载完成后立即触发音频和文本,不等待滚动到视口 + if (parsedConclusion.value && audioUrl.value) { + const stockCode = currentStock.value.stockInfo?.code || currentStock.value.stockInfo?.symbol; + if (stockCode && !stockTypewriterShown.value.has(stockCode)) { + console.log('数据加载完成,立即触发音频和打字机效果'); + startTypewriterEffect(parsedConclusion.value); + + if (!stockAudioPlayed.value.has(stockCode)) { + stockAudioPlayed.value.set(stockCode, true); + playAudio(audioUrl.value); + } + stockTypewriterShown.value.set(stockCode, true); + } + } + } + }); + } else { + // 数据加载失败,停止图片旋转,恢复历史数据 + isLoading.value = false; + const aiMessage = reactive({ sender: 'ai', text: '数据加载失败,请重试' }); + messages.value.push(aiMessage); + isRotating.value = false; + messages.value = [...previousMessages, ...messages.value]; + return; } } catch (error) { const aiMessage = reactive({ sender: 'ai', text: '请求工作流接口失败,请检查网络连接' }); messages.value.push(aiMessage); - return; // 请求失败时直接返回 + // 请求失败时停止图片旋转,恢复历史数据 + isRotating.value = false; + messages.value = [...previousMessages, ...messages.value]; + return; } finally { // 停止图片旋转(只有在设置了旋转状态时才需要停止) if (isRotating.value) { @@ -925,13 +976,17 @@ async function fetchData(code, market, stockName, queryText) { }; // 将股票数据添加到store中 emotionStore.addStock(stockData); + return true; // 返回成功标识 } else { - const aiMessage = reactive({ sender: 'ai', text: '请求失败,请检查网络连接' }); + const aiMessage = reactive({ sender: 'ai', text: '图表数据请求失败,请检查网络连接' }); messages.value.push(aiMessage); + return false; // 返回失败标识 } } catch (error) { - const aiMessage = reactive({ sender: 'ai', text: '请求失败,请检查网络连接' }); + console.error('fetchData error:', error); + const aiMessage = reactive({ sender: 'ai', text: '图表数据请求失败,请检查网络连接' }); messages.value.push(aiMessage); + return false; // 返回失败标识 } }