diff --git a/src/store/emotion.ts b/src/store/emotion.ts index 1e4bbaf..7cf7874 100644 --- a/src/store/emotion.ts +++ b/src/store/emotion.ts @@ -38,18 +38,41 @@ export const useEmotionStore = defineStore('emotion', { }, // 添加新股票 addStock(stockData: StockData) { + // 验证必要字段 + if (!stockData.stockInfo?.code || !stockData.stockInfo?.market || !stockData.timestamp) { + console.error('股票数据不完整,无法添加:', stockData); + return false; + } + + // 生成唯一标识 + const uniqueId = this.generateStockUniqueId(stockData); + + // 检查是否已存在相同的股票 + const existingStock = this.stockList.find(stock => { + const existingId = this.generateStockUniqueId(stock); + return existingId === uniqueId; + }); + + if (existingStock) { + console.log('股票已存在,切换到现有股票:', stockData.stockInfo.name); + // 找到现有股票的索引并切换 + const existingIndex = this.stockList.indexOf(existingStock); + this.switchStock(existingIndex); + return false; // 返回false表示没有添加新股票 + } + + // 添加唯一标识到股票数据中 + const stockWithId = { + ...stockData, + uniqueId: uniqueId + }; + // 添加新股票并设为当前激活 - this.stockList.push(stockData); + this.stockList.push(stockWithId); this.activeStockIndex = this.stockList.length - 1; - - // 同时添加到历史记录 - // this.addHistory({ - // queryText: stockData.queryText, - // stockInfo: stockData.stockInfo, - // apiData: stockData.apiData, - // conclusionData: stockData.conclusionData, - // timestamp: stockData.timestamp - // }); + + console.log('成功添加新股票:', stockData.stockInfo.name, 'ID:', uniqueId); + return true; // 返回true表示成功添加新股票 }, // 切换股票 switchStock(index: number) { @@ -141,6 +164,14 @@ export const useEmotionStore = defineStore('emotion', { }; } }, + // 生成股票唯一标识 + generateStockUniqueId(stockData: StockData): string { + if (!stockData.stockInfo?.code || !stockData.stockInfo?.market) { + throw new Error('股票代码和市场信息不能为空'); + } + // 使用 code + market + timestamp 确保唯一性 + return `${stockData.stockInfo.code}_${stockData.stockInfo.market}_${stockData.timestamp}`; + } }, }); @@ -159,15 +190,16 @@ interface HistoryItem { // 定义股票数据的类型 interface StockData { - queryText: string; // 用户输入的查询文本 + queryText: string; stockInfo: { - name: string; // 股票名称 - code: string; // 股票代码 - market: string; // 市场 + name: string; + code: string; + market: string; }; - apiData: any; // API返回的完整数据 - conclusionData?: string; // 第二个工作流接口返回的结论数据 - timestamp: string; // 数据获取时间 + apiData: any; + conclusionData?: string; + timestamp: string; + uniqueId?: string; // 添加唯一标识字段 } // 定义对话消息的类型 diff --git a/src/views/AIchat.vue b/src/views/AIchat.vue index c389ce2..d54adf8 100644 --- a/src/views/AIchat.vue +++ b/src/views/AIchat.vue @@ -747,7 +747,7 @@ const createTypingEffect = (message, content, speed) => { class: "ing", type: "ing", flag: false, - content: "工作流返回出错,请稍后重试", + content: "系统正在为您努力加载中,请稍后再试", }); chatStore.isLoading = false; chatStore.chatInput = false; @@ -881,7 +881,7 @@ const createTypingEffect = (message, content, speed) => { class: "ing", type: "ing", flag: false, - content: "工作流返回出错,请稍后重试", + content: "系统正在为您努力加载中,请稍后再试", }); chatStore.isLoading = false; chatStore.chatInput = false; @@ -915,7 +915,7 @@ const createTypingEffect = (message, content, speed) => { class: "ing", type: "ing", flag: false, - content: "工作流返回出错,请稍后重试", + content: "系统正在为您努力加载中,请稍后再试", }); chatStore.isLoading = false; chatStore.chatInput = false; @@ -1228,7 +1228,7 @@ watch( class: "ing", type: "ing", flag: false, - content: "工作流返回出错,请稍后重试", + content: "系统正在为您努力加载中,请稍后再试", }); chatStore.isLoading = false; chatStore.chatInput = false; @@ -1824,7 +1824,7 @@ watch( class: "ing", type: "ing", flag: false, - content: "工作流返回出错,请稍后重试", + content: "系统正在为您努力加载中,请稍后再试", }); chatStore.isLoading = false; chatStore.chatInput = false; @@ -1934,7 +1934,7 @@ watch( class: "ing", type: "ing", flag: false, - content: "工作流返回出错,请稍后重试", + content: "系统正在为您努力加载中,请稍后再试", }); chatStore.isLoading = false; chatStore.chatInput = false; @@ -2133,7 +2133,7 @@ watch( class: "ing", type: "ing", flag: false, - content: "工作流返回出错,请稍后重试1111", + content: "系统正在为您努力加载中,请稍后再试", }); chatStore.isLoading = false; chatStore.chatInput = false; @@ -2278,7 +2278,7 @@ watch( class: "ing", type: "ing", flag: false, - content: "工作流返回出错,请稍后重试", + content: "系统正在为您努力加载中,请稍后再试", }); chatStore.isLoading = false; chatStore.chatInput = false; diff --git a/src/views/AiEmotion.vue b/src/views/AiEmotion.vue index 7918c12..9a8dd2d 100644 --- a/src/views/AiEmotion.vue +++ b/src/views/AiEmotion.vue @@ -538,35 +538,39 @@ const loadConversationsFromStockList = () => { // 检查是否有新的股票需要添加到对话中 emotionStore.stockList.forEach((stock) => { - const stockKey = `${stock.stockInfo.code}_${stock.timestamp}`; + // 验证股票数据完整性 + if (!stock?.stockInfo?.code || !stock?.timestamp || !stock?.queryText) { + console.warn('股票数据不完整,跳过添加:', stock); + return; + } + + // 使用统一的唯一标识生成方法 + const stockKey = getStockUniqueId(stock); + if (!stockKey) { + console.warn('无法生成股票唯一标识,跳过添加:', stock); + return; + } - // 如果这个股票还没有添加到对话中 + // 多重检查避免重复添加 if (!addedStocks.value.has(stockKey)) { - // 检查messages中是否已经存在相同的用户消息 - const existingMessage = messages.value.find( + const existingInMessages = messages.value.find( (msg) => msg.sender === "user" && msg.text === stock.queryText ); + + const storeConversations = emotionStore.getConversations(); + const existingInStore = storeConversations.find( + (conv) => conv.sender === "user" && conv.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); - } - } + // if (!existingInMessages && !existingInStore) { + // const userMessage = { + // sender: "user", + // text: stock.queryText, + // }; + // messages.value.push(userMessage); + // emotionStore.addConversation(userMessage); + // } - // 将这个股票标记为已添加 addedStocks.value.add(stockKey); } }); @@ -584,6 +588,13 @@ const clearConversations = () => { const addStock = (stockData) => { console.log("AiEmotion组件接收到股票数据:", stockData); + // 验证股票数据完整性 + if (!stockData || !stockData.stockInfo || !stockData.stockInfo.code) { + console.error('addStock: 股票数据不完整', stockData); + emit('enableInput'); + return; + } + // 设置为历史记录模式,并重置用户主动搜索标志 isHistoryMode.value = true; isUserInitiated.value = false; @@ -694,6 +705,12 @@ const stockAudioStates = ref(new Map()); // 生成股票唯一标识符的辅助函数 const getStockUniqueId = (stock) => { + // 验证输入参数 + if (!stock || typeof stock !== 'object') { + console.warn('getStockUniqueId: 无效的股票对象'); + return null; + } + // 优先使用预设的uniqueId if (stock.uniqueId) { return stock.uniqueId; @@ -702,7 +719,13 @@ const getStockUniqueId = (stock) => { // 兼容旧的生成方式 const stockCode = stock.stockInfo?.code || stock.stockInfo?.symbol; const timestamp = stock.timestamp; - return stockCode && timestamp ? `${stockCode}_${timestamp}` : null; + + if (!stockCode || !timestamp) { + console.warn('getStockUniqueId: 缺少必要字段', { stockCode, timestamp }); + return null; + } + + return `${stockCode}_${timestamp}`; }; // 存储当前的完成回调函数 const currentOnCompleteCallback = ref(null); @@ -714,7 +737,10 @@ const isAudioPlaying = ref(false); // 获取股票的音频播放状态 const getStockAudioState = (stock) => { const stockUniqueId = getStockUniqueId(stock); - if (!stockUniqueId) return { isPlaying: false, isPaused: false }; + if (!stockUniqueId) { + console.warn('getStockAudioState: 无法获取股票唯一标识'); + return { isPlaying: false, isPaused: false }; + } return ( stockAudioStates.value.get(stockUniqueId) || { @@ -727,7 +753,15 @@ const getStockAudioState = (stock) => { // 设置股票的音频播放状态 const setStockAudioState = (stock, state) => { const stockUniqueId = getStockUniqueId(stock); - if (!stockUniqueId) return; + if (!stockUniqueId) { + console.warn('setStockAudioState: 无法获取股票唯一标识'); + return; + } + + if (!state || typeof state !== 'object') { + console.warn('setStockAudioState: 无效的状态对象'); + return; + } stockAudioStates.value.set(stockUniqueId, { ...state }); }; @@ -876,21 +910,30 @@ const getStockConclusion = (stock) => { // 辅助函数:获取股票的打字机文本状态 const getStockTypewriterTexts = (stock) => { const stockUniqueId = getStockUniqueId(stock); - if (!stockUniqueId) return null; + if (!stockUniqueId) { + console.warn('getStockTypewriterTexts: 无法获取股票唯一标识'); + return null; + } return stockTypewriterTexts.value.get(stockUniqueId) || null; }; // 辅助函数:获取股票的打字机可见性状态 const getStockTypewriterVisibility = (stock) => { const stockUniqueId = getStockUniqueId(stock); - if (!stockUniqueId) return null; + if (!stockUniqueId) { + console.warn('getStockTypewriterVisibility: 无法获取股票唯一标识'); + return null; + } return stockTypewriterVisibility.value.get(stockUniqueId) || null; }; // 辅助函数:检查股票是否正在进行打字机效果 const isStockTypewriting = (stock) => { const stockUniqueId = getStockUniqueId(stock); - if (!stockUniqueId) return false; + if (!stockUniqueId) { + console.warn('isStockTypewriting: 无法获取股票唯一标识'); + return false; + } return stockTypewriterShown.value.has(stockUniqueId) && !stockTypewriterTexts.value.has(stockUniqueId); }; @@ -2129,7 +2172,7 @@ async function handleSendMessage(input, onComplete) { // 关闭加载状态和等待提示,返回refuse信息,停止图片旋转,恢复历史数据 // isLoading.value = false; isPageLoaded.value = false; - const refuseMessage = response && response.msg ? response.msg : "接口返回数据异常,请重试"; + const refuseMessage = response && response.msg ? response.msg : "系统正在为您努力加载中,请稍后再试"; const aiMessage = reactive({ sender: "ai", text: processRefuseMessage(refuseMessage), @@ -2236,7 +2279,7 @@ async function handleSendMessage(input, onComplete) { } // 使用getConclusionAPI返回的msg在对话界面中输出 - const errorMsg = conclusionResponse.msg || "第二个接口请求失败"; + const errorMsg = conclusionResponse.msg || "系统正在为您努力加载中,请稍后再试"; const aiMessage = reactive({ sender: "ai", text: errorMsg, @@ -2367,7 +2410,7 @@ async function handleSendMessage(input, onComplete) { if (!conclusionResponse || !conclusionResponse.data) { const aiMessage = reactive({ sender: "ai", - text: "网络加载失败,请重试", + text: "系统正在为您努力加载中,请稍后再试", }); messages.value.push(aiMessage); } @@ -2526,14 +2569,14 @@ async function fetchData(code, market, stockName, queryText, stockId, presetUniq const aiMessage = reactive({ sender: "ai", - text: `数据丢失了,请稍后重试。`, + text: `系统正在为您努力加载中,请稍后再试`, }); messages.value.push(aiMessage); // 将AI消息添加到emotion store中 emotionStore.addConversation({ sender: "ai", - text: "数据丢失了,请稍后重试。", + text: "系统正在为您努力加载中,请稍后再试", timestamp: new Date().toISOString(), }); return false; // 返回失败标识,不添加股票到标签 @@ -2587,14 +2630,14 @@ async function fetchData(code, market, stockName, queryText, stockId, presetUniq const aiMessage = reactive({ sender: "ai", - text: "图表数据请求失败,请检查网络连接", + text: "系统正在为您努力加载中,请稍后再试", }); messages.value.push(aiMessage); // 将AI消息添加到emotion store中 emotionStore.addConversation({ sender: "ai", - text: "图表数据请求失败,请检查网络连接", + text: "系统正在为您努力加载中,请稍后再试", timestamp: new Date().toISOString(), }); return false; // 返回失败标识 @@ -2631,14 +2674,14 @@ async function fetchData(code, market, stockName, queryText, stockId, presetUniq const aiMessage = reactive({ sender: "ai", - text: "图表数据请求失败,请检查网络连接", + text: "系统正在为您努力加载中,请稍后再试", }); messages.value.push(aiMessage); // 将AI消息添加到emotion store中 emotionStore.addConversation({ sender: "ai", - text: "图表数据请求失败,请检查网络连接", + text: "系统正在为您努力加载中,请稍后再试", timestamp: new Date().toISOString(), }); return false; // 返回失败标识 @@ -2917,7 +2960,7 @@ function renderCharts(data) { // 将AI消息添加到emotion store中 emotionStore.addConversation({ sender: "ai", - text: "图表渲染失败,请重试", + text: "系统正在为您努力加载中,请稍后再试", timestamp: new Date().toISOString(), }); }