diff --git a/src/views/AiEmotion.vue b/src/views/AiEmotion.vue index e78dae7..5fce74d 100644 --- a/src/views/AiEmotion.vue +++ b/src/views/AiEmotion.vue @@ -46,18 +46,17 @@
AI情绪大模型正在努力为您加载,请稍候...
- - - -
+ + +
- {{ stockName }}{{ stockName ? '量子四维矩阵图' : '' }} + {{ stock.stockInfo.name }}{{ stock.stockInfo.name ? '量子四维矩阵图' : '' }}
-
{{ displayDate }}
+
{{ getDisplayDate(stock) }}
情绪监控图标 @@ -70,11 +69,11 @@ 股市温度计
-
股票温度:{{ data2 ?? "NA" }}
-
市场温度:{{ data1 }}
+
股票温度:{{ getStockData2(stock) ?? "NA" }}
+
市场温度:{{ getStockData1(stock) }}
- +
@@ -87,7 +86,7 @@ 情绪解码器
- +
@@ -100,7 +99,7 @@ 情绪探底雷达
- +
@@ -113,7 +112,7 @@ 情绪能量转化器
- +
@@ -152,27 +151,27 @@
场景应用标题
-
-
-

{{ displayedTitles.one }}

-

{{ displayedTexts.one1 }}

-

{{ displayedTexts.one2 }}

+
+
+

L1: 情绪监控

+

{{ getStockConclusion(stock).one1 }}

+

{{ getStockConclusion(stock).one2 }}

-
-

{{ displayedTitles.two }}

-

{{ displayedTexts.two }}

+
+

L2: 情绪解码

+

{{ getStockConclusion(stock).two }}

-
-

{{ displayedTitles.three }}

-

{{ displayedTexts.three }}

+
+

L3: 情绪推演

+

{{ getStockConclusion(stock).three }}

-
-

{{ displayedTitles.four }}

-

{{ displayedTexts.four }}

+
+

L4: 情绪套利

+

{{ getStockConclusion(stock).four }}

-
-

{{ displayedTexts.disclaimer }}

+
+

该内容由AI生成,请注意甄别

