|
|
@ -1001,7 +1001,9 @@ async function handleSendMessage(input, onComplete) { |
|
|
|
|
|
|
|
// 检查用户输入是否合法 |
|
|
|
if (!parsedData || !parsedData.market || !parsedData.code) { |
|
|
|
// 输入不合法,返回refuse信息,停止图片旋转,恢复历史数据 |
|
|
|
// 输入不合法,关闭加载状态和等待提示,返回refuse信息,停止图片旋转,恢复历史数据 |
|
|
|
isLoading.value = false; |
|
|
|
isPageLoaded.value = false; |
|
|
|
const aiMessage = reactive({ sender: 'ai', text: processRefuseMessage(parsedData.refuse) }); |
|
|
|
messages.value.push(aiMessage); |
|
|
|
isRotating.value = false; |
|
|
@ -1094,10 +1096,23 @@ async function handleSendMessage(input, onComplete) { |
|
|
|
} else { |
|
|
|
// 数据加载失败,停止图片旋转,恢复历史数据 |
|
|
|
isLoading.value = false; |
|
|
|
const aiMessage = reactive({ sender: 'ai', text: '数据加载失败,请重试' }); |
|
|
|
messages.value.push(aiMessage); |
|
|
|
// 如果 fetchDataResult 为 false,说明数据不完整的错误信息已经在 fetchData 中添加到 messages |
|
|
|
// 只有在 conclusionResponse 有问题时才添加通用错误信息 |
|
|
|
if (!conclusionResponse || !conclusionResponse.data) { |
|
|
|
const aiMessage = reactive({ sender: 'ai', text: '数据加载失败,请重试' }); |
|
|
|
messages.value.push(aiMessage); |
|
|
|
} |
|
|
|
isRotating.value = false; |
|
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
|
|
|
|
|
// 如果有之前的股票数据且页面已加载,重新渲染图表 |
|
|
|
if (isPageLoaded.value && emotionStore.activeStock && emotionStore.activeStock.apiData) { |
|
|
|
nextTick(() => { |
|
|
|
renderCharts(emotionStore.activeStock.apiData); |
|
|
|
console.log('搜索失败,恢复显示之前股票的图表:', emotionStore.activeStock.stockInfo.name); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
onComplete(); |
|
|
@ -1107,11 +1122,36 @@ async function handleSendMessage(input, onComplete) { |
|
|
|
return; |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
// 请求失败时关闭加载状态 |
|
|
|
isLoading.value = false; |
|
|
|
|
|
|
|
// 如果有之前的股票数据,恢复显示状态;否则设置为false |
|
|
|
if (emotionStore.stockList.length > 0 && emotionStore.activeStock) { |
|
|
|
isPageLoaded.value = true; |
|
|
|
console.log('请求工作流接口失败,但恢复显示之前的股票数据'); |
|
|
|
// 立即渲染之前股票的图表,提升用户体验 |
|
|
|
nextTick(() => { |
|
|
|
renderCharts(emotionStore.activeStock.apiData); |
|
|
|
console.log('立即恢复显示之前股票的图表:', emotionStore.activeStock.stockInfo.name); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
isPageLoaded.value = false; |
|
|
|
} |
|
|
|
|
|
|
|
const aiMessage = reactive({ sender: 'ai', text: '请求工作流接口失败,请检查网络连接' }); |
|
|
|
messages.value.push(aiMessage); |
|
|
|
// 请求失败时停止图片旋转,恢复历史数据 |
|
|
|
isRotating.value = false; |
|
|
|
messages.value = [...previousMessages, ...messages.value]; |
|
|
|
|
|
|
|
// 如果有之前的股票数据且页面已加载,重新渲染图表 |
|
|
|
if (isPageLoaded.value && emotionStore.activeStock && emotionStore.activeStock.apiData) { |
|
|
|
nextTick(() => { |
|
|
|
renderCharts(emotionStore.activeStock.apiData); |
|
|
|
console.log('请求失败,恢复显示之前股票的图表:', emotionStore.activeStock.stockInfo.name); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 调用完成回调,重新启用输入框 |
|
|
|
if (onComplete && typeof onComplete === 'function') { |
|
|
|
onComplete(); |
|
|
@ -1154,7 +1194,37 @@ async function fetchData(code, market, stockName, queryText) { |
|
|
|
const stockDataResponse = stockDataResult.data; // 获取返回所有的数据 |
|
|
|
|
|
|
|
if (stockDataResponse.code === 200 && stockDataResponse.data) { |
|
|
|
// 创建股票数据对象 |
|
|
|
// 检查关键数据字段是否完整 |
|
|
|
const validation = validateRequiredFields(stockDataResponse.data); |
|
|
|
|
|
|
|
// 如果有关键数据缺失,返回失败,不添加到StockTabs |
|
|
|
if (!validation.isValid) { |
|
|
|
console.log('API返回数据不完整,缺失字段:', validation.missingFields); |
|
|
|
// 关闭加载状态 |
|
|
|
isLoading.value = false; |
|
|
|
|
|
|
|
// 如果有之前的股票数据,恢复显示状态;否则设置为false |
|
|
|
if (emotionStore.stockList.length > 0 && emotionStore.activeStock) { |
|
|
|
isPageLoaded.value = true; |
|
|
|
console.log('数据验证失败,但恢复显示之前的股票数据'); |
|
|
|
// 立即渲染之前股票的图表,提升用户体验 |
|
|
|
nextTick(() => { |
|
|
|
renderCharts(emotionStore.activeStock.apiData); |
|
|
|
console.log('立即恢复显示之前股票的图表:', emotionStore.activeStock.stockInfo.name); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
isPageLoaded.value = false; |
|
|
|
} |
|
|
|
|
|
|
|
const aiMessage = reactive({ |
|
|
|
sender: 'ai', |
|
|
|
text: `数据丢失了,请稍后重试。` |
|
|
|
}); |
|
|
|
messages.value.push(aiMessage); |
|
|
|
return false; // 返回失败标识,不添加股票到标签 |
|
|
|
} |
|
|
|
|
|
|
|
// 只有数据完整时才创建股票数据对象并添加到store |
|
|
|
const stockData = { |
|
|
|
queryText: queryText, |
|
|
|
stockInfo: { |
|
|
@ -1166,21 +1236,72 @@ async function fetchData(code, market, stockName, queryText) { |
|
|
|
conclusionData: conclusionData.value, // 包含结论数据 |
|
|
|
timestamp: new Date().toISOString() |
|
|
|
}; |
|
|
|
// 将股票数据添加到store中 |
|
|
|
// 将股票数据添加到store中,显示在StockTabs中 |
|
|
|
emotionStore.addStock(stockData); |
|
|
|
return true; // 返回成功标识 |
|
|
|
} else { |
|
|
|
// 关闭加载状态 |
|
|
|
isLoading.value = false; |
|
|
|
|
|
|
|
// 如果有之前的股票数据,恢复显示状态;否则设置为false |
|
|
|
if (emotionStore.stockList.length > 0 && emotionStore.activeStock) { |
|
|
|
isPageLoaded.value = true; |
|
|
|
console.log('API请求失败,但恢复显示之前的股票数据'); |
|
|
|
// 立即渲染之前股票的图表,提升用户体验 |
|
|
|
nextTick(() => { |
|
|
|
renderCharts(emotionStore.activeStock.apiData); |
|
|
|
console.log('立即恢复显示之前股票的图表:', emotionStore.activeStock.stockInfo.name); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
isPageLoaded.value = false; |
|
|
|
} |
|
|
|
|
|
|
|
const aiMessage = reactive({ sender: 'ai', text: '图表数据请求失败,请检查网络连接' }); |
|
|
|
messages.value.push(aiMessage); |
|
|
|
return false; // 返回失败标识 |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
// 关闭加载状态 |
|
|
|
isLoading.value = false; |
|
|
|
|
|
|
|
// 如果有之前的股票数据,恢复显示状态;否则设置为false |
|
|
|
if (emotionStore.stockList.length > 0 && emotionStore.activeStock) { |
|
|
|
isPageLoaded.value = true; |
|
|
|
console.log('网络异常,但恢复显示之前的股票数据'); |
|
|
|
// 立即渲染之前股票的图表,提升用户体验 |
|
|
|
nextTick(() => { |
|
|
|
renderCharts(emotionStore.activeStock.apiData); |
|
|
|
console.log('立即恢复显示之前股票的图表:', emotionStore.activeStock.stockInfo.name); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
isPageLoaded.value = false; |
|
|
|
} |
|
|
|
|
|
|
|
const aiMessage = reactive({ sender: 'ai', text: '图表数据请求失败,请检查网络连接' }); |
|
|
|
messages.value.push(aiMessage); |
|
|
|
return false; // 返回失败标识 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 检查关键数据字段是否完整的函数 |
|
|
|
function validateRequiredFields(data) { |
|
|
|
const requiredFields = ['GSWDJ', 'KLine20', 'QXJMQ', 'QXTDLD', 'WDRL']; |
|
|
|
const missingFields = []; |
|
|
|
|
|
|
|
for (const field of requiredFields) { |
|
|
|
if (!data[field] || |
|
|
|
(Array.isArray(data[field]) && data[field].length === 0) || |
|
|
|
(typeof data[field] === 'object' && !hasValidData(data[field]))) { |
|
|
|
missingFields.push(field); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
isValid: missingFields.length === 0, |
|
|
|
missingFields: missingFields |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
// 检查对象是否包含有效数据的辅助函数 |
|
|
|
function hasValidData(obj) { |
|
|
|
if (!obj || typeof obj !== 'object') { |
|
|
@ -1236,6 +1357,25 @@ function renderCharts(data) { |
|
|
|
// 深拷贝数据避免污染原始数据 |
|
|
|
const clonedData = JSON.parse(JSON.stringify(data)); |
|
|
|
|
|
|
|
// 检查关键数据字段是否完整 |
|
|
|
const validation = validateRequiredFields(clonedData); |
|
|
|
|
|
|
|
// 如果有任何关键数据缺失,不渲染页面并返回提示 |
|
|
|
if (!validation.isValid) { |
|
|
|
console.log('关键数据缺失:', validation.missingFields); |
|
|
|
const aiMessage = reactive({ |
|
|
|
sender: 'ai', |
|
|
|
text: `数据不完整,缺少以下关键数据:${validation.missingFields.join('、')}。请稍后重试或联系客服。` |
|
|
|
}); |
|
|
|
messages.value.push(aiMessage); |
|
|
|
|
|
|
|
// 隐藏页面内容 |
|
|
|
isPageLoaded.value = false; |
|
|
|
isLoading.value = false; |
|
|
|
|
|
|
|
return; // 直接返回,不进行后续渲染 |
|
|
|
} |
|
|
|
|
|
|
|
// 先设置图表组件显示状态 |
|
|
|
chartVisibility.value = { |
|
|
|
marketTemperature: !!(clonedData.GSWDJ && clonedData.GSWDJ.length > 0), |
|
|
@ -1871,13 +2011,13 @@ defineExpose({ |
|
|
|
right: 0; |
|
|
|
height: 2px; |
|
|
|
background: linear-gradient(90deg, #00d4ff, #0099ff, #00d4ff); |
|
|
|
opacity: 0.8; |
|
|
|
opacity: 0.8; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
&:last-child { |
|
|
|
margin-bottom: 0; |
|
|
|
margin-bottom: 0; |
|
|
|
} |
|
|
|
|
|
|
|
.conclusion-title { |
|
|
|