|
|
@ -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回复 |
|
|
|
if (!existingInMessages && !existingInStore) { |
|
|
|
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); |
|
|
|
} |
|
|
|
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); |
|
|
|
}; |
|
|
|
|
|
|
|