|
@ -45,11 +45,11 @@ |
|
|
</div> |
|
|
</div> |
|
|
<span class="span02">{{ displayDate }}</span> |
|
|
<span class="span02">{{ displayDate }}</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="class0201"> |
|
|
|
|
|
|
|
|
<div class="class0201" v-if="chartVisibility.marketTemperature"> |
|
|
<img src="@/assets/img/AiEmotion/L1.png" alt="情绪监控图标"> |
|
|
<img src="@/assets/img/AiEmotion/L1.png" alt="情绪监控图标"> |
|
|
</div> |
|
|
</div> |
|
|
<!-- 温度计图表 --> |
|
|
<!-- 温度计图表 --> |
|
|
<div class="class03"> |
|
|
|
|
|
|
|
|
<div class="class03" v-if="chartVisibility.marketTemperature"> |
|
|
<div class="class003"> |
|
|
<div class="class003"> |
|
|
<div class="content1"> |
|
|
<div class="content1"> |
|
|
<img class="img01" src="@/assets/img/AiEmotion/温度计.png" alt="温度计图标"> |
|
|
<img class="img01" src="@/assets/img/AiEmotion/温度计.png" alt="温度计图标"> |
|
@ -63,11 +63,11 @@ |
|
|
<marketTemperature ref="marketTemperatureRef" /> |
|
|
<marketTemperature ref="marketTemperatureRef" /> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="class0301"> |
|
|
|
|
|
|
|
|
<div class="class0301" v-if="chartVisibility.emotionDecod"> |
|
|
<img src="@/assets/img/AiEmotion/L2.png" alt="情绪解码图标"> |
|
|
<img src="@/assets/img/AiEmotion/L2.png" alt="情绪解码图标"> |
|
|
</div> |
|
|
</div> |
|
|
<!-- 情绪解码器图表 --> |
|
|
<!-- 情绪解码器图表 --> |
|
|
<div class="class04"> |
|
|
|
|
|
|
|
|
<div class="class04" v-if="chartVisibility.emotionDecod"> |
|
|
<div class="class0401"> |
|
|
<div class="class0401"> |
|
|
<img class="img02" src='@/assets/img/AiEmotion/emotionDecod.png' alt="情绪解码器图标"> |
|
|
<img class="img02" src='@/assets/img/AiEmotion/emotionDecod.png' alt="情绪解码器图标"> |
|
|
<span class="title2">情绪解码器</span> |
|
|
<span class="title2">情绪解码器</span> |
|
@ -76,11 +76,11 @@ |
|
|
<emotionDecod ref="emotionDecodRef"></emotionDecod> |
|
|
<emotionDecod ref="emotionDecodRef"></emotionDecod> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="class0403"> |
|
|
|
|
|
|
|
|
<div class="class0403" v-if="chartVisibility.emotionalBottomRadar"> |
|
|
<img src="@/assets/img/AiEmotion/L3.png" alt="情绪推演图标"> |
|
|
<img src="@/assets/img/AiEmotion/L3.png" alt="情绪推演图标"> |
|
|
</div> |
|
|
</div> |
|
|
<!-- 情绪探底雷达图表 --> |
|
|
<!-- 情绪探底雷达图表 --> |
|
|
<div class="class05"> |
|
|
|
|
|
|
|
|
<div class="class05" v-if="chartVisibility.emotionalBottomRadar"> |
|
|
<div class="class0502"> |
|
|
<div class="class0502"> |
|
|
<img class="img03" src="@/assets/img/AiEmotion/探底雷达.png" alt="探底雷达图表"> |
|
|
<img class="img03" src="@/assets/img/AiEmotion/探底雷达.png" alt="探底雷达图表"> |
|
|
<span class="title3">情绪探底雷达</span> |
|
|
<span class="title3">情绪探底雷达</span> |
|
@ -89,11 +89,11 @@ |
|
|
<emotionalBottomRadar ref="emotionalBottomRadarRef"></emotionalBottomRadar> |
|
|
<emotionalBottomRadar ref="emotionalBottomRadarRef"></emotionalBottomRadar> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="class0501"> |
|
|
|
|
|
|
|
|
<div class="class0501" v-if="chartVisibility.emoEnergyConverter"> |
|
|
<img src="@/assets/img/AiEmotion/L4.png" alt="情绪套利"> |
|
|
<img src="@/assets/img/AiEmotion/L4.png" alt="情绪套利"> |
|
|
</div> |
|
|
</div> |
|
|
<!-- 情绪能量转化器图表 --> |
|
|
<!-- 情绪能量转化器图表 --> |
|
|
<div class="class06"> |
|
|
|
|
|
|
|
|
<div class="class06" v-if="chartVisibility.emoEnergyConverter"> |
|
|
<div class="class0601"> |
|
|
<div class="class0601"> |
|
|
<img class="img04" src="@/assets/img/AiEmotion/能量转化器.png" alt="能量转化器图标"> |
|
|
<img class="img04" src="@/assets/img/AiEmotion/能量转化器.png" alt="能量转化器图标"> |
|
|
<span class="title4">情绪能量转化器</span> |
|
|
<span class="title4">情绪能量转化器</span> |
|
@ -277,6 +277,14 @@ const moduleVisibility = ref({ |
|
|
four: false, |
|
|
four: false, |
|
|
disclaimer: false |
|
|
disclaimer: false |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 图表组件显示状态 |
|
|
|
|
|
const chartVisibility = ref({ |
|
|
|
|
|
marketTemperature: false, |
|
|
|
|
|
emotionDecod: false, |
|
|
|
|
|
emotionalBottomRadar: false, |
|
|
|
|
|
emoEnergyConverter: false |
|
|
|
|
|
}); |
|
|
const typewriterTimers = ref([]); |
|
|
const typewriterTimers = ref([]); |
|
|
// 记录每个股票是否已经显示过打字机效果 |
|
|
// 记录每个股票是否已经显示过打字机效果 |
|
|
const stockTypewriterShown = ref(new Map()); |
|
|
const stockTypewriterShown = ref(new Map()); |
|
@ -372,6 +380,13 @@ watch(() => emotionStore.stockList, (newStockList) => { |
|
|
four: false, |
|
|
four: false, |
|
|
disclaimer: false |
|
|
disclaimer: false |
|
|
}; |
|
|
}; |
|
|
|
|
|
// 隐藏所有图表组件 |
|
|
|
|
|
chartVisibility.value = { |
|
|
|
|
|
marketTemperature: false, |
|
|
|
|
|
emotionDecod: false, |
|
|
|
|
|
emotionalBottomRadar: false, |
|
|
|
|
|
emoEnergyConverter: false |
|
|
|
|
|
}; |
|
|
console.log('股票列表已清空,页面数据已隐藏'); |
|
|
console.log('股票列表已清空,页面数据已隐藏'); |
|
|
} |
|
|
} |
|
|
}, { deep: true }); |
|
|
}, { deep: true }); |
|
@ -583,6 +598,13 @@ watch(currentStock, (newStock) => { |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
console.log('股票数据不存在或API数据未加载'); |
|
|
console.log('股票数据不存在或API数据未加载'); |
|
|
|
|
|
// 隐藏所有图表组件 |
|
|
|
|
|
chartVisibility.value = { |
|
|
|
|
|
marketTemperature: false, |
|
|
|
|
|
emotionDecod: false, |
|
|
|
|
|
emotionalBottomRadar: false, |
|
|
|
|
|
emoEnergyConverter: false |
|
|
|
|
|
}; |
|
|
} |
|
|
} |
|
|
}, { immediate: true }); |
|
|
}, { immediate: true }); |
|
|
|
|
|
|
|
@ -625,7 +647,7 @@ watch(parsedConclusion, (newConclusion) => { |
|
|
}, { immediate: true }); |
|
|
}, { immediate: true }); |
|
|
|
|
|
|
|
|
// 打字机效果函数 |
|
|
// 打字机效果函数 |
|
|
function startTypewriterEffect(conclusion) { |
|
|
|
|
|
|
|
|
function startTypewriterEffect(conclusion, onComplete) { |
|
|
console.log('开始打字机效果,结论数据:', conclusion); |
|
|
console.log('开始打字机效果,结论数据:', conclusion); |
|
|
|
|
|
|
|
|
// 详细调试各个字段 |
|
|
// 详细调试各个字段 |
|
@ -758,10 +780,14 @@ function startTypewriterEffect(conclusion) { |
|
|
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); |
|
|
displayedTexts.value.disclaimer = disclaimerText.substring(0, i); |
|
|
// 在打字机效果的最后一个字符显示完成后,滚动到底部 |
|
|
|
|
|
|
|
|
// 在打字机效果的最后一个字符显示完成后,滚动到底部并调用完成回调 |
|
|
if (i === disclaimerText.length) { |
|
|
if (i === disclaimerText.length) { |
|
|
setTimeout(() => { |
|
|
setTimeout(() => { |
|
|
scrollToBottom(); |
|
|
scrollToBottom(); |
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
|
|
onComplete(); |
|
|
|
|
|
} |
|
|
}, 100); |
|
|
}, 100); |
|
|
} |
|
|
} |
|
|
}, totalDelay + i * typeSpeed); |
|
|
}, totalDelay + i * typeSpeed); |
|
@ -877,7 +903,7 @@ function startImageRotation() { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 发送消息方法 |
|
|
// 发送消息方法 |
|
|
async function handleSendMessage(input) { |
|
|
|
|
|
|
|
|
async function handleSendMessage(input, onComplete) { |
|
|
console.log("发送内容:", input); |
|
|
console.log("发送内容:", input); |
|
|
// 标记为用户主动搜索 |
|
|
// 标记为用户主动搜索 |
|
|
isUserInitiated.value = true; |
|
|
isUserInitiated.value = true; |
|
@ -885,6 +911,10 @@ async function handleSendMessage(input) { |
|
|
// 检查用户输入内容是否为空 |
|
|
// 检查用户输入内容是否为空 |
|
|
if (!input || !input.trim()) { |
|
|
if (!input || !input.trim()) { |
|
|
ElMessage.warning("输入内容不能为空"); |
|
|
ElMessage.warning("输入内容不能为空"); |
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
|
|
onComplete(); |
|
|
|
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -903,6 +933,10 @@ async function handleSendMessage(input) { |
|
|
// 停止图片旋转,恢复历史数据 |
|
|
// 停止图片旋转,恢复历史数据 |
|
|
isRotating.value = false; |
|
|
isRotating.value = false; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
|
|
onComplete(); |
|
|
|
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -920,6 +954,10 @@ async function handleSendMessage(input) { |
|
|
// 停止图片旋转,恢复历史数据 |
|
|
// 停止图片旋转,恢复历史数据 |
|
|
isRotating.value = false; |
|
|
isRotating.value = false; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
|
|
onComplete(); |
|
|
|
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -947,7 +985,6 @@ async function handleSendMessage(input) { |
|
|
const result = await getReplyAPI(params); |
|
|
const result = await getReplyAPI(params); |
|
|
const response = await result.json(); |
|
|
const response = await result.json(); |
|
|
const parsedData = JSON.parse(response.data); |
|
|
const parsedData = JSON.parse(response.data); |
|
|
console.log("第一个接口解析后的数据:", parsedData); |
|
|
|
|
|
|
|
|
|
|
|
// 检查用户输入是否合法 |
|
|
// 检查用户输入是否合法 |
|
|
if (!parsedData || !parsedData.market || !parsedData.code) { |
|
|
if (!parsedData || !parsedData.market || !parsedData.code) { |
|
@ -956,6 +993,10 @@ async function handleSendMessage(input) { |
|
|
messages.value.push(aiMessage); |
|
|
messages.value.push(aiMessage); |
|
|
isRotating.value = false; |
|
|
isRotating.value = false; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
|
|
onComplete(); |
|
|
|
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -963,7 +1004,6 @@ async function handleSendMessage(input) { |
|
|
// 设置加载状态,隐藏图表页面 |
|
|
// 设置加载状态,隐藏图表页面 |
|
|
isLoading.value = true; |
|
|
isLoading.value = true; |
|
|
|
|
|
|
|
|
console.log("工作流接口返回股票信息:", parsedData); |
|
|
|
|
|
isPageLoaded.value = false; |
|
|
isPageLoaded.value = false; |
|
|
|
|
|
|
|
|
// 调用第二个工作流接口 |
|
|
// 调用第二个工作流接口 |
|
@ -985,7 +1025,6 @@ async function handleSendMessage(input) { |
|
|
|
|
|
|
|
|
// 处理结论接口返回的数据 |
|
|
// 处理结论接口返回的数据 |
|
|
const conclusionResponse = await conclusionResult.json(); |
|
|
const conclusionResponse = await conclusionResult.json(); |
|
|
console.log("第二个工作流接口返回数据:", conclusionResponse); |
|
|
|
|
|
|
|
|
|
|
|
// 检查所有数据是否都加载成功 |
|
|
// 检查所有数据是否都加载成功 |
|
|
if (conclusionResponse && conclusionResponse.data && fetchDataResult) { |
|
|
if (conclusionResponse && conclusionResponse.data && fetchDataResult) { |
|
@ -1006,26 +1045,28 @@ async function handleSendMessage(input) { |
|
|
console.error('更新用户次数失败:', error); |
|
|
console.error('更新用户次数失败:', error); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
console.log('所有数据加载完成,开始渲染页面'); |
|
|
|
|
|
|
|
|
|
|
|
// 确保页面状态更新后触发图表渲染和音频文本 |
|
|
// 确保页面状态更新后触发图表渲染和音频文本 |
|
|
nextTick(() => { |
|
|
nextTick(() => { |
|
|
if (currentStock.value && currentStock.value.apiData) { |
|
|
if (currentStock.value && currentStock.value.apiData) { |
|
|
renderCharts(currentStock.value.apiData); |
|
|
renderCharts(currentStock.value.apiData); |
|
|
console.log('数据加载完成后开始渲染图表'); |
|
|
|
|
|
|
|
|
|
|
|
// 只有在用户主动搜索时才自动触发音频和文本 |
|
|
// 只有在用户主动搜索时才自动触发音频和文本 |
|
|
if (isUserInitiated.value && parsedConclusion.value && audioUrl.value) { |
|
|
if (isUserInitiated.value && parsedConclusion.value && audioUrl.value) { |
|
|
const stockCode = currentStock.value.stockInfo?.code || currentStock.value.stockInfo?.symbol; |
|
|
const stockCode = currentStock.value.stockInfo?.code || currentStock.value.stockInfo?.symbol; |
|
|
if (stockCode && !stockTypewriterShown.value.has(stockCode)) { |
|
|
if (stockCode && !stockTypewriterShown.value.has(stockCode)) { |
|
|
console.log('用户主动搜索,立即触发音频和打字机效果'); |
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value); |
|
|
|
|
|
|
|
|
startTypewriterEffect(parsedConclusion.value, onComplete); |
|
|
|
|
|
|
|
|
if (!stockAudioPlayed.value.has(stockCode)) { |
|
|
if (!stockAudioPlayed.value.has(stockCode)) { |
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
stockAudioPlayed.value.set(stockCode, true); |
|
|
playAudio(audioUrl.value); |
|
|
playAudio(audioUrl.value); |
|
|
} |
|
|
} |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
stockTypewriterShown.value.set(stockCode, true); |
|
|
|
|
|
} else { |
|
|
|
|
|
// 如果不需要打字机效果,直接调用完成回调 |
|
|
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
|
|
onComplete(); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1040,6 +1081,10 @@ async function handleSendMessage(input) { |
|
|
messages.value.push(aiMessage); |
|
|
messages.value.push(aiMessage); |
|
|
isRotating.value = false; |
|
|
isRotating.value = false; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
|
|
onComplete(); |
|
|
|
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
} catch (error) { |
|
|
} catch (error) { |
|
@ -1048,6 +1093,10 @@ async function handleSendMessage(input) { |
|
|
// 请求失败时停止图片旋转,恢复历史数据 |
|
|
// 请求失败时停止图片旋转,恢复历史数据 |
|
|
isRotating.value = false; |
|
|
isRotating.value = false; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
|
|
onComplete(); |
|
|
|
|
|
} |
|
|
return; |
|
|
return; |
|
|
} finally { |
|
|
} finally { |
|
|
// 停止图片旋转(只有在设置了旋转状态时才需要停止) |
|
|
// 停止图片旋转(只有在设置了旋转状态时才需要停止) |
|
@ -1082,11 +1131,8 @@ async function fetchData(code, market, stockName, queryText) { |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
const stockDataResponse = stockDataResult.data; // 获取返回所有的数据 |
|
|
const stockDataResponse = stockDataResult.data; // 获取返回所有的数据 |
|
|
console.log('图表数据接口返回数据:', stockDataResponse.data); |
|
|
|
|
|
|
|
|
|
|
|
if (stockDataResponse.code === 200 && stockDataResponse.data) { |
|
|
if (stockDataResponse.code === 200 && stockDataResponse.data) { |
|
|
console.log(stockDataResponse.code) |
|
|
|
|
|
|
|
|
|
|
|
// 创建股票数据对象 |
|
|
// 创建股票数据对象 |
|
|
const stockData = { |
|
|
const stockData = { |
|
|
queryText: queryText, |
|
|
queryText: queryText, |
|
@ -1108,7 +1154,6 @@ async function fetchData(code, market, stockName, queryText) { |
|
|
return false; // 返回失败标识 |
|
|
return false; // 返回失败标识 |
|
|
} |
|
|
} |
|
|
} catch (error) { |
|
|
} catch (error) { |
|
|
console.error('fetchData error:', error); |
|
|
|
|
|
const aiMessage = reactive({ sender: 'ai', text: '图表数据请求失败,请检查网络连接' }); |
|
|
const aiMessage = reactive({ sender: 'ai', text: '图表数据请求失败,请检查网络连接' }); |
|
|
messages.value.push(aiMessage); |
|
|
messages.value.push(aiMessage); |
|
|
return false; // 返回失败标识 |
|
|
return false; // 返回失败标识 |
|
@ -1117,52 +1162,114 @@ async function fetchData(code, market, stockName, queryText) { |
|
|
|
|
|
|
|
|
// 渲染组件图表的方法 |
|
|
// 渲染组件图表的方法 |
|
|
function renderCharts(data) { |
|
|
function renderCharts(data) { |
|
|
|
|
|
console.log('开始渲染图表,数据:', data); |
|
|
|
|
|
|
|
|
|
|
|
// 深拷贝数据避免污染原始数据 |
|
|
|
|
|
const clonedData = JSON.parse(JSON.stringify(data)); |
|
|
|
|
|
|
|
|
|
|
|
// 先设置图表组件显示状态 |
|
|
|
|
|
chartVisibility.value = { |
|
|
|
|
|
marketTemperature: !!(clonedData.GSWDJ && clonedData.GSWDJ.length > 0), |
|
|
|
|
|
emotionDecod: !!(clonedData.QXJMQ && clonedData.QXJMQ.length > 0), |
|
|
|
|
|
emotionalBottomRadar: !!(clonedData.QXTDLD && clonedData.QXTDLD.length > 0), |
|
|
|
|
|
emoEnergyConverter: !!(clonedData.QXNLZHQ && clonedData.QXNLZHQ.length > 0) |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
console.log('图表显示状态:', chartVisibility.value); |
|
|
|
|
|
|
|
|
nextTick(() => { |
|
|
nextTick(() => { |
|
|
// 添加小延迟确保DOM完全更新 |
|
|
|
|
|
|
|
|
// 增加延迟确保DOM完全更新和组件完全挂载 |
|
|
setTimeout(() => { |
|
|
setTimeout(() => { |
|
|
try { |
|
|
try { |
|
|
// 深拷贝数据避免污染原始数据 |
|
|
|
|
|
const clonedData = JSON.parse(JSON.stringify(data)); |
|
|
|
|
|
console.log('已深拷贝数据,避免污染原始数据'); |
|
|
|
|
|
console.log('所有数据1111111111111:', clonedData) |
|
|
|
|
|
|
|
|
console.log('图表组件ref状态:', { |
|
|
|
|
|
marketTemperatureRef: !!marketTemperatureRef.value, |
|
|
|
|
|
emotionDecodRef: !!emotionDecodRef.value, |
|
|
|
|
|
emotionalBottomRadarRef: !!emotionalBottomRadarRef.value, |
|
|
|
|
|
emoEnergyConverterRef: !!emoEnergyConverterRef.value |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
// 渲染股市温度计图表 |
|
|
// 渲染股市温度计图表 |
|
|
if (marketTemperatureRef.value && clonedData.GSWDJ) { |
|
|
|
|
|
console.log("开始渲染股市温度计图表"); |
|
|
|
|
|
console.log("股市温度计数据", clonedData.GSWDJ); |
|
|
|
|
|
|
|
|
if (marketTemperatureRef.value && chartVisibility.value.marketTemperature) { |
|
|
|
|
|
console.log('开始渲染股市温度计图表'); |
|
|
|
|
|
console.log('marketTemperatureRef方法:', typeof marketTemperatureRef.value.initChart); |
|
|
|
|
|
if (typeof marketTemperatureRef.value.initChart === 'function') { |
|
|
|
|
|
try { |
|
|
marketTemperatureRef.value.initChart(clonedData.GSWDJ, clonedData.KLine20, clonedData.WDRL); |
|
|
marketTemperatureRef.value.initChart(clonedData.GSWDJ, clonedData.KLine20, clonedData.WDRL); |
|
|
console.log("股市温度计图表已渲染"); |
|
|
|
|
|
|
|
|
console.log('股市温度计图表渲染成功'); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('股市温度计图表渲染失败:', error); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
console.error('marketTemperatureRef.initChart 方法不存在'); |
|
|
} |
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
console.log('股市温度计图表未渲染,ref存在:', !!marketTemperatureRef.value, '数据存在:', chartVisibility.value.marketTemperature); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 渲染情绪解码器图表 |
|
|
// 渲染情绪解码器图表 |
|
|
if (emotionDecodRef.value && clonedData.QXJMQ) { |
|
|
|
|
|
console.log("开始渲染情绪解码器图表"); |
|
|
|
|
|
console.log("情绪解码器数据", clonedData.QXJMQ); |
|
|
|
|
|
|
|
|
if (emotionDecodRef.value && chartVisibility.value.emotionDecod) { |
|
|
|
|
|
console.log('开始渲染情绪解码器图表'); |
|
|
|
|
|
console.log('emotionDecodRef方法:', typeof emotionDecodRef.value.initQXNLZHEcharts); |
|
|
|
|
|
if (typeof emotionDecodRef.value.initQXNLZHEcharts === 'function') { |
|
|
|
|
|
try { |
|
|
emotionDecodRef.value.initQXNLZHEcharts(clonedData.KLine20, clonedData.QXJMQ); |
|
|
emotionDecodRef.value.initQXNLZHEcharts(clonedData.KLine20, clonedData.QXJMQ); |
|
|
console.log("情绪解码器图表已渲染"); |
|
|
|
|
|
|
|
|
console.log('情绪解码器图表渲染成功'); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('情绪解码器图表渲染失败:', error); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
console.error('emotionDecodRef.initQXNLZHEcharts 方法不存在'); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
console.log('情绪解码器图表未渲染,ref存在:', !!emotionDecodRef.value, '数据存在:', chartVisibility.value.emotionDecod); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 渲染情绪探底雷达图表 |
|
|
// 渲染情绪探底雷达图表 |
|
|
if (emotionalBottomRadarRef.value && clonedData.QXTDLD) { |
|
|
|
|
|
console.log("开始渲染情绪探底雷达图表"); |
|
|
|
|
|
console.log("探底雷达数据", clonedData.QXTDLD); |
|
|
|
|
|
|
|
|
if (emotionalBottomRadarRef.value && chartVisibility.value.emotionalBottomRadar) { |
|
|
|
|
|
console.log('开始渲染情绪探底雷达图表'); |
|
|
|
|
|
console.log('emotionalBottomRadarRef方法:', typeof emotionalBottomRadarRef.value.initEmotionalBottomRadar); |
|
|
|
|
|
if (typeof emotionalBottomRadarRef.value.initEmotionalBottomRadar === 'function') { |
|
|
|
|
|
try { |
|
|
emotionalBottomRadarRef.value.initEmotionalBottomRadar( |
|
|
emotionalBottomRadarRef.value.initEmotionalBottomRadar( |
|
|
clonedData.KLine20, |
|
|
clonedData.KLine20, |
|
|
clonedData.QXTDLD |
|
|
clonedData.QXTDLD |
|
|
); |
|
|
); |
|
|
console.log("情绪探底雷达图表已渲染"); |
|
|
|
|
|
|
|
|
console.log('情绪探底雷达图表渲染成功'); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('情绪探底雷达图表渲染失败:', error); |
|
|
} |
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
console.error('emotionalBottomRadarRef.initEmotionalBottomRadar 方法不存在'); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
console.log('情绪探底雷达图表未渲染,ref存在:', !!emotionalBottomRadarRef.value, '数据存在:', chartVisibility.value.emotionalBottomRadar); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 渲染情绪能量转化器图表 |
|
|
// 渲染情绪能量转化器图表 |
|
|
if (emoEnergyConverterRef.value && clonedData.QXNLZHQ) { |
|
|
|
|
|
console.log("开始渲染情绪能量转化器图表"); |
|
|
|
|
|
console.log("KLine20:", clonedData.KLine20); |
|
|
|
|
|
console.log("QXNLZHQ:", clonedData.QXNLZHQ); |
|
|
|
|
|
|
|
|
if (emoEnergyConverterRef.value && chartVisibility.value.emoEnergyConverter) { |
|
|
|
|
|
console.log('开始渲染情绪能量转化器图表'); |
|
|
|
|
|
console.log('emoEnergyConverterRef方法:', typeof emoEnergyConverterRef.value.initQXNLZHEcharts); |
|
|
|
|
|
if (typeof emoEnergyConverterRef.value.initQXNLZHEcharts === 'function') { |
|
|
|
|
|
try { |
|
|
emoEnergyConverterRef.value.initQXNLZHEcharts(clonedData.KLine20, clonedData.QXNLZHQ); |
|
|
emoEnergyConverterRef.value.initQXNLZHEcharts(clonedData.KLine20, clonedData.QXNLZHQ); |
|
|
console.log("情绪能量转化器图表已渲染"); |
|
|
|
|
|
|
|
|
console.log('情绪能量转化器图表渲染成功'); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('情绪能量转化器图表渲染失败:', error); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
console.error('emoEnergyConverterRef.initQXNLZHEcharts 方法不存在'); |
|
|
} |
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
console.log('情绪能量转化器图表未渲染,ref存在:', !!emoEnergyConverterRef.value, '数据存在:', chartVisibility.value.emoEnergyConverter); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
console.log('图表渲染完成'); |
|
|
} catch (error) { |
|
|
} catch (error) { |
|
|
console.error('图表渲染过程中发生错误:', error); |
|
|
|
|
|
|
|
|
console.error('图表渲染错误:', error); |
|
|
const aiMessage = reactive({ sender: 'ai', text: '图表渲染失败,请重试' }); |
|
|
const aiMessage = reactive({ sender: 'ai', text: '图表渲染失败,请重试' }); |
|
|
messages.value.push(aiMessage); |
|
|
messages.value.push(aiMessage); |
|
|
} |
|
|
} |
|
|
}, 100); // 100ms延迟确保DOM稳定 |
|
|
|
|
|
|
|
|
}, 500); // 增加延迟到500ms确保DOM和组件完全稳定 |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1515,10 +1622,10 @@ defineExpose({ |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<style scoped> |
|
|
<style scoped> |
|
|
.disclaimer-item { |
|
|
|
|
|
p { |
|
|
|
|
|
|
|
|
.disclaimer-item p { |
|
|
color: #ffffff !important; |
|
|
color: #ffffff !important; |
|
|
} |
|
|
|
|
|
|
|
|
font-size: 20px; |
|
|
|
|
|
font-weight: bold; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.container { |
|
|
.container { |
|
@ -1700,8 +1807,6 @@ defineExpose({ |
|
|
padding-left: 15px; |
|
|
padding-left: 15px; |
|
|
position: relative; |
|
|
position: relative; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:last-child { |
|
|
&:last-child { |
|
|
margin-bottom: 0; |
|
|
margin-bottom: 0; |
|
|
} |
|
|
} |
|
@ -2002,6 +2107,7 @@ defineExpose({ |
|
|
transition: all 0.3s ease; |
|
|
transition: all 0.3s ease; |
|
|
/* 添加平滑过渡效果 */ |
|
|
/* 添加平滑过渡效果 */ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.class04 { |
|
|
.class04 { |
|
|
background-image: url('@/assets/img/AiEmotion/bk00000.png'); |
|
|
background-image: url('@/assets/img/AiEmotion/bk00000.png'); |
|
|
/* 使用导入的背景图片 */ |
|
|
/* 使用导入的背景图片 */ |
|
@ -2058,7 +2164,7 @@ defineExpose({ |
|
|
/* 确保不超出父容器 */ |
|
|
/* 确保不超出父容器 */ |
|
|
height: auto; |
|
|
height: auto; |
|
|
/* 高度根据内容动态变化 */ |
|
|
/* 高度根据内容动态变化 */ |
|
|
min-height: 55rem; |
|
|
|
|
|
|
|
|
/* min-height: 55rem; */ |
|
|
/* 设置最小高度,确保图片显示 */ |
|
|
/* 设置最小高度,确保图片显示 */ |
|
|
margin: 0 auto; |
|
|
margin: 0 auto; |
|
|
box-sizing: border-box; |
|
|
box-sizing: border-box; |
|
@ -2245,9 +2351,9 @@ defineExpose({ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* 调整图表容器高度 */ |
|
|
/* 调整图表容器高度 */ |
|
|
.class00 { |
|
|
|
|
|
|
|
|
/* .class00 { |
|
|
min-height: 45rem; |
|
|
min-height: 45rem; |
|
|
} |
|
|
|
|
|
|
|
|
} */ |
|
|
|
|
|
|
|
|
.class03 { |
|
|
.class03 { |
|
|
min-height: 60rem; |
|
|
min-height: 60rem; |
|
@ -2274,9 +2380,9 @@ defineExpose({ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* 调整图表容器高度 */ |
|
|
/* 调整图表容器高度 */ |
|
|
.class00 { |
|
|
|
|
|
|
|
|
/* .class00 { |
|
|
min-height: 40rem; |
|
|
min-height: 40rem; |
|
|
} |
|
|
|
|
|
|
|
|
} */ |
|
|
|
|
|
|
|
|
.class03 { |
|
|
.class03 { |
|
|
min-height: 55rem; |
|
|
min-height: 55rem; |
|
@ -2440,9 +2546,9 @@ defineExpose({ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* 调整其他图表容器高度 */ |
|
|
/* 调整其他图表容器高度 */ |
|
|
.class00 { |
|
|
|
|
|
|
|
|
/* .class00 { |
|
|
min-height: 35rem; |
|
|
min-height: 35rem; |
|
|
} |
|
|
|
|
|
|
|
|
} */ |
|
|
|
|
|
|
|
|
.class03 { |
|
|
.class03 { |
|
|
min-height: 45rem; |
|
|
min-height: 45rem; |
|
@ -2576,8 +2682,9 @@ defineExpose({ |
|
|
transition: all 0.3s ease; |
|
|
transition: all 0.3s ease; |
|
|
position: relative; |
|
|
position: relative; |
|
|
overflow: hidden; |
|
|
overflow: hidden; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
&::before { |
|
|
|
|
|
|
|
|
.conclusion-item::before { |
|
|
content: ''; |
|
|
content: ''; |
|
|
position: absolute; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
top: 0; |
|
@ -2588,21 +2695,20 @@ defineExpose({ |
|
|
opacity: 0.8; |
|
|
opacity: 0.8; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:last-child { |
|
|
|
|
|
|
|
|
.conclusion-item:last-child { |
|
|
margin-bottom: 0; |
|
|
margin-bottom: 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.conclusion-title { |
|
|
|
|
|
|
|
|
.conclusion-item .conclusion-title { |
|
|
color: #FFD700; |
|
|
color: #FFD700; |
|
|
font-size: 22px; |
|
|
font-size: 22px; |
|
|
font-weight: bold; |
|
|
font-weight: bold; |
|
|
margin: 0 0 15px 0; |
|
|
margin: 0 0 15px 0; |
|
|
text-align: center; |
|
|
text-align: center; |
|
|
letter-spacing: 2px; |
|
|
letter-spacing: 2px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
&::after { |
|
|
|
|
|
|
|
|
.conclusion-item .conclusion-title::after { |
|
|
content: ''; |
|
|
content: ''; |
|
|
position: absolute; |
|
|
position: absolute; |
|
|
bottom: -5px; |
|
|
bottom: -5px; |
|
@ -2612,9 +2718,8 @@ defineExpose({ |
|
|
height: 2px; |
|
|
height: 2px; |
|
|
background: linear-gradient(90deg, transparent, #00d4ff, transparent); |
|
|
background: linear-gradient(90deg, transparent, #00d4ff, transparent); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.conclusion-text { |
|
|
|
|
|
|
|
|
.conclusion-item .conclusion-text { |
|
|
color: #ffffff; |
|
|
color: #ffffff; |
|
|
font-size: 20px; |
|
|
font-size: 20px; |
|
|
line-height: 1.8; |
|
|
line-height: 1.8; |
|
@ -2623,8 +2728,9 @@ defineExpose({ |
|
|
word-wrap: break-word; |
|
|
word-wrap: break-word; |
|
|
padding-left: 15px; |
|
|
padding-left: 15px; |
|
|
position: relative; |
|
|
position: relative; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
&::before { |
|
|
|
|
|
|
|
|
.conclusion-item .conclusion-text::before { |
|
|
content: '▶'; |
|
|
content: '▶'; |
|
|
position: absolute; |
|
|
position: absolute; |
|
|
left: 0; |
|
|
left: 0; |
|
@ -2634,12 +2740,10 @@ defineExpose({ |
|
|
opacity: 0.7; |
|
|
opacity: 0.7; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
&:last-child { |
|
|
|
|
|
|
|
|
.conclusion-item .conclusion-text:last-child { |
|
|
margin-bottom: 0; |
|
|
margin-bottom: 0; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.conclusion-placeholder { |
|
|
.conclusion-placeholder { |
|
|
padding: 30px; |
|
|
padding: 30px; |
|
@ -2647,31 +2751,29 @@ defineExpose({ |
|
|
border-radius: 12px; |
|
|
border-radius: 12px; |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border: 1px dashed rgba(153, 153, 153, 0.3); |
|
|
border: 1px dashed rgba(153, 153, 153, 0.3); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
p { |
|
|
|
|
|
|
|
|
.conclusion-placeholder p { |
|
|
color: #999999; |
|
|
color: #999999; |
|
|
font-size: 16px; |
|
|
font-size: 16px; |
|
|
margin: 0; |
|
|
margin: 0; |
|
|
font-style: italic; |
|
|
font-style: italic; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.disclaimer-item { |
|
|
.disclaimer-item { |
|
|
margin-top: 30px; |
|
|
|
|
|
|
|
|
/* margin-top: 30px; */ |
|
|
padding: 20px; |
|
|
padding: 20px; |
|
|
border-top: 1px solid rgba(153, 153, 153, 0.2); |
|
|
border-top: 1px solid rgba(153, 153, 153, 0.2); |
|
|
text-align: center; |
|
|
text-align: center; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
p.disclaimer-text { |
|
|
|
|
|
|
|
|
.disclaimer-item p { |
|
|
color: #ffffff !important; |
|
|
color: #ffffff !important; |
|
|
font-size: 14px; |
|
|
|
|
|
|
|
|
font-size: 16px; |
|
|
margin: 0; |
|
|
margin: 0; |
|
|
font-style: italic; |
|
|
|
|
|
opacity: 0.8; |
|
|
|
|
|
letter-spacing: 1px; |
|
|
letter-spacing: 1px; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.class05 { |
|
|
.class05 { |
|
|
background-size: 100% 100%; |
|
|
background-size: 100% 100%; |
|
@ -2817,9 +2919,9 @@ defineExpose({ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* 调整图表容器高度适配超小屏幕 */ |
|
|
/* 调整图表容器高度适配超小屏幕 */ |
|
|
.class00 { |
|
|
|
|
|
|
|
|
/* .class00 { |
|
|
min-height: 25rem; |
|
|
min-height: 25rem; |
|
|
} |
|
|
|
|
|
|
|
|
} */ |
|
|
|
|
|
|
|
|
.class03 { |
|
|
.class03 { |
|
|
min-height: 35rem; |
|
|
min-height: 35rem; |
|
|