@@ -271,11 +270,11 @@ function processRefuseMessage(refuseData) { } } -// 组件引用 -const marketTemperatureRef = ref(null); // 引用市场温度计组件 -const emoEnergyConverterRef = ref(null) -const emotionDecodRef = ref(null) -const emotionalBottomRadarRef = ref(null) +// 组件引用 - 修改为数组形式支持多个股票 +const marketTemperatureRef = ref([]); // 引用市场温度计组件数组 +const emoEnergyConverterRef = ref([]) +const emotionDecodRef = ref([]) +const emotionalBottomRadarRef = ref([]) const userInputDisplayRef = ref(null);//消息区域的引用 // 响应式数据 @@ -290,10 +289,53 @@ const loadConversationsFromStore = () => { })); }; +// 记录已经添加到对话中的股票,避免重复添加 +const addedStocks = ref(new Set()); + +// 从stockList生成对话历史 +const loadConversationsFromStockList = () => { + // 检查是否有新的股票需要添加到对话中 + emotionStore.stockList.forEach(stock => { + const stockKey = `${stock.stockInfo.code}_${stock.timestamp}`; + + // 如果这个股票还没有添加到对话中 + if (!addedStocks.value.has(stockKey)) { + // 检查messages中是否已经存在相同的用户消息 + const existingMessage = messages.value.find(msg => + msg.sender === 'user' && msg.text === stock.queryText + ); + + // 只有当messages中不存在相同消息时才添加 + if (!existingMessage) { + // 只添加用户输入消息,不添加AI回复 + const userMessage = { + sender: 'user', + text: stock.queryText + }; + messages.value.push(userMessage); + + // 只将用户消息添加到emotion store中(如果store中也不存在) + const storeConversations = emotionStore.getConversations(); + const existingInStore = storeConversations.find(conv => + conv.sender === 'user' && conv.text === stock.queryText + ); + if (!existingInStore) { + emotionStore.addConversation(userMessage); + } + } + + // 将这个股票标记为已添加 + addedStocks.value.add(stockKey); + } + }); +}; + // 清空对话记录 const clearConversations = () => { messages.value = []; emotionStore.clearConversations(); + // 清空已添加股票的记录 + addedStocks.value.clear(); }; // 暴露清空对话记录的方法给父组件 @@ -346,10 +388,10 @@ const moduleVisibility = ref({ // 图表组件显示状态 const chartVisibility = ref({ - marketTemperature: false, - emotionDecod: false, - emotionalBottomRadar: false, - emoEnergyConverter: false + marketTemperature: true, + emotionDecod: true, + emotionalBottomRadar: true, + emoEnergyConverter: true }); const typewriterTimers = ref([]); // 记录每个股票是否已经显示过打字机效果 @@ -410,6 +452,50 @@ const parsedConclusion = computed(() => { } }); +// 辅助函数:获取股票的显示日期 +const getDisplayDate = (stock) => { + if (!stock?.apiData) return ""; + const lastData = stock.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})/); + if (dateMatch) { + const [, year, month, day] = dateMatch; + // 转换为 DD/MM/YYYY 格式 + return `更新时间:${day.padStart(2, '0')}/${month.padStart(2, '0')}/${year}`; + } + + // 如果不匹配预期格式,返回原始值 + return dateStr; +}; + +// 辅助函数:获取股票的市场温度数据 +const getStockData1 = (stock) => { + if (!stock?.apiData) return null; + const lastData = stock.apiData.GSWDJ?.at(-1); + return lastData ? Math.round(lastData[1]) : null; +}; + +// 辅助函数:获取股票的股票温度数据 +const getStockData2 = (stock) => { + if (!stock?.apiData) return null; + const lastData = stock.apiData.GSWDJ?.at(-1); + return lastData ? Math.round(lastData[2]) : null; +}; + +// 辅助函数:获取股票的结论数据 +const getStockConclusion = (stock) => { + if (!stock?.conclusionData) return null; + try { + return JSON.parse(stock.conclusionData); + } catch (error) { + console.error('解析股票结论数据失败:', error); + return null; + } +}; + // 监听股票列表变化,当列表为空时隐藏页面数据 @@ -429,6 +515,8 @@ watch(() => emotionStore.stockList, (newStockList) => { hasTriggeredTypewriter.value = false; stockTypewriterShown.value.clear(); stockAudioPlayed.value.clear(); + // 清理已添加股票的记录 + addedStocks.value.clear(); // 清理显示的文本和标题 displayedTexts.value = { one1: '', @@ -460,6 +548,9 @@ watch(() => emotionStore.stockList, (newStockList) => { emoEnergyConverter: false }; console.log('股票列表已清空,页面数据已隐藏'); + } else { + // 当stockList有数据时,更新对话记录 + loadConversationsFromStockList(); } }, { deep: true }); @@ -1089,11 +1180,20 @@ async function handleSendMessage(input, onComplete) { const previousMessages = [...messages.value]; // 保存历史消息 messages.value = []; // 清空历史数据 + // 添加用户消息(只添加一次) + const userMessage = reactive({ sender: 'user', text: input }); + messages.value.push(userMessage); + + // 将用户消息添加到emotion store中 + emotionStore.addConversation({ + sender: 'user', + text: input, + timestamp: new Date().toISOString() + }); + // 检查用户剩余次数 await chatStore.getUserCount(); // 获取最新的用户次数 if (chatStore.UserCount <= 0) { - const userMessage = reactive({ sender: 'user', text: input }); - messages.value.push(userMessage); const aiMessage = reactive({ sender: 'ai', text: '您的剩余次数为0,无法使用情绪大模型,请联系客服或购买服务包。' }); messages.value.push(aiMessage); @@ -1115,39 +1215,6 @@ async function handleSendMessage(input, onComplete) { return; } - // 检查用户是否有使用次数(检查是否有任何权限) - // const hasPermission = userStore.brainPerssion || userStore.swordPerssion || - // userStore.pricePerssion || userStore.timePerssion || - // userStore.aibullPerssion || userStore.aiGnbullPerssion || - // userStore.airadarPerssion; - - // if (!hasPermission) { - // const userMessage = reactive({ sender: 'user', text: input }); - // messages.value.push(userMessage); - // const aiMessage = reactive({ sender: 'ai', text: '您当前没有可用权限,请联系客服或购买服务包。' }); - // messages.value.push(aiMessage); - // // 停止图片旋转,恢复历史数据 - // isRotating.value = false; - // messages.value = [...previousMessages, ...messages.value]; - // // 调用完成回调,重新启用输入框 - // if (onComplete && typeof onComplete === 'function') { - // onComplete(); - // // 清除保存的回调函数 - // currentOnCompleteCallback.value = null; - // } - // return; - // } - - const userMessage = reactive({ sender: 'user', text: input }); - messages.value.push(userMessage); - - // 将用户消息添加到emotion store中 - emotionStore.addConversation({ - sender: 'user', - text: input, - timestamp: new Date().toISOString() - }); - // 开始思考过程(不带股票名称) const thinkingMessageRef = await showThinkingProcess(); @@ -1602,36 +1669,36 @@ function hasValidData(obj) { return false; } -// 依次渲染图表的方法 -async function renderChartsSequentially(clonedData) { - console.log('开始依次渲染图表'); +// 依次渲染图表的方法 - 支持多个股票 +async function renderChartsSequentially(clonedData, stockIndex = 0) { + console.log(`开始渲染第${stockIndex}个股票的图表`); // 定义图表渲染顺序和配置 const chartConfigs = [ { name: '股市温度计', - ref: marketTemperatureRef, + ref: marketTemperatureRef.value[stockIndex], visibility: chartVisibility.value.marketTemperature, method: 'initChart', params: [clonedData.GSWDJ, clonedData.KLine20, clonedData.WDRL] }, { name: '情绪解码器', - ref: emotionDecodRef, + ref: emotionDecodRef.value[stockIndex], visibility: chartVisibility.value.emotionDecod, method: 'initQXNLZHEcharts', params: [clonedData.KLine20, clonedData.QXJMQ] }, { name: '情绪探底雷达', - ref: emotionalBottomRadarRef, + ref: emotionalBottomRadarRef.value[stockIndex], visibility: chartVisibility.value.emotionalBottomRadar, method: 'initEmotionalBottomRadar', params: [clonedData.KLine20, clonedData.QXTDLD] }, { name: '情绪能量转化器', - ref: emoEnergyConverterRef, + ref: emoEnergyConverterRef.value[stockIndex], visibility: chartVisibility.value.emoEnergyConverter, method: 'initQXNLZHEcharts', params: [clonedData.KLine20, clonedData.QXNLZHQ] @@ -1640,29 +1707,29 @@ async function renderChartsSequentially(clonedData) { // 依次渲染每个图表 for (const config of chartConfigs) { - if (config.ref.value && config.visibility) { - console.log(`开始渲染${config.name}图表`); - console.log(`${config.name}Ref方法:`, typeof config.ref.value[config.method]); + if (config.ref && config.visibility) { + console.log(`开始渲染第${stockIndex}个股票的${config.name}图表`); + console.log(`${config.name}Ref方法:`, typeof config.ref[config.method]); - if (typeof config.ref.value[config.method] === 'function') { + if (typeof config.ref[config.method] === 'function') { try { - config.ref.value[config.method](...config.params); - console.log(`${config.name}图表渲染成功`); + config.ref[config.method](...config.params); + console.log(`第${stockIndex}个股票的${config.name}图表渲染成功`); // 每个图表渲染完成后等待一段时间再渲染下一个 await new Promise(resolve => setTimeout(resolve, 800)); } catch (error) { - console.error(`${config.name}图表渲染失败:`, error); + console.error(`第${stockIndex}个股票的${config.name}图表渲染失败:`, error); } } else { - console.error(`${config.name}Ref.${config.method} 方法不存在`); + console.error(`第${stockIndex}个股票的${config.name}Ref.${config.method} 方法不存在`); } } else { - console.log(`${config.name}图表未渲染,ref存在:`, !!config.ref.value, '数据存在:', config.visibility); + console.log(`第${stockIndex}个股票的${config.name}图表未渲染,ref存在:`, !!config.ref, '数据存在:', config.visibility); } } - console.log('所有图表依次渲染完成'); + console.log(`第${stockIndex}个股票的所有图表依次渲染完成`); } // 渲染组件图表的方法 @@ -1746,8 +1813,12 @@ function renderCharts(data) { } }, 1000); - // 开始依次渲染图表 - renderChartsSequentially(clonedData); + // 开始依次渲染图表 - 为每个股票渲染 + emotionStore.stockList.forEach((stock, index) => { + if (stock.apiData) { + renderChartsSequentially(stock.apiData, index); + } + }); console.log('图表渲染完成'); } catch (error) { @@ -1798,20 +1869,29 @@ function isDataLoaded() { return false; } - // 检查图表组件是否已渲染 - const requiredRefs = [ - marketTemperatureRef.value, - emotionDecodRef.value, - emotionalBottomRadarRef.value, - emoEnergyConverterRef.value - ]; - - const allRefsLoaded = requiredRefs.every(ref => ref !== null); - if (!allRefsLoaded) { - console.log('图表组件尚未完全加载'); + // 检查图表组件是否已渲染 - 检查所有股票的组件 + const stockCount = emotionStore.stockList.length; + if (stockCount === 0) { + console.log('没有股票数据'); return false; } + // 检查每个股票的图表组件是否都已加载 + for (let i = 0; i < stockCount; i++) { + const requiredRefs = [ + marketTemperatureRef.value[i], + emotionDecodRef.value[i], + emotionalBottomRadarRef.value[i], + emoEnergyConverterRef.value[i] + ]; + + const allRefsLoaded = requiredRefs.every(ref => ref !== null); + if (!allRefsLoaded) { + console.log(`第${i}个股票的图表组件尚未完全加载`); + return false; + } + } + console.log('所有数据和组件已加载完成'); return true; } @@ -1954,6 +2034,8 @@ const handleContainerScroll = () => { onMounted(async () => { // 恢复对话记录 loadConversationsFromStore(); + // 从stockList加载对话记录 + loadConversationsFromStockList(); // 确保获取用户次数 // try { diff --git a/src/views/components/emoEnergyConverter.vue b/src/views/components/emoEnergyConverter.vue index 63feff8..3ea78ff 100644 --- a/src/views/components/emoEnergyConverter.vue +++ b/src/views/components/emoEnergyConverter.vue @@ -1,5 +1,5 @@