@@ -167,7 +168,7 @@ import { ElMessage } from 'element-plus';
import { useEmotionStore } from '@/store/emotion'; // 导入Pinia store
import { useAudioStore } from '@/store/audio.js'; // 导入音频store
import { Howl, Howler } from 'howler'; // 导入音频播放库
-
+import { reactive } from 'vue';
// 使用Pinia store
const emotionStore = useEmotionStore();
const audioStore = useAudioStore();
@@ -186,6 +187,15 @@ const isRotating = ref(false);//控制旋转
const version1 = ref(2); // 版本号
const conclusionData = ref(''); // 存储第二个工作流接口返回的结论数据
+// 自动滚动相关数据
+const isAutoScrolling = ref(false);
+const currentSection = ref(0);
+const sectionRefs = ref([]);
+const scenarioApplicationRef = ref(null); // 场景应用部分的引用
+const hasTriggeredAudio = ref(false); // 是否已触发音频播放
+const hasTriggeredTypewriter = ref(false); // 是否已触发打字机效果
+const intersectionObserver = ref(null); // 存储observer实例
+
// 打字机效果相关数据
const displayedTexts = ref({
one1: '',
@@ -232,10 +242,24 @@ const parsedConclusion = computed(() => {
}
});
+
+
// 监听当前股票变化,重新渲染图表
watch(currentStock, (newStock) => {
if (newStock && newStock.apiData) {
isPageLoaded.value = true;
+ // 重置触发状态,允许新股票重新触发效果
+ hasTriggeredAudio.value = false;
+ hasTriggeredTypewriter.value = false;
+ // 清空之前的显示文本
+ displayedTexts.value = {
+ one1: '',
+ one2: '',
+ two: '',
+ three: '',
+ four: '',
+ disclaimer: ''
+ };
nextTick(() => {
renderCharts(newStock.apiData);
});
@@ -244,11 +268,11 @@ watch(currentStock, (newStock) => {
}
}, { immediate: true });
-// 监听parsedConclusion变化,触发打字机效果
+// 监听parsedConclusion变化,准备数据但不立即触发打字机效果
watch(parsedConclusion, (newConclusion) => {
if (newConclusion) {
console.log('场景应用结论数据:', newConclusion);
- startTypewriterEffect(newConclusion);
+ // 不再立即开始打字机效果,等待滚动到场景应用部分时触发
// 尝试多种可能的语音URL字段名
let voiceUrl = null;
@@ -266,13 +290,13 @@ watch(parsedConclusion, (newConclusion) => {
}
if (voiceUrl && voiceUrl.startsWith('http')) {
- console.log('找到并清理后的语音URL:', voiceUrl);
- audioUrl.value = voiceUrl;
- playAudio(voiceUrl);
- } else {
- console.log('未找到有效的语音URL,原始URL:', newConclusion.url);
- console.log('结论数据中的所有字段:', Object.keys(newConclusion));
- }
+ console.log('找到并清理后的语音URL:', voiceUrl);
+ audioUrl.value = voiceUrl;
+ console.log('音频URL已准备,等待滚动触发播放');
+ } else {
+ console.log('未找到有效的语音URL,原始URL:', newConclusion.url);
+ console.log('结论数据中的所有字段:', Object.keys(newConclusion));
+ }
}
}, { immediate: true });
@@ -293,7 +317,7 @@ function startTypewriterEffect(conclusion) {
};
// 定义打字速度(毫秒)
- const typeSpeed = 50;
+ const typeSpeed = 300;
let totalDelay = 0;
// 为每个文本创建打字机效果
@@ -404,8 +428,6 @@ function stopAudio() {
}
isAudioPlaying.value = false;
}
-//导出方法供外部使用
-defineExpose({ handleSendMessage })
// 触发图片旋转的方法
function startImageRotation() {
isRotating.value = true;
@@ -620,16 +642,175 @@ const scrollToBottom = async () => {
};
-// 页面挂载完成后触发图片旋转
-onMounted(() => {
- startImageRotation();
-});
+// 检查数据是否已加载完成
+function isDataLoaded() {
+ // 检查页面是否已加载
+ if (!isPageLoaded.value) {
+ console.log('页面数据尚未加载完成');
+ return false;
+ }
+
+ // 检查当前股票数据是否存在
+ if (!currentStock.value || !currentStock.value.apiData) {
+ console.log('股票数据尚未加载完成');
+ return false;
+ }
+
+ // 检查图表组件是否已渲染
+ const requiredRefs = [
+ marketTemperatureRef.value,
+ emotionDecodRef.value,
+ emotionalBottomRadarRef.value,
+ emoEnergyConverterRef.value
+ ];
+
+ const allRefsLoaded = requiredRefs.every(ref => ref !== null);
+ if (!allRefsLoaded) {
+ console.log('图表组件尚未完全加载');
+ return false;
+ }
+
+ console.log('所有数据和组件已加载完成,可以开始滚动');
+ return true;
+}
-// 组件卸载时清理定时器和音频
-onUnmounted(() => {
- clearTypewriterTimers();
- stopAudio();
-});
+// 自动滚动函数
+function startAutoScroll() {
+ if (isAutoScrolling.value) return;
+
+ // 检查数据是否已加载完成
+ if (!isDataLoaded()) {
+ console.log('数据尚未加载完成,延迟1秒后重试');
+ setTimeout(() => {
+ startAutoScroll();
+ }, 1000);
+ return;
+ }
+
+ isAutoScrolling.value = true;
+ const sections = document.querySelectorAll('.class02, .class03, .class04, .class05, .class06, .class08, .class09');
+
+ let currentIndex = 0;
+
+ function scrollToNextSection() {
+ if (currentIndex < sections.length) {
+ const section = sections[currentIndex];
+
+ // 使用更平滑的滚动配置
+ section.scrollIntoView({
+ behavior: 'smooth',
+ block: 'center', // 改为居中显示,视觉效果更好
+ inline: 'nearest'
+ });
+
+ console.log(`滚动到第${currentIndex + 1}个部分`);
+ currentSection.value = currentIndex;
+ currentIndex++;
+
+ // 增加滚动间隔时间,让用户有更多时间观看内容
+ setTimeout(scrollToNextSection, 4000); // 从2秒增加到4秒
+ } else {
+ console.log('自动滚动完成');
+ isAutoScrolling.value = false;
+ }
+ }
+
+ // 开始滚动前等待2秒,给用户准备时间
+ console.log('自动滚动将在2秒后开始');
+ setTimeout(scrollToNextSection, 2000);
+}
+
+// 设置Intersection Observer监听场景应用部分
+ function setupIntersectionObserver() {
+ if (!scenarioApplicationRef.value) return;
+
+ const observer = new IntersectionObserver(
+ (entries) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting && (!hasTriggeredAudio.value || !hasTriggeredTypewriter.value)) {
+ console.log('场景应用部分进入视口,开始打字机效果和音频播放');
+
+ // 触发打字机效果
+ if (!hasTriggeredTypewriter.value && parsedConclusion.value) {
+ console.log('开始场景应用打字机效果');
+ hasTriggeredTypewriter.value = true;
+ startTypewriterEffect(parsedConclusion.value);
+ }
+
+ // 触发音频播放
+ if (!hasTriggeredAudio.value && audioUrl.value && parsedConclusion.value) {
+ console.log('自动触发场景应用音频播放');
+ hasTriggeredAudio.value = true;
+ playAudio(audioUrl.value);
+ }
+ }
+ });
+ },
+ {
+ threshold: 0.3, // 当30%的元素进入视口时触发
+ rootMargin: '0px 0px -100px 0px' // 提前100px触发
+ }
+ );
+
+ observer.observe(scenarioApplicationRef.value);
+ intersectionObserver.value = observer;
+ }
+
+ // 手动触发自动滚动
+ function triggerAutoScroll() {
+ // 检查是否正在滚动
+ if (isAutoScrolling.value) {
+ console.log('自动滚动正在进行中,请稍候');
+ return;
+ }
+
+ // 检查数据是否已准备好
+ if (!isDataLoaded()) {
+ console.log('数据尚未准备完成,请等待数据加载后再试');
+ // 可以显示提示信息给用户
+ return;
+ }
+
+ console.log('手动触发自动滚动');
+ startAutoScroll();
+ }
+
+// 页面挂载完成后触发图片旋转和设置滚动监听
+ onMounted(() => {
+ startImageRotation();
+
+ // 等待DOM完全渲染后设置监听器
+ nextTick(() => {
+ setupIntersectionObserver();
+
+ // 页面加载完成后自动开始滚动
+ setTimeout(() => {
+ triggerAutoScroll();
+ }, 1000); // 延迟1秒开始滚动,确保页面完全渲染
+ });
+ });
+
+ // 组件卸载时清理定时器、音频和observer
+ onUnmounted(() => {
+ clearTypewriterTimers();
+ stopAudio();
+
+ // 重置触发状态
+ hasTriggeredAudio.value = false;
+ hasTriggeredTypewriter.value = false;
+
+ // 清理Intersection Observer
+ if (intersectionObserver.value) {
+ intersectionObserver.value.disconnect();
+ intersectionObserver.value = null;
+ }
+ });
+
+ // 导出方法供外部使用
+ defineExpose({
+ handleSendMessage,
+ triggerAutoScroll
+ });