|
@ -277,41 +277,76 @@ |
|
|
<img src="@/assets/img/AiEmotion/场景应用.png" alt="场景应用标题" /> |
|
|
<img src="@/assets/img/AiEmotion/场景应用.png" alt="场景应用标题" /> |
|
|
<div class="bk-image"> |
|
|
<div class="bk-image"> |
|
|
<div class="conclusion-container"> |
|
|
<div class="conclusion-container"> |
|
|
<!-- 使用打字机效果显示结论内容 --> |
|
|
|
|
|
<div class="conclusion-item" v-if="moduleVisibility.one"> |
|
|
|
|
|
<h4 class="conclusion-title">{{ displayedTitles.one }}</h4> |
|
|
|
|
|
<p class="conclusion-text" v-if="displayedTexts.one1"> |
|
|
|
|
|
{{ displayedTexts.one1 }} |
|
|
|
|
|
|
|
|
<!-- 使用当前股票项的结论数据显示内容,支持打字机效果 --> |
|
|
|
|
|
<!-- L1: 情绪监控 --> |
|
|
|
|
|
<div class="conclusion-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).one) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock) && (getStockConclusion(stock).one1 || getStockConclusion(stock).one2))"> |
|
|
|
|
|
<h4 class="conclusion-title">L1: 情绪监控</h4> |
|
|
|
|
|
<!-- 打字机效果文本 --> |
|
|
|
|
|
<p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).one1"> |
|
|
|
|
|
{{ getStockTypewriterTexts(stock).one1 }} |
|
|
</p> |
|
|
</p> |
|
|
<p class="conclusion-text" v-if="displayedTexts.one2"> |
|
|
|
|
|
{{ displayedTexts.one2 }} |
|
|
|
|
|
|
|
|
<p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).one2"> |
|
|
|
|
|
{{ getStockTypewriterTexts(stock).one2 }} |
|
|
|
|
|
</p> |
|
|
|
|
|
<!-- 完整文本 --> |
|
|
|
|
|
<p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).one1"> |
|
|
|
|
|
{{ getStockConclusion(stock).one1 }} |
|
|
|
|
|
</p> |
|
|
|
|
|
<p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).one2"> |
|
|
|
|
|
{{ getStockConclusion(stock).one2 }} |
|
|
</p> |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
<div class="conclusion-item" v-if="moduleVisibility.two"> |
|
|
|
|
|
<h4 class="conclusion-title">{{ displayedTitles.two }}</h4> |
|
|
|
|
|
<p class="conclusion-text">{{ displayedTexts.two }}</p> |
|
|
|
|
|
|
|
|
<!-- L2: 情绪解码 --> |
|
|
|
|
|
<div class="conclusion-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).two) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock) && getStockConclusion(stock).two)"> |
|
|
|
|
|
<h4 class="conclusion-title">L2: 情绪解码</h4> |
|
|
|
|
|
<!-- 打字机效果文本 --> |
|
|
|
|
|
<p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).two"> |
|
|
|
|
|
{{ getStockTypewriterTexts(stock).two }} |
|
|
|
|
|
</p> |
|
|
|
|
|
<!-- 完整文本 --> |
|
|
|
|
|
<p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).two"> |
|
|
|
|
|
{{ getStockConclusion(stock).two }} |
|
|
|
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
<div class="conclusion-item" v-if="moduleVisibility.three"> |
|
|
|
|
|
<h4 class="conclusion-title">{{ displayedTitles.three }}</h4> |
|
|
|
|
|
<p class="conclusion-text">{{ displayedTexts.three }}</p> |
|
|
|
|
|
|
|
|
<!-- L3: 情绪推演 --> |
|
|
|
|
|
<div class="conclusion-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).three) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock) && getStockConclusion(stock).three)"> |
|
|
|
|
|
<h4 class="conclusion-title">L3: 情绪推演</h4> |
|
|
|
|
|
<!-- 打字机效果文本 --> |
|
|
|
|
|
<p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).three"> |
|
|
|
|
|
{{ getStockTypewriterTexts(stock).three }} |
|
|
|
|
|
</p> |
|
|
|
|
|
<!-- 完整文本 --> |
|
|
|
|
|
<p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).three"> |
|
|
|
|
|
{{ getStockConclusion(stock).three }} |
|
|
|
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
<div class="conclusion-item" v-if="moduleVisibility.four"> |
|
|
|
|
|
<h4 class="conclusion-title">{{ displayedTitles.four }}</h4> |
|
|
|
|
|
<p class="conclusion-text">{{ displayedTexts.four }}</p> |
|
|
|
|
|
|
|
|
<!-- L4: 情绪套利 --> |
|
|
|
|
|
<div class="conclusion-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).four) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock) && getStockConclusion(stock).four)"> |
|
|
|
|
|
<h4 class="conclusion-title">L4: 情绪套利</h4> |
|
|
|
|
|
<!-- 打字机效果文本 --> |
|
|
|
|
|
<p class="conclusion-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).four"> |
|
|
|
|
|
{{ getStockTypewriterTexts(stock).four }} |
|
|
|
|
|
</p> |
|
|
|
|
|
<!-- 完整文本 --> |
|
|
|
|
|
<p class="conclusion-text" v-if="!getStockTypewriterTexts(stock) && getStockConclusion(stock) && getStockConclusion(stock).four"> |
|
|
|
|
|
{{ getStockConclusion(stock).four }} |
|
|
|
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
<!-- AI生成内容免责声明 --> |
|
|
<!-- AI生成内容免责声明 --> |
|
|
<div class="disclaimer-item" v-if="moduleVisibility.disclaimer"> |
|
|
|
|
|
<p class="disclaimer-text">{{ displayedTexts.disclaimer }}</p> |
|
|
|
|
|
|
|
|
<div class="disclaimer-item" v-if="(getStockTypewriterVisibility(stock) && getStockTypewriterVisibility(stock).disclaimer) || (getStockConclusion(stock) && !getStockTypewriterTexts(stock))"> |
|
|
|
|
|
<!-- 打字机效果文本 --> |
|
|
|
|
|
<p class="disclaimer-text" v-if="getStockTypewriterTexts(stock) && getStockTypewriterTexts(stock).disclaimer"> |
|
|
|
|
|
{{ getStockTypewriterTexts(stock).disclaimer }} |
|
|
|
|
|
</p> |
|
|
|
|
|
<!-- 完整文本 --> |
|
|
|
|
|
<p class="disclaimer-text" v-if="!getStockTypewriterTexts(stock)"> |
|
|
|
|
|
该内容由AI生成,请注意甄别 |
|
|
|
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div |
|
|
<div |
|
|
class="conclusion-placeholder" |
|
|
class="conclusion-placeholder" |
|
|
v-if=" |
|
|
|
|
|
!moduleVisibility.one && |
|
|
|
|
|
!moduleVisibility.two && |
|
|
|
|
|
!moduleVisibility.three && |
|
|
|
|
|
!moduleVisibility.four |
|
|
|
|
|
" |
|
|
|
|
|
|
|
|
v-if="!getStockConclusion(stock) || (!getStockConclusion(stock).one1 && !getStockConclusion(stock).one2 && !getStockConclusion(stock).two && !getStockConclusion(stock).three && !getStockConclusion(stock).four)" |
|
|
> |
|
|
> |
|
|
<p>等待股票分析结论...</p> |
|
|
<p>等待股票分析结论...</p> |
|
|
</div> |
|
|
</div> |
|
@ -565,30 +600,7 @@ const addStock = (stockData) => { |
|
|
stockTypewriterShown.value.clear(); |
|
|
stockTypewriterShown.value.clear(); |
|
|
stockAudioPlayed.value.clear(); |
|
|
stockAudioPlayed.value.clear(); |
|
|
|
|
|
|
|
|
// 清理显示的文本和标题 |
|
|
|
|
|
displayedTexts.value = { |
|
|
|
|
|
one1: "", |
|
|
|
|
|
one2: "", |
|
|
|
|
|
two: "", |
|
|
|
|
|
three: "", |
|
|
|
|
|
four: "", |
|
|
|
|
|
disclaimer: "", |
|
|
|
|
|
}; |
|
|
|
|
|
displayedTitles.value = { |
|
|
|
|
|
one: "", |
|
|
|
|
|
two: "", |
|
|
|
|
|
three: "", |
|
|
|
|
|
four: "", |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 隐藏所有模块 |
|
|
|
|
|
moduleVisibility.value = { |
|
|
|
|
|
one: false, |
|
|
|
|
|
two: false, |
|
|
|
|
|
three: false, |
|
|
|
|
|
four: false, |
|
|
|
|
|
disclaimer: false, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 清理状态变量(保留用于其他功能的变量) |
|
|
|
|
|
|
|
|
// 隐藏所有图表组件 |
|
|
// 隐藏所有图表组件 |
|
|
chartVisibility.value = { |
|
|
chartVisibility.value = { |
|
@ -603,50 +615,15 @@ const addStock = (stockData) => { |
|
|
// 3. 设置页面为已加载状态,重新渲染页面 |
|
|
// 3. 设置页面为已加载状态,重新渲染页面 |
|
|
isPageLoaded.value = true; |
|
|
isPageLoaded.value = true; |
|
|
|
|
|
|
|
|
// 4. 立即显示历史记录的结论文本 |
|
|
|
|
|
|
|
|
// 4. 标记历史记录股票已显示过,避免重复触发 |
|
|
if (stockData.conclusionData) { |
|
|
if (stockData.conclusionData) { |
|
|
try { |
|
|
|
|
|
const conclusion = |
|
|
|
|
|
typeof stockData.conclusionData === "object" |
|
|
|
|
|
? stockData.conclusionData |
|
|
|
|
|
: JSON.parse(stockData.conclusionData); |
|
|
|
|
|
|
|
|
|
|
|
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, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 标记该股票已显示过,避免重复触发 |
|
|
|
|
|
const stockCode = |
|
|
const stockCode = |
|
|
stockData.stockInfo?.code || stockData.stockInfo?.symbol; |
|
|
stockData.stockInfo?.code || stockData.stockInfo?.symbol; |
|
|
if (stockCode) { |
|
|
if (stockCode) { |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
console.log("历史记录结论文本已立即显示:", conclusion); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error("解析历史记录结论数据失败:", error); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
console.log("历史记录股票已标记为已显示"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 5. 使用nextTick确保DOM更新后启动高度监听器并滚动到底部 |
|
|
// 5. 使用nextTick确保DOM更新后启动高度监听器并滚动到底部 |
|
@ -681,32 +658,7 @@ const hasTriggeredTypewriter = ref(false); // 是否已触发打字机效果 |
|
|
const intersectionObserver = ref(null); // 存储observer实例 |
|
|
const intersectionObserver = ref(null); // 存储observer实例 |
|
|
const isUserInitiated = ref(false); // 标记是否为用户主动搜索 |
|
|
const isUserInitiated = ref(false); // 标记是否为用户主动搜索 |
|
|
|
|
|
|
|
|
// 显示的文本内容(用于打字机效果) |
|
|
|
|
|
const displayedTexts = ref({ |
|
|
|
|
|
one1: "", |
|
|
|
|
|
one2: "", |
|
|
|
|
|
two: "", |
|
|
|
|
|
three: "", |
|
|
|
|
|
four: "", |
|
|
|
|
|
disclaimer: "", |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 显示的标题内容(用于打字机效果) |
|
|
|
|
|
const displayedTitles = ref({ |
|
|
|
|
|
one: "", |
|
|
|
|
|
two: "", |
|
|
|
|
|
three: "", |
|
|
|
|
|
four: "", |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 模块显示状态 |
|
|
|
|
|
const moduleVisibility = ref({ |
|
|
|
|
|
one: false, |
|
|
|
|
|
two: false, |
|
|
|
|
|
three: false, |
|
|
|
|
|
four: false, |
|
|
|
|
|
disclaimer: false, |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
// 打字机效果相关的变量已移除,现在直接使用parsedConclusion显示内容 |
|
|
|
|
|
|
|
|
// 图表组件显示状态 |
|
|
// 图表组件显示状态 |
|
|
const chartVisibility = ref({ |
|
|
const chartVisibility = ref({ |
|
@ -718,6 +670,10 @@ const chartVisibility = ref({ |
|
|
const typewriterTimers = ref([]); |
|
|
const typewriterTimers = ref([]); |
|
|
// 记录每个股票是否已经显示过打字机效果 |
|
|
// 记录每个股票是否已经显示过打字机效果 |
|
|
const stockTypewriterShown = ref(new Map()); |
|
|
const stockTypewriterShown = ref(new Map()); |
|
|
|
|
|
// 记录每个股票的打字机显示状态 |
|
|
|
|
|
const stockTypewriterTexts = ref(new Map()); |
|
|
|
|
|
// 记录每个股票的打字机模块可见性 |
|
|
|
|
|
const stockTypewriterVisibility = ref(new Map()); |
|
|
// 记录每个股票是否已经播放过音频 |
|
|
// 记录每个股票是否已经播放过音频 |
|
|
const stockAudioPlayed = ref(new Map()); |
|
|
const stockAudioPlayed = ref(new Map()); |
|
|
// 跟踪每个股票的音频播放状态 |
|
|
// 跟踪每个股票的音频播放状态 |
|
@ -887,6 +843,27 @@ const getStockConclusion = (stock) => { |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数:获取股票的打字机文本状态 |
|
|
|
|
|
const getStockTypewriterTexts = (stock) => { |
|
|
|
|
|
const stockCode = stock.stockInfo?.code || stock.stockInfo?.symbol; |
|
|
|
|
|
if (!stockCode) return null; |
|
|
|
|
|
return stockTypewriterTexts.value.get(stockCode) || null; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数:获取股票的打字机可见性状态 |
|
|
|
|
|
const getStockTypewriterVisibility = (stock) => { |
|
|
|
|
|
const stockCode = stock.stockInfo?.code || stock.stockInfo?.symbol; |
|
|
|
|
|
if (!stockCode) return null; |
|
|
|
|
|
return stockTypewriterVisibility.value.get(stockCode) || null; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数:检查股票是否正在进行打字机效果 |
|
|
|
|
|
const isStockTypewriting = (stock) => { |
|
|
|
|
|
const stockCode = stock.stockInfo?.code || stock.stockInfo?.symbol; |
|
|
|
|
|
if (!stockCode) return false; |
|
|
|
|
|
return stockTypewriterShown.value.has(stockCode) && !stockTypewriterTexts.value.has(stockCode); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 监听股票列表变化,当列表为空时隐藏页面数据 |
|
|
// 监听股票列表变化,当列表为空时隐藏页面数据 |
|
|
watch( |
|
|
watch( |
|
|
() => emotionStore.stockList, |
|
|
() => emotionStore.stockList, |
|
@ -908,29 +885,6 @@ watch( |
|
|
stockAudioPlayed.value.clear(); |
|
|
stockAudioPlayed.value.clear(); |
|
|
// 清理已添加股票的记录 |
|
|
// 清理已添加股票的记录 |
|
|
addedStocks.value.clear(); |
|
|
addedStocks.value.clear(); |
|
|
// 清理显示的文本和标题 |
|
|
|
|
|
displayedTexts.value = { |
|
|
|
|
|
one1: "", |
|
|
|
|
|
one2: "", |
|
|
|
|
|
two: "", |
|
|
|
|
|
three: "", |
|
|
|
|
|
four: "", |
|
|
|
|
|
disclaimer: "", |
|
|
|
|
|
}; |
|
|
|
|
|
displayedTitles.value = { |
|
|
|
|
|
one: "", |
|
|
|
|
|
two: "", |
|
|
|
|
|
three: "", |
|
|
|
|
|
four: "", |
|
|
|
|
|
}; |
|
|
|
|
|
// 隐藏所有模块 |
|
|
|
|
|
moduleVisibility.value = { |
|
|
|
|
|
one: false, |
|
|
|
|
|
two: false, |
|
|
|
|
|
three: false, |
|
|
|
|
|
four: false, |
|
|
|
|
|
disclaimer: false, |
|
|
|
|
|
}; |
|
|
|
|
|
// 隐藏所有图表组件 |
|
|
// 隐藏所有图表组件 |
|
|
chartVisibility.value = { |
|
|
chartVisibility.value = { |
|
|
marketTemperature: false, |
|
|
marketTemperature: false, |
|
@ -947,7 +901,7 @@ watch( |
|
|
{ deep: true } |
|
|
{ deep: true } |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
// 监听当前股票变化,重新渲染图表 |
|
|
|
|
|
|
|
|
// 监听当前股票变化,重新渲染图表和显示对应结论 |
|
|
watch( |
|
|
watch( |
|
|
currentStock, |
|
|
currentStock, |
|
|
(newStock) => { |
|
|
(newStock) => { |
|
@ -968,9 +922,7 @@ watch( |
|
|
// 获取股票代码作为唯一标识 |
|
|
// 获取股票代码作为唯一标识 |
|
|
const stockCode = newStock.stockInfo?.code || newStock.stockInfo?.symbol; |
|
|
const stockCode = newStock.stockInfo?.code || newStock.stockInfo?.symbol; |
|
|
|
|
|
|
|
|
// 检查该股票是否已经显示过打字机效果 |
|
|
|
|
|
if (stockCode && stockTypewriterShown.value.has(stockCode)) { |
|
|
|
|
|
// 如果已经显示过,直接显示完整文本和标题 |
|
|
|
|
|
|
|
|
// 处理当前股票的音频URL |
|
|
if (newStock.conclusionData) { |
|
|
if (newStock.conclusionData) { |
|
|
try { |
|
|
try { |
|
|
// 如果conclusionData已经是对象,直接使用;否则解析JSON |
|
|
// 如果conclusionData已经是对象,直接使用;否则解析JSON |
|
@ -978,28 +930,10 @@ watch( |
|
|
typeof newStock.conclusionData === "object" |
|
|
typeof newStock.conclusionData === "object" |
|
|
? newStock.conclusionData |
|
|
? newStock.conclusionData |
|
|
: JSON.parse(newStock.conclusionData); |
|
|
: JSON.parse(newStock.conclusionData); |
|
|
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 (stockCode && stockTypewriterShown.value.has(stockCode)) { |
|
|
|
|
|
// 如果已经显示过,直接显示完整内容,不需要打字机效果 |
|
|
|
|
|
|
|
|
// 提取音频URL但不自动播放,等待用户手动点击 |
|
|
// 提取音频URL但不自动播放,等待用户手动点击 |
|
|
let voiceUrl = null; |
|
|
let voiceUrl = null; |
|
@ -1063,103 +997,15 @@ watch( |
|
|
emotionAudioStore.setCurrentAudioUrl(voiceUrl); |
|
|
emotionAudioStore.setCurrentAudioUrl(voiceUrl); |
|
|
// 不自动播放,等待用户手动点击 |
|
|
// 不自动播放,等待用户手动点击 |
|
|
} |
|
|
} |
|
|
} catch (error) { |
|
|
|
|
|
console.error("解析股票结论数据失败:", error); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
// 如果没有显示过,清空显示文本,等待打字机效果 |
|
|
|
|
|
displayedTexts.value = { |
|
|
|
|
|
one1: "", |
|
|
|
|
|
one2: "", |
|
|
|
|
|
two: "", |
|
|
|
|
|
three: "", |
|
|
|
|
|
four: "", |
|
|
|
|
|
disclaimer: "", |
|
|
|
|
|
}; |
|
|
|
|
|
displayedTitles.value = { |
|
|
|
|
|
one: "", |
|
|
|
|
|
two: "", |
|
|
|
|
|
three: "", |
|
|
|
|
|
four: "", |
|
|
|
|
|
}; |
|
|
|
|
|
moduleVisibility.value = { |
|
|
|
|
|
one: false, |
|
|
|
|
|
two: false, |
|
|
|
|
|
three: false, |
|
|
|
|
|
four: false, |
|
|
|
|
|
disclaimer: false, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 即使没有显示过,也需要设置音频URL以便用户手动播放 |
|
|
|
|
|
if (newStock.conclusionData) { |
|
|
|
|
|
try { |
|
|
|
|
|
// 如果conclusionData已经是对象,直接使用;否则解析JSON |
|
|
|
|
|
const conclusion = |
|
|
|
|
|
typeof newStock.conclusionData === "object" |
|
|
|
|
|
? newStock.conclusionData |
|
|
|
|
|
: JSON.parse(newStock.conclusionData); |
|
|
|
|
|
let voiceUrl = null; |
|
|
|
|
|
// 优先使用one1_url,如果没有则尝试其他音频URL |
|
|
|
|
|
if (conclusion.one1_url) { |
|
|
|
|
|
voiceUrl = conclusion.one1_url |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.one2_url) { |
|
|
|
|
|
voiceUrl = conclusion.one2_url |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.two_url) { |
|
|
|
|
|
voiceUrl = conclusion.two_url |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.three_url) { |
|
|
|
|
|
voiceUrl = conclusion.three_url |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.four_url) { |
|
|
|
|
|
voiceUrl = conclusion.four_url |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.url) { |
|
|
|
|
|
voiceUrl = conclusion.url.toString().trim().replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.audioUrl) { |
|
|
|
|
|
voiceUrl = conclusion.audioUrl |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.voice_url) { |
|
|
|
|
|
voiceUrl = conclusion.voice_url |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.audio) { |
|
|
|
|
|
voiceUrl = conclusion.audio |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} else if (conclusion.tts_url) { |
|
|
|
|
|
voiceUrl = conclusion.tts_url |
|
|
|
|
|
.toString() |
|
|
|
|
|
.trim() |
|
|
|
|
|
.replace(/[`\s]/g, ""); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (voiceUrl && voiceUrl.startsWith("http")) { |
|
|
|
|
|
console.log("切换到未显示股票,准备音频URL:", voiceUrl); |
|
|
|
|
|
audioUrl.value = voiceUrl; |
|
|
|
|
|
// 同时更新store中的音频URL |
|
|
|
|
|
emotionAudioStore.setCurrentAudioUrl(voiceUrl); |
|
|
|
|
|
} |
|
|
} |
|
|
} catch (error) { |
|
|
} catch (error) { |
|
|
console.error("解析股票结论数据失败:", error); |
|
|
console.error("解析股票结论数据失败:", error); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
// 如果没有结论数据,清空音频URL |
|
|
|
|
|
audioUrl.value = ""; |
|
|
|
|
|
emotionAudioStore.resetAudioState(); |
|
|
|
|
|
console.log("当前股票没有结论数据,已清空音频"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 只有在页面已加载的情况下才渲染图表 |
|
|
// 只有在页面已加载的情况下才渲染图表 |
|
@ -1213,7 +1059,7 @@ watch( |
|
|
playAudioQueue(parsedConclusion.value, true); |
|
|
playAudioQueue(parsedConclusion.value, true); |
|
|
} else { |
|
|
} else { |
|
|
// 如果音频已播放过,只启动打字机效果 |
|
|
// 如果音频已播放过,只启动打字机效果 |
|
|
startTypewriterEffect(parsedConclusion.value); |
|
|
|
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value, stockCode); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
@ -1229,27 +1075,7 @@ watch( |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
const conclusion = parsedConclusion.value; |
|
|
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, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 结论内容现在直接通过parsedConclusion计算属性显示 |
|
|
|
|
|
|
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
@ -1381,8 +1207,19 @@ watch( |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
// 打字机效果函数 |
|
|
// 打字机效果函数 |
|
|
function startTypewriterEffect(conclusion, onComplete) { |
|
|
|
|
|
console.log("开始打字机效果,结论数据:", conclusion); |
|
|
|
|
|
|
|
|
function startTypewriterEffect(conclusion, stockId, onComplete) { |
|
|
|
|
|
// 如果没有传入stockId,使用当前活跃股票 |
|
|
|
|
|
if (!stockId && emotionStore.activeStock) { |
|
|
|
|
|
const stock = emotionStore.activeStock; |
|
|
|
|
|
stockId = stock.stockInfo?.code || stock.stockInfo?.symbol; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!stockId) { |
|
|
|
|
|
console.warn("无法确定股票ID,跳过打字机效果"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
console.log("开始打字机效果,结论数据:", conclusion, "股票ID:", stockId); |
|
|
|
|
|
|
|
|
// 保存当前的完成回调函数 |
|
|
// 保存当前的完成回调函数 |
|
|
currentOnCompleteCallback.value = onComplete; |
|
|
currentOnCompleteCallback.value = onComplete; |
|
@ -1398,30 +1235,44 @@ function startTypewriterEffect(conclusion, onComplete) { |
|
|
typewriterTimers.value.forEach((timer) => clearTimeout(timer)); |
|
|
typewriterTimers.value.forEach((timer) => clearTimeout(timer)); |
|
|
typewriterTimers.value = []; |
|
|
typewriterTimers.value = []; |
|
|
|
|
|
|
|
|
// 重置显示文本和状态 |
|
|
|
|
|
displayedTexts.value = { |
|
|
|
|
|
|
|
|
// 初始化该股票的打字机状态 |
|
|
|
|
|
if (!stockTypewriterTexts.value.has(stockId)) { |
|
|
|
|
|
stockTypewriterTexts.value.set(stockId, { |
|
|
one1: "", |
|
|
one1: "", |
|
|
one2: "", |
|
|
one2: "", |
|
|
two: "", |
|
|
two: "", |
|
|
three: "", |
|
|
three: "", |
|
|
four: "", |
|
|
four: "", |
|
|
disclaimer: "", |
|
|
disclaimer: "", |
|
|
}; |
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
if (!stockTypewriterVisibility.value.has(stockId)) { |
|
|
|
|
|
stockTypewriterVisibility.value.set(stockId, { |
|
|
|
|
|
one: false, |
|
|
|
|
|
two: false, |
|
|
|
|
|
three: false, |
|
|
|
|
|
four: false, |
|
|
|
|
|
disclaimer: false, |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
displayedTitles.value = { |
|
|
|
|
|
one: "", |
|
|
|
|
|
|
|
|
// 重置该股票的显示文本和状态 |
|
|
|
|
|
stockTypewriterTexts.value.set(stockId, { |
|
|
|
|
|
one1: "", |
|
|
|
|
|
one2: "", |
|
|
two: "", |
|
|
two: "", |
|
|
three: "", |
|
|
three: "", |
|
|
four: "", |
|
|
four: "", |
|
|
}; |
|
|
|
|
|
|
|
|
disclaimer: "", |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
moduleVisibility.value = { |
|
|
|
|
|
|
|
|
stockTypewriterVisibility.value.set(stockId, { |
|
|
one: false, |
|
|
one: false, |
|
|
two: false, |
|
|
two: false, |
|
|
three: false, |
|
|
three: false, |
|
|
four: false, |
|
|
four: false, |
|
|
disclaimer: false, |
|
|
disclaimer: false, |
|
|
}; |
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
// 定义打字速度(毫秒) |
|
|
// 定义打字速度(毫秒) |
|
|
const typeSpeed = 200; |
|
|
const typeSpeed = 200; |
|
@ -1469,35 +1320,32 @@ function startTypewriterEffect(conclusion, onComplete) { |
|
|
if (!hasContent) return; |
|
|
if (!hasContent) return; |
|
|
|
|
|
|
|
|
console.log(`开始显示模块 ${module.key}`); |
|
|
console.log(`开始显示模块 ${module.key}`); |
|
|
|
|
|
|
|
|
// 显示模块 |
|
|
// 显示模块 |
|
|
const showModuleTimer = setTimeout(() => { |
|
|
const showModuleTimer = setTimeout(() => { |
|
|
moduleVisibility.value[module.key] = true; |
|
|
|
|
|
console.log(`模块 ${module.key} 已设置为可见`); |
|
|
|
|
|
|
|
|
const visibility = stockTypewriterVisibility.value.get(stockId); |
|
|
|
|
|
if (visibility) { |
|
|
|
|
|
visibility[module.key] = true; |
|
|
|
|
|
stockTypewriterVisibility.value.set(stockId, { ...visibility }); |
|
|
|
|
|
} |
|
|
}, totalDelay); |
|
|
}, totalDelay); |
|
|
typewriterTimers.value.push(showModuleTimer); |
|
|
typewriterTimers.value.push(showModuleTimer); |
|
|
totalDelay += 100; |
|
|
totalDelay += 100; |
|
|
|
|
|
|
|
|
// 打字机效果显示标题 |
|
|
|
|
|
const title = module.title; |
|
|
|
|
|
for (let i = 0; i <= title.length; i++) { |
|
|
|
|
|
const timer = setTimeout(() => { |
|
|
|
|
|
displayedTitles.value[module.key] = title.substring(0, i); |
|
|
|
|
|
}, totalDelay + i * typeSpeed); |
|
|
|
|
|
typewriterTimers.value.push(timer); |
|
|
|
|
|
} |
|
|
|
|
|
totalDelay += title.length * typeSpeed + 300; // 标题完成后间隔 |
|
|
|
|
|
|
|
|
|
|
|
// 打字机效果显示内容 |
|
|
|
|
|
|
|
|
// 为每个内容项添加打字机效果 |
|
|
module.contents.forEach((content) => { |
|
|
module.contents.forEach((content) => { |
|
|
if (content.text && content.text.trim()) { |
|
|
if (content.text && content.text.trim()) { |
|
|
const text = content.text; |
|
|
|
|
|
for (let i = 0; i <= text.length; i++) { |
|
|
|
|
|
|
|
|
for (let i = 0; i <= content.text.length; i++) { |
|
|
const timer = setTimeout(() => { |
|
|
const timer = setTimeout(() => { |
|
|
displayedTexts.value[content.key] = text.substring(0, i); |
|
|
|
|
|
|
|
|
const texts = stockTypewriterTexts.value.get(stockId); |
|
|
|
|
|
if (texts) { |
|
|
|
|
|
texts[content.key] = content.text.substring(0, i); |
|
|
|
|
|
stockTypewriterTexts.value.set(stockId, { ...texts }); |
|
|
|
|
|
} |
|
|
}, totalDelay + i * typeSpeed); |
|
|
}, totalDelay + i * typeSpeed); |
|
|
typewriterTimers.value.push(timer); |
|
|
typewriterTimers.value.push(timer); |
|
|
} |
|
|
} |
|
|
totalDelay += text.length * typeSpeed + 500; // 内容完成后间隔 |
|
|
|
|
|
|
|
|
totalDelay += content.text.length * typeSpeed + 200; // 内容间间隔 |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
@ -1509,7 +1357,11 @@ function startTypewriterEffect(conclusion, onComplete) { |
|
|
|
|
|
|
|
|
// 显示免责声明模块 |
|
|
// 显示免责声明模块 |
|
|
const showDisclaimerTimer = setTimeout(() => { |
|
|
const showDisclaimerTimer = setTimeout(() => { |
|
|
moduleVisibility.value.disclaimer = true; |
|
|
|
|
|
|
|
|
const visibility = stockTypewriterVisibility.value.get(stockId); |
|
|
|
|
|
if (visibility) { |
|
|
|
|
|
visibility.disclaimer = true; |
|
|
|
|
|
stockTypewriterVisibility.value.set(stockId, { ...visibility }); |
|
|
|
|
|
} |
|
|
}, totalDelay); |
|
|
}, totalDelay); |
|
|
typewriterTimers.value.push(showDisclaimerTimer); |
|
|
typewriterTimers.value.push(showDisclaimerTimer); |
|
|
totalDelay += 100; |
|
|
totalDelay += 100; |
|
@ -1517,7 +1369,11 @@ function startTypewriterEffect(conclusion, onComplete) { |
|
|
// 打字机效果显示免责声明 |
|
|
// 打字机效果显示免责声明 |
|
|
for (let i = 0; i <= disclaimerText.length; i++) { |
|
|
for (let i = 0; i <= disclaimerText.length; i++) { |
|
|
const timer = setTimeout(() => { |
|
|
const timer = setTimeout(() => { |
|
|
displayedTexts.value.disclaimer = disclaimerText.substring(0, i); |
|
|
|
|
|
|
|
|
const texts = stockTypewriterTexts.value.get(stockId); |
|
|
|
|
|
if (texts) { |
|
|
|
|
|
texts.disclaimer = disclaimerText.substring(0, i); |
|
|
|
|
|
stockTypewriterTexts.value.set(stockId, { ...texts }); |
|
|
|
|
|
} |
|
|
// 在免责声明打字机效果完成后调用回调函数 |
|
|
// 在免责声明打字机效果完成后调用回调函数 |
|
|
if (i === disclaimerText.length) { |
|
|
if (i === disclaimerText.length) { |
|
|
console.log("打字机效果完成,调用onComplete回调"); |
|
|
console.log("打字机效果完成,调用onComplete回调"); |
|
@ -1628,7 +1484,9 @@ const playNextAudio = () => { |
|
|
parsedConclusion.value |
|
|
parsedConclusion.value |
|
|
) { |
|
|
) { |
|
|
console.log("🎬 第一个音频开始播放,同时启动打字机效果"); |
|
|
console.log("🎬 第一个音频开始播放,同时启动打字机效果"); |
|
|
startTypewriterEffect(parsedConclusion.value, audioInfo.onComplete); |
|
|
|
|
|
|
|
|
const currentStock = emotionStore.activeStock; |
|
|
|
|
|
const stockId = currentStock?.stockInfo?.code || currentStock?.stockInfo?.symbol; |
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value, stockId, audioInfo.onComplete); |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
onpause: () => { |
|
|
onpause: () => { |
|
@ -1854,7 +1712,9 @@ function playAudioQueue( |
|
|
// 如果没有音频但需要启动打字机效果,直接启动 |
|
|
// 如果没有音频但需要启动打字机效果,直接启动 |
|
|
if (shouldStartTypewriter) { |
|
|
if (shouldStartTypewriter) { |
|
|
console.log("没有音频但需要启动打字机效果"); |
|
|
console.log("没有音频但需要启动打字机效果"); |
|
|
startTypewriterEffect(conclusion, onComplete); |
|
|
|
|
|
|
|
|
const currentStock = emotionStore.activeStock; |
|
|
|
|
|
const stockId = currentStock?.stockInfo?.code || currentStock?.stockInfo?.symbol; |
|
|
|
|
|
startTypewriterEffect(conclusion, stockId, onComplete); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
console.log(`总共找到 ${audioQueue.value.length} 个音频,准备播放`); |
|
|
console.log(`总共找到 ${audioQueue.value.length} 个音频,准备播放`); |
|
@ -2295,7 +2155,8 @@ async function handleSendMessage(input, onComplete) { |
|
|
playAudioQueue(parsedConclusion.value, true, onComplete); |
|
|
playAudioQueue(parsedConclusion.value, true, onComplete); |
|
|
} else { |
|
|
} else { |
|
|
// 如果音频已播放过,只启动打字机效果 |
|
|
// 如果音频已播放过,只启动打字机效果 |
|
|
startTypewriterEffect(parsedConclusion.value, onComplete); |
|
|
|
|
|
|
|
|
const stockCode = currentStock.value?.stockInfo?.code || currentStock.value?.stockInfo?.symbol; |
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value, stockCode, onComplete); |
|
|
} |
|
|
} |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
} else { |
|
|
} else { |
|
@ -2975,7 +2836,7 @@ function setupIntersectionObserver() { |
|
|
playAudioQueue(parsedConclusion.value, true); |
|
|
playAudioQueue(parsedConclusion.value, true); |
|
|
} else { |
|
|
} else { |
|
|
// 如果音频已播放过,只启动打字机效果 |
|
|
// 如果音频已播放过,只启动打字机效果 |
|
|
startTypewriterEffect(parsedConclusion.value); |
|
|
|
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value, stockCode); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
@ -2985,29 +2846,7 @@ function setupIntersectionObserver() { |
|
|
"非用户主动搜索,该股票第一次进入场景应用,直接显示完整内容" |
|
|
"非用户主动搜索,该股票第一次进入场景应用,直接显示完整内容" |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
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, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 结论内容现在直接通过parsedConclusion计算属性显示 |
|
|
|
|
|
|
|
|
// 记录该股票已显示过 |
|
|
// 记录该股票已显示过 |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
@ -3017,30 +2856,7 @@ function setupIntersectionObserver() { |
|
|
// 非第一次或已经触发过:直接显示完整内容,不播放音频和打字机效果 |
|
|
// 非第一次或已经触发过:直接显示完整内容,不播放音频和打字机效果 |
|
|
console.log("非第一次进入场景应用或已触发过,直接显示完整内容"); |
|
|
console.log("非第一次进入场景应用或已触发过,直接显示完整内容"); |
|
|
|
|
|
|
|
|
// 直接显示完整内容 |
|
|
|
|
|
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, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 结论内容现在直接通过parsedConclusion计算属性显示 |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -3358,31 +3174,8 @@ onMounted(async () => { |
|
|
if (currentStockData.conclusionData) { |
|
|
if (currentStockData.conclusionData) { |
|
|
conclusionData.value = currentStockData.conclusionData; |
|
|
conclusionData.value = currentStockData.conclusionData; |
|
|
|
|
|
|
|
|
// 直接显示所有内容,不使用打字机效果 |
|
|
|
|
|
const conclusion = currentStockData.conclusionData; |
|
|
|
|
|
displayedTexts.value = { |
|
|
|
|
|
one1: conclusion.one1 || "", |
|
|
|
|
|
one2: conclusion.one2 || "", |
|
|
|
|
|
two: conclusion.two || "", |
|
|
|
|
|
three: conclusion.three || "", |
|
|
|
|
|
four: conclusion.four || "", |
|
|
|
|
|
disclaimer: "该内容由AI生成,请注意甄别", |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
displayedTitles.value = { |
|
|
|
|
|
one: conclusion.one1 || conclusion.one2 ? "L1: 情绪监控" : "", |
|
|
|
|
|
two: conclusion.two ? "L2: 情绪解码" : "", |
|
|
|
|
|
three: conclusion.three ? "L3: 情绪推演" : "", |
|
|
|
|
|
four: conclusion.four ? "L4: 情绪套利" : "", |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
moduleVisibility.value = { |
|
|
|
|
|
one: !!(conclusion.one1 || conclusion.one2), |
|
|
|
|
|
two: !!conclusion.two, |
|
|
|
|
|
three: !!conclusion.three, |
|
|
|
|
|
four: !!conclusion.four, |
|
|
|
|
|
disclaimer: true, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 结论内容现在直接通过parsedConclusion计算属性显示 |
|
|
|
|
|
conclusionData.value = currentStockData.conclusionData; |
|
|
|
|
|
|
|
|
// 标记该股票的打字机效果和音频已经显示过,避免后续自动触发 |
|
|
// 标记该股票的打字机效果和音频已经显示过,避免后续自动触发 |
|
|
const stockCode = |
|
|
const stockCode = |
|
|