|
|
@ -100,10 +100,14 @@ |
|
|
|
</div> |
|
|
|
<div class="bk-image"> |
|
|
|
<div class="text-container"> |
|
|
|
<p>情绪监控-金融宇宙的【量子检测网络】核心任务:构建全市场情绪引力场雷达</p> |
|
|
|
<p>情绪解码-主力思维的【神经破译矩阵】核心任务:解构资金行为的量子密码</p> |
|
|
|
<p>情绪推演-未来战争的【时空推演舱】核心任务:情绪推演</p> |
|
|
|
<p>情绪套利-财富裂变的【粒子对撞机】核心任务:将情绪差转化为a收益粒子流</p> |
|
|
|
<p><span class="title">🔍 情绪监控-金融宇宙的【量子检测网络】</span> |
|
|
|
<span class="content">核心任务:构建全市场情绪引力场雷达,实时监测资金流向和情绪波动</span></p> |
|
|
|
<p><span class="title">🧠 情绪解码-主力思维的【神经破译矩阵】</span> |
|
|
|
<span class="content">核心任务:解构资金行为的量子密码,破译主力操盘意图和策略布局</span></p> |
|
|
|
<p><span class="title">🔮 情绪推演-未来战争的【时空推演舱】</span> |
|
|
|
<span class="content">核心任务:基于情绪数据推演未来走势,预测市场转折点和机会窗口</span></p> |
|
|
|
<p><span class="title">💰 情绪套利-财富裂变的【粒子对撞机】</span> |
|
|
|
<span class="content">核心任务:将情绪差转化为收益粒子流,实现情绪能量的价值转换</span></p> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<!-- 核心逻辑 --> |
|
|
@ -115,7 +119,7 @@ |
|
|
|
<img src="@/assets/img/AiEmotion/量子神经决策树.png" alt="树标题"> |
|
|
|
</div> |
|
|
|
<div class="scaled-img"> |
|
|
|
<img src="@/assets/img/AiEmotion/tree02.png" alt="树图片"> |
|
|
|
<!-- <img src="@/assets/img/AiEmotion/tree02.jpg" alt="树图片"> --> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<!-- 场景应用 --> |
|
|
@ -274,10 +278,10 @@ watch(currentStock, (newStock) => { |
|
|
|
// 重置触发状态,允许新股票重新触发效果 |
|
|
|
hasTriggeredAudio.value = false; |
|
|
|
hasTriggeredTypewriter.value = false; |
|
|
|
|
|
|
|
|
|
|
|
// 获取股票代码作为唯一标识 |
|
|
|
const stockCode = newStock.stockInfo?.code || newStock.stockInfo?.symbol; |
|
|
|
|
|
|
|
|
|
|
|
// 检查该股票是否已经显示过打字机效果 |
|
|
|
if (stockCode && stockTypewriterShown.value.has(stockCode)) { |
|
|
|
// 如果已经显示过,直接显示完整文本和标题 |
|
|
@ -334,71 +338,71 @@ watch(currentStock, (newStock) => { |
|
|
|
disclaimer: false |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
nextTick(() => { |
|
|
|
renderCharts(newStock.apiData); |
|
|
|
|
|
|
|
|
|
|
|
// 检查场景应用部分是否已经在视口中,如果是则立即触发效果 |
|
|
|
setTimeout(() => { |
|
|
|
if (scenarioApplicationRef.value && parsedConclusion.value) { |
|
|
|
const rect = scenarioApplicationRef.value.getBoundingClientRect(); |
|
|
|
const isInViewport = rect.top < window.innerHeight && rect.bottom > 0; |
|
|
|
|
|
|
|
|
|
|
|
if (isInViewport && !hasTriggeredTypewriter.value) { |
|
|
|
console.log('股票切换后检测到场景应用部分在视口中,立即触发效果'); |
|
|
|
const stockCode = newStock.stockInfo?.code || newStock.stockInfo?.symbol; |
|
|
|
|
|
|
|
|
|
|
|
if (stockCode) { |
|
|
|
if (!stockTypewriterShown.value.has(stockCode)) { |
|
|
|
// 检查音频是否准备好,如果没有准备好则不触发效果 |
|
|
|
if (!audioUrl.value) { |
|
|
|
console.log('音频尚未准备好,等待音频加载完成后再触发效果(股票切换后)'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
console.log('开始场景应用打字机效果和音频播放(股票切换后首次)'); |
|
|
|
hasTriggeredTypewriter.value = true; |
|
|
|
hasTriggeredAudio.value = true; |
|
|
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value); |
|
|
|
|
|
|
|
if (!stockAudioPlayed.value.has(stockCode)) { |
|
|
|
console.log('同时开始音频播放(股票切换后)'); |
|
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
|
playAudio(audioUrl.value); |
|
|
|
} |
|
|
|
|
|
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
|
} else { |
|
|
|
console.log('该股票已显示过,直接显示完整内容(股票切换后)'); |
|
|
|
hasTriggeredTypewriter.value = true; |
|
|
|
hasTriggeredAudio.value = true; |
|
|
|
|
|
|
|
// 直接显示完整内容 |
|
|
|
const conclusion = parsedConclusion.value; |
|
|
|
displayedTexts.value = { |
|
|
|
one1: conclusion.one1 || '', |
|
|
|
one2: conclusion.one2 || '', |
|
|
|
two: conclusion.two || '', |
|
|
|
three: conclusion.three || '', |
|
|
|
four: conclusion.four || '', |
|
|
|
disclaimer: '该内容由AI内容生成,请注意甄别' |
|
|
|
}; |
|
|
|
displayedTitles.value = { |
|
|
|
one: 'L1: 情绪监控', |
|
|
|
two: 'L2: 情绪解码', |
|
|
|
three: 'L3: 情绪推演', |
|
|
|
four: 'L4: 情绪套利' |
|
|
|
}; |
|
|
|
moduleVisibility.value = { |
|
|
|
one: !!(conclusion.one1 || conclusion.one2), |
|
|
|
two: !!conclusion.two, |
|
|
|
three: !!conclusion.three, |
|
|
|
four: !!conclusion.four, |
|
|
|
disclaimer: true |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!stockTypewriterShown.value.has(stockCode)) { |
|
|
|
// 检查音频是否准备好,如果没有准备好则不触发效果 |
|
|
|
if (!audioUrl.value) { |
|
|
|
console.log('音频尚未准备好,等待音频加载完成后再触发效果(股票切换后)'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
console.log('开始场景应用打字机效果和音频播放(股票切换后首次)'); |
|
|
|
hasTriggeredTypewriter.value = true; |
|
|
|
hasTriggeredAudio.value = true; |
|
|
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value); |
|
|
|
|
|
|
|
if (!stockAudioPlayed.value.has(stockCode)) { |
|
|
|
console.log('同时开始音频播放(股票切换后)'); |
|
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
|
playAudio(audioUrl.value); |
|
|
|
} |
|
|
|
|
|
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
|
} else { |
|
|
|
console.log('该股票已显示过,直接显示完整内容(股票切换后)'); |
|
|
|
hasTriggeredTypewriter.value = true; |
|
|
|
hasTriggeredAudio.value = true; |
|
|
|
|
|
|
|
// 直接显示完整内容 |
|
|
|
const conclusion = parsedConclusion.value; |
|
|
|
displayedTexts.value = { |
|
|
|
one1: conclusion.one1 || '', |
|
|
|
one2: conclusion.one2 || '', |
|
|
|
two: conclusion.two || '', |
|
|
|
three: conclusion.three || '', |
|
|
|
four: conclusion.four || '', |
|
|
|
disclaimer: '该内容由AI内容生成,请注意甄别' |
|
|
|
}; |
|
|
|
displayedTitles.value = { |
|
|
|
one: 'L1: 情绪监控', |
|
|
|
two: 'L2: 情绪解码', |
|
|
|
three: 'L3: 情绪推演', |
|
|
|
four: 'L4: 情绪套利' |
|
|
|
}; |
|
|
|
moduleVisibility.value = { |
|
|
|
one: !!(conclusion.one1 || conclusion.one2), |
|
|
|
two: !!conclusion.two, |
|
|
|
three: !!conclusion.three, |
|
|
|
four: !!conclusion.four, |
|
|
|
disclaimer: true |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}, 500); // 延迟500ms确保数据完全加载 |
|
|
@ -433,7 +437,7 @@ watch(parsedConclusion, (newConclusion) => { |
|
|
|
console.log('找到并清理后的语音URL:', voiceUrl); |
|
|
|
audioUrl.value = voiceUrl; |
|
|
|
console.log('音频URL已准备,检查是否需要立即触发效果'); |
|
|
|
|
|
|
|
|
|
|
|
// 音频准备好后,检查场景应用部分是否已经在视口中 |
|
|
|
nextTick(() => { |
|
|
|
setTimeout(() => { |
|
|
@ -441,21 +445,21 @@ watch(parsedConclusion, (newConclusion) => { |
|
|
|
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 && !hasTriggeredTypewriter.value && parsedConclusion.value && stockCode) { |
|
|
|
if (!stockTypewriterShown.value.has(stockCode)) { |
|
|
|
console.log('音频准备完成且场景应用部分在视口中,立即触发效果'); |
|
|
|
hasTriggeredTypewriter.value = true; |
|
|
|
hasTriggeredAudio.value = true; |
|
|
|
|
|
|
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value); |
|
|
|
|
|
|
|
|
|
|
|
if (!stockAudioPlayed.value.has(stockCode)) { |
|
|
|
console.log('立即开始音频播放'); |
|
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
|
playAudio(audioUrl.value); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
|
} |
|
|
|
} |
|
|
@ -472,14 +476,14 @@ watch(parsedConclusion, (newConclusion) => { |
|
|
|
// 打字机效果函数 |
|
|
|
function startTypewriterEffect(conclusion) { |
|
|
|
console.log('开始打字机效果,结论数据:', conclusion); |
|
|
|
|
|
|
|
|
|
|
|
// 详细调试各个字段 |
|
|
|
console.log('L1字段 - one1:', conclusion.one1); |
|
|
|
console.log('L1字段 - one2:', conclusion.one2); |
|
|
|
console.log('L2字段 - two:', conclusion.two); |
|
|
|
console.log('L3字段 - three:', conclusion.three); |
|
|
|
console.log('L4字段 - four:', conclusion.four); |
|
|
|
|
|
|
|
|
|
|
|
// 清除之前的定时器 |
|
|
|
typewriterTimers.value.forEach(timer => clearTimeout(timer)); |
|
|
|
typewriterTimers.value = []; |
|
|
@ -493,14 +497,14 @@ function startTypewriterEffect(conclusion) { |
|
|
|
four: '', |
|
|
|
disclaimer: '' |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
displayedTitles.value = { |
|
|
|
one: '', |
|
|
|
two: '', |
|
|
|
three: '', |
|
|
|
four: '' |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
moduleVisibility.value = { |
|
|
|
one: false, |
|
|
|
two: false, |
|
|
@ -591,7 +595,7 @@ function startTypewriterEffect(conclusion) { |
|
|
|
|
|
|
|
// 添加免责声明的打字机效果(在所有模块显示完成后) |
|
|
|
const disclaimerText = '该内容由AI内容生成,请注意甄别'; |
|
|
|
|
|
|
|
|
|
|
|
// 显示免责声明模块 |
|
|
|
const showDisclaimerTimer = setTimeout(() => { |
|
|
|
moduleVisibility.value.disclaimer = true; |
|
|
@ -749,7 +753,7 @@ async function handleSendMessage(input) { |
|
|
|
// 在调用第二个工作流接口前立即开始缓慢滚动 |
|
|
|
console.log('第二个工作流接口开始调用,立即开始缓慢滚动'); |
|
|
|
startAutoScroll(); |
|
|
|
|
|
|
|
|
|
|
|
// 同时调用第二个数据流接口和fetchData方法 |
|
|
|
const [conclusionResult, fetchDataResult] = await Promise.all([ |
|
|
|
getConclusionAPI(conclusionParams), |
|
|
@ -1004,28 +1008,28 @@ function setupIntersectionObserver() { |
|
|
|
console.log('音频尚未准备好,等待音频加载完成后再触发效果'); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
console.log('开始场景应用打字机效果和音频播放(首次加载)'); |
|
|
|
hasTriggeredTypewriter.value = true; |
|
|
|
hasTriggeredAudio.value = true; |
|
|
|
|
|
|
|
|
|
|
|
// 同时开始打字机效果和音频播放 |
|
|
|
startTypewriterEffect(parsedConclusion.value); |
|
|
|
|
|
|
|
|
|
|
|
// 立即开始播放音频 |
|
|
|
if (!stockAudioPlayed.value.has(stockCode)) { |
|
|
|
console.log('同时开始音频播放'); |
|
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
|
playAudio(audioUrl.value); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 记录该股票已显示过打字机效果 |
|
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
|
} else { |
|
|
|
console.log('该股票已显示过打字机效果,直接显示完整内容'); |
|
|
|
hasTriggeredTypewriter.value = true; |
|
|
|
hasTriggeredAudio.value = true; |
|
|
|
|
|
|
|
|
|
|
|
// 直接显示完整内容,不使用打字机效果 |
|
|
|
const conclusion = parsedConclusion.value; |
|
|
|
displayedTexts.value = { |
|
|
@ -1235,18 +1239,14 @@ defineExpose({ |
|
|
|
opacity: 0.8; |
|
|
|
} |
|
|
|
|
|
|
|
&:hover { |
|
|
|
background: linear-gradient(135deg, rgba(0, 212, 255, 0.25) 0%, rgba(0, 150, 255, 0.15) 100%); |
|
|
|
transform: translateY(-2px) scale(1.02); |
|
|
|
box-shadow: 0 8px 25px rgba(0, 212, 255, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
&:last-child { |
|
|
|
margin-bottom: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.conclusion-title { |
|
|
|
color: #fff000; |
|
|
|
color: #FFD700; |
|
|
|
font-size: 22px; |
|
|
|
font-weight: bold; |
|
|
|
margin: 0 0 15px 0; |
|
|
@ -1269,7 +1269,7 @@ defineExpose({ |
|
|
|
|
|
|
|
.conclusion-text { |
|
|
|
color: #ffffff; |
|
|
|
font-size: 16px; |
|
|
|
font-size: 20px; |
|
|
|
line-height: 1.8; |
|
|
|
margin: 0 0 12px 0; |
|
|
|
text-align: left; |
|
|
@ -1353,12 +1353,22 @@ defineExpose({ |
|
|
|
opacity: 0.8; |
|
|
|
} |
|
|
|
|
|
|
|
.text-container p:hover { |
|
|
|
background: linear-gradient(135deg, rgba(0, 212, 255, 0.25) 0%, rgba(0, 150, 255, 0.15) 100%); |
|
|
|
transform: translateY(-2px) scale(1.02); |
|
|
|
box-shadow: 0 8px 25px rgba(0, 212, 255, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2); |
|
|
|
.text-container .title { |
|
|
|
display: block; |
|
|
|
color: #FFD700; |
|
|
|
font-weight: bold; |
|
|
|
margin-bottom: 10px; |
|
|
|
font-size: 22px; |
|
|
|
} |
|
|
|
|
|
|
|
.text-container .content { |
|
|
|
display: block; |
|
|
|
color: white; |
|
|
|
font-size: 20px; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.class07 { |
|
|
|
background-image: url("@/assets/img/AiEmotion/bk03.png"); |
|
|
|
/* 使用导入的背景图片 */ |
|
|
@ -1401,8 +1411,7 @@ defineExpose({ |
|
|
|
|
|
|
|
.class0603 { |
|
|
|
min-width: 100%; |
|
|
|
/* margin: 0 auto; */ |
|
|
|
|
|
|
|
margin-top: 3%; |
|
|
|
} |
|
|
|
|
|
|
|
.class0502 { |
|
|
@ -1484,21 +1493,21 @@ defineExpose({ |
|
|
|
|
|
|
|
.title2 { |
|
|
|
color: white; |
|
|
|
font-size: 30px; |
|
|
|
font-size: 20px; |
|
|
|
font-weight: bold; |
|
|
|
margin-left: 44%; |
|
|
|
} |
|
|
|
|
|
|
|
.title3 { |
|
|
|
color: white; |
|
|
|
font-size: 30px; |
|
|
|
font-size: 20px; |
|
|
|
font-weight: bold; |
|
|
|
margin-left: 43%; |
|
|
|
} |
|
|
|
|
|
|
|
.title4 { |
|
|
|
color: white; |
|
|
|
font-size: 2rem; |
|
|
|
font-size: 20px; |
|
|
|
font-weight: bold; |
|
|
|
margin-left: 41.5%; |
|
|
|
} |
|
|
@ -1511,9 +1520,16 @@ defineExpose({ |
|
|
|
|
|
|
|
/* 为需要放大的图片添加样式 */ |
|
|
|
.scaled-img { |
|
|
|
transform: scale(2.5); |
|
|
|
background-image: url('@/assets/img/AiEmotion/tree02.jpg'); |
|
|
|
background-size: 100% 100%; |
|
|
|
background-position: center; |
|
|
|
background-repeat: no-repeat; |
|
|
|
width: 70%; |
|
|
|
height: 400px; |
|
|
|
min-height: 400px; |
|
|
|
text-align: center; |
|
|
|
margin-top: 8%; |
|
|
|
margin: 0 auto; |
|
|
|
margin-top: 3%; |
|
|
|
} |
|
|
|
|
|
|
|
.lz-img { |
|
|
@ -1574,7 +1590,7 @@ defineExpose({ |
|
|
|
/* 设置容器宽度 */ |
|
|
|
height: auto; |
|
|
|
/* 高度根据内容动态变化 */ |
|
|
|
min-height: 57rem; |
|
|
|
min-height: 75rem; |
|
|
|
/* 设置最小高度,确保图片显示 */ |
|
|
|
margin: 0 auto; |
|
|
|
} |
|
|
@ -1777,6 +1793,7 @@ defineExpose({ |
|
|
|
.container { |
|
|
|
padding-top: 2%; |
|
|
|
} |
|
|
|
|
|
|
|
.title4 { |
|
|
|
color: white; |
|
|
|
font-size: 20px; |
|
|
@ -1790,9 +1807,15 @@ defineExpose({ |
|
|
|
} |
|
|
|
|
|
|
|
.scaled-img { |
|
|
|
transform: scale(1.5); |
|
|
|
background-image: url('@/assets/img/AiEmotion/tree02.jpg'); |
|
|
|
background-size: 100% 100%; |
|
|
|
background-position: center; |
|
|
|
background-repeat: no-repeat; |
|
|
|
text-align: center; |
|
|
|
width: 95%; |
|
|
|
margin-top: 6%; |
|
|
|
height: 200px; |
|
|
|
min-height: 200px; |
|
|
|
} |
|
|
|
|
|
|
|
.title3 { |
|
|
@ -1945,11 +1968,10 @@ defineExpose({ |
|
|
|
.class08 { |
|
|
|
background-size: 100% 100%; |
|
|
|
background-repeat: no-repeat; |
|
|
|
width: 127%; |
|
|
|
width: 100%; |
|
|
|
height: auto; |
|
|
|
min-height: 13rem; |
|
|
|
min-height: 20rem; |
|
|
|
margin: 0 auto; |
|
|
|
margin-left: -41px; |
|
|
|
} |
|
|
|
|
|
|
|
.bk-image { |
|
|
@ -1966,7 +1988,7 @@ defineExpose({ |
|
|
|
} |
|
|
|
|
|
|
|
.conclusion-title { |
|
|
|
color: #fff000; |
|
|
|
color: #FFD700; |
|
|
|
font-size: 16px; |
|
|
|
font-weight: bold; |
|
|
|
margin: 0 0 8px 0; |
|
|
@ -2041,18 +2063,14 @@ defineExpose({ |
|
|
|
opacity: 0.8; |
|
|
|
} |
|
|
|
|
|
|
|
&:hover { |
|
|
|
background: linear-gradient(135deg, rgba(0, 212, 255, 0.25) 0%, rgba(0, 150, 255, 0.15) 100%); |
|
|
|
transform: translateY(-2px) scale(1.02); |
|
|
|
box-shadow: 0 8px 25px rgba(0, 212, 255, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
&:last-child { |
|
|
|
margin-bottom: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.conclusion-title { |
|
|
|
color: #fff000; |
|
|
|
color: #FFD700; |
|
|
|
font-size: 22px; |
|
|
|
font-weight: bold; |
|
|
|
margin: 0 0 15px 0; |
|
|
@ -2075,7 +2093,7 @@ defineExpose({ |
|
|
|
|
|
|
|
.conclusion-text { |
|
|
|
color: #ffffff; |
|
|
|
font-size: 16px; |
|
|
|
font-size: 20px; |
|
|
|
line-height: 1.8; |
|
|
|
margin: 0 0 12px 0; |
|
|
|
text-align: left; |
|
|
|