情绪能量转化器
@@ -277,6 +277,14 @@ const moduleVisibility = ref({
four: false,
disclaimer: false
});
+
+// 图表组件显示状态
+const chartVisibility = ref({
+ marketTemperature: false,
+ emotionDecod: false,
+ emotionalBottomRadar: false,
+ emoEnergyConverter: false
+});
const typewriterTimers = ref([]);
// 记录每个股票是否已经显示过打字机效果
const stockTypewriterShown = ref(new Map());
@@ -294,7 +302,7 @@ const displayDate = computed(() => {
if (!currentStock.value?.apiData) return "";
const lastData = currentStock.value.apiData.GSWDJ?.at(-1);
if (!lastData || !lastData[0]) return "";
-
+
const dateStr = lastData[0];
// 假设原格式为 YYYY-MM-DD 或 YYYY/MM/DD
const dateMatch = dateStr.match(/(\d{4})[\-\/](\d{1,2})[\-\/](\d{1,2})/);
@@ -303,7 +311,7 @@ const displayDate = computed(() => {
// 转换为 DD/MM/YYYY 格式
return `更新时间:${day.padStart(2, '0')}/${month.padStart(2, '0')}/${year}`;
}
-
+
// 如果不匹配预期格式,返回原始值
return dateStr;
});
@@ -372,6 +380,13 @@ watch(() => emotionStore.stockList, (newStockList) => {
four: false,
disclaimer: false
};
+ // 隐藏所有图表组件
+ chartVisibility.value = {
+ marketTemperature: false,
+ emotionDecod: false,
+ emotionalBottomRadar: false,
+ emoEnergyConverter: false
+ };
console.log('股票列表已清空,页面数据已隐藏');
}
}, { deep: true });
@@ -583,6 +598,13 @@ watch(currentStock, (newStock) => {
}
} else {
console.log('股票数据不存在或API数据未加载');
+ // 隐藏所有图表组件
+ chartVisibility.value = {
+ marketTemperature: false,
+ emotionDecod: false,
+ emotionalBottomRadar: false,
+ emoEnergyConverter: false
+ };
}
}, { immediate: true });
@@ -625,7 +647,7 @@ watch(parsedConclusion, (newConclusion) => {
}, { immediate: true });
// 打字机效果函数
-function startTypewriterEffect(conclusion) {
+function startTypewriterEffect(conclusion, onComplete) {
console.log('开始打字机效果,结论数据:', conclusion);
// 详细调试各个字段
@@ -758,10 +780,14 @@ function startTypewriterEffect(conclusion) {
for (let i = 0; i <= disclaimerText.length; i++) {
const timer = setTimeout(() => {
displayedTexts.value.disclaimer = disclaimerText.substring(0, i);
- // 在打字机效果的最后一个字符显示完成后,滚动到底部
+ // 在打字机效果的最后一个字符显示完成后,滚动到底部并调用完成回调
if (i === disclaimerText.length) {
setTimeout(() => {
scrollToBottom();
+ // 调用完成回调,重新启用输入框
+ if (onComplete && typeof onComplete === 'function') {
+ onComplete();
+ }
}, 100);
}
}, totalDelay + i * typeSpeed);
@@ -877,7 +903,7 @@ function startImageRotation() {
// 发送消息方法
-async function handleSendMessage(input) {
+async function handleSendMessage(input, onComplete) {
console.log("发送内容:", input);
// 标记为用户主动搜索
isUserInitiated.value = true;
@@ -885,6 +911,10 @@ async function handleSendMessage(input) {
// 检查用户输入内容是否为空
if (!input || !input.trim()) {
ElMessage.warning("输入内容不能为空");
+ // 调用完成回调,重新启用输入框
+ if (onComplete && typeof onComplete === 'function') {
+ onComplete();
+ }
return;
}
@@ -903,6 +933,10 @@ async function handleSendMessage(input) {
// 停止图片旋转,恢复历史数据
isRotating.value = false;
messages.value = [...previousMessages, ...messages.value];
+ // 调用完成回调,重新启用输入框
+ if (onComplete && typeof onComplete === 'function') {
+ onComplete();
+ }
return;
}
@@ -920,6 +954,10 @@ async function handleSendMessage(input) {
// 停止图片旋转,恢复历史数据
isRotating.value = false;
messages.value = [...previousMessages, ...messages.value];
+ // 调用完成回调,重新启用输入框
+ if (onComplete && typeof onComplete === 'function') {
+ onComplete();
+ }
return;
}
@@ -947,7 +985,6 @@ async function handleSendMessage(input) {
const result = await getReplyAPI(params);
const response = await result.json();
const parsedData = JSON.parse(response.data);
- console.log("第一个接口解析后的数据:", parsedData);
// 检查用户输入是否合法
if (!parsedData || !parsedData.market || !parsedData.code) {
@@ -956,6 +993,10 @@ async function handleSendMessage(input) {
messages.value.push(aiMessage);
isRotating.value = false;
messages.value = [...previousMessages, ...messages.value];
+ // 调用完成回调,重新启用输入框
+ if (onComplete && typeof onComplete === 'function') {
+ onComplete();
+ }
return;
}
@@ -963,7 +1004,6 @@ async function handleSendMessage(input) {
// 设置加载状态,隐藏图表页面
isLoading.value = true;
- console.log("工作流接口返回股票信息:", parsedData);
isPageLoaded.value = false;
// 调用第二个工作流接口
@@ -985,7 +1025,6 @@ async function handleSendMessage(input) {
// 处理结论接口返回的数据
const conclusionResponse = await conclusionResult.json();
- console.log("第二个工作流接口返回数据:", conclusionResponse);
// 检查所有数据是否都加载成功
if (conclusionResponse && conclusionResponse.data && fetchDataResult) {
@@ -1006,26 +1045,28 @@ async function handleSendMessage(input) {
console.error('更新用户次数失败:', error);
}
- console.log('所有数据加载完成,开始渲染页面');
// 确保页面状态更新后触发图表渲染和音频文本
nextTick(() => {
if (currentStock.value && currentStock.value.apiData) {
renderCharts(currentStock.value.apiData);
- console.log('数据加载完成后开始渲染图表');
// 只有在用户主动搜索时才自动触发音频和文本
if (isUserInitiated.value && 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);
+ startTypewriterEffect(parsedConclusion.value, onComplete);
if (!stockAudioPlayed.value.has(stockCode)) {
stockAudioPlayed.value.set(stockCode, true);
playAudio(audioUrl.value);
}
stockTypewriterShown.value.set(stockCode, true);
+ } else {
+ // 如果不需要打字机效果,直接调用完成回调
+ if (onComplete && typeof onComplete === 'function') {
+ onComplete();
+ }
}
}
@@ -1040,6 +1081,10 @@ async function handleSendMessage(input) {
messages.value.push(aiMessage);
isRotating.value = false;
messages.value = [...previousMessages, ...messages.value];
+ // 调用完成回调,重新启用输入框
+ if (onComplete && typeof onComplete === 'function') {
+ onComplete();
+ }
return;
}
} catch (error) {
@@ -1048,6 +1093,10 @@ async function handleSendMessage(input) {
// 请求失败时停止图片旋转,恢复历史数据
isRotating.value = false;
messages.value = [...previousMessages, ...messages.value];
+ // 调用完成回调,重新启用输入框
+ if (onComplete && typeof onComplete === 'function') {
+ onComplete();
+ }
return;
} finally {
// 停止图片旋转(只有在设置了旋转状态时才需要停止)
@@ -1082,11 +1131,8 @@ async function fetchData(code, market, stockName, queryText) {
);
const stockDataResponse = stockDataResult.data; // 获取返回所有的数据
- console.log('图表数据接口返回数据:', stockDataResponse.data);
if (stockDataResponse.code === 200 && stockDataResponse.data) {
- console.log(stockDataResponse.code)
-
// 创建股票数据对象
const stockData = {
queryText: queryText,
@@ -1108,7 +1154,6 @@ async function fetchData(code, market, stockName, queryText) {
return false; // 返回失败标识
}
} catch (error) {
- console.error('fetchData error:', error);
const aiMessage = reactive({ sender: 'ai', text: '图表数据请求失败,请检查网络连接' });
messages.value.push(aiMessage);
return false; // 返回失败标识
@@ -1117,52 +1162,114 @@ async function fetchData(code, market, stockName, queryText) {
// 渲染组件图表的方法
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(() => {
- // 添加小延迟确保DOM完全更新
+ // 增加延迟确保DOM完全更新和组件完全挂载
setTimeout(() => {
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);
- marketTemperatureRef.value.initChart(clonedData.GSWDJ, clonedData.KLine20, clonedData.WDRL);
- console.log("股市温度计图表已渲染");
+ 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);
+ 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);
- emotionDecodRef.value.initQXNLZHEcharts(clonedData.KLine20, clonedData.QXJMQ);
- console.log("情绪解码器图表已渲染");
+ 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);
+ 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);
- emotionalBottomRadarRef.value.initEmotionalBottomRadar(
- clonedData.KLine20,
- clonedData.QXTDLD
- );
- console.log("情绪探底雷达图表已渲染");
+ 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(
+ clonedData.KLine20,
+ clonedData.QXTDLD
+ );
+ 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);
- emoEnergyConverterRef.value.initQXNLZHEcharts(clonedData.KLine20, clonedData.QXNLZHQ);
- console.log("情绪能量转化器图表已渲染");
+ 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);
+ 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) {
- console.error('图表渲染过程中发生错误:', error);
+ console.error('图表渲染错误:', error);
const aiMessage = reactive({ sender: 'ai', text: '图表渲染失败,请重试' });
messages.value.push(aiMessage);
}
- }, 100); // 100ms延迟确保DOM稳定
+ }, 500); // 增加延迟到500ms确保DOM和组件完全稳定
});
}
@@ -1172,7 +1279,7 @@ const scrollToBottom = async () => {
console.log('用户正在手动滚动,跳过自动滚动');
return;
}
-
+
const container = userInputDisplayRef.value;
if (!container) return;
await nextTick();
@@ -1185,12 +1292,12 @@ const scrollToBottom = async () => {
// 处理用户滚动事件
const handleUserScroll = () => {
isUserScrolling.value = true;
-
+
// 清除之前的定时器
if (scrollTimeout.value) {
clearTimeout(scrollTimeout.value);
}
-
+
// 设置定时器,2秒后重新允许自动滚动
scrollTimeout.value = setTimeout(() => {
isUserScrolling.value = false;
@@ -1408,7 +1515,7 @@ onMounted(async () => {
// 添加新的监听器
window.addEventListener('resize', globalResizeHandler);
window.aiEmotionGlobalResizeHandler = globalResizeHandler;
-
+
// 添加滚动事件监听器
const container = userInputDisplayRef.value;
if (container) {
@@ -1488,7 +1595,7 @@ onUnmounted(() => {
window.removeEventListener('resize', window.aiEmotionGlobalResizeHandler);
window.aiEmotionGlobalResizeHandler = null;
}
-
+
// 清理滚动事件监听器
const container = userInputDisplayRef.value;
if (container) {
@@ -1496,7 +1603,7 @@ onUnmounted(() => {
container.removeEventListener('touchmove', handleTouchMove);
container.removeEventListener('scroll', handleUserScroll);
}
-
+
// 清理滚动定时器
if (scrollTimeout.value) {
clearTimeout(scrollTimeout.value);
@@ -1515,10 +1622,10 @@ defineExpose({