|
|
@ -246,213 +246,295 @@ watch( |
|
|
|
|
|
|
|
// 调用工作流获取回复 |
|
|
|
const result = (await getReplyAPI(params)).json(); |
|
|
|
const ans = ref(); |
|
|
|
// console.log(result, "result"); |
|
|
|
// 解析 data 字段中的 JSON |
|
|
|
// 获取结果 |
|
|
|
const ans = ref(); |
|
|
|
await result.then((res) => { |
|
|
|
// console.log(res.data, "res"); |
|
|
|
|
|
|
|
// 解析 data 字段中的 JSON |
|
|
|
ans.value = JSON.parse(res.data); |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
// console.log(ans.value, "ans"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const AIcontent = ref(""); |
|
|
|
// 处理不同的 answer 字段 |
|
|
|
|
|
|
|
var status; |
|
|
|
if (ans.value.resp !== "") { |
|
|
|
status = JSON.parse(ans.value.resp); |
|
|
|
} else { |
|
|
|
status = null; |
|
|
|
} |
|
|
|
console.log(status, "status") |
|
|
|
if (status === null || status.code == 200) { |
|
|
|
if (ans.value.answerG !== "") { |
|
|
|
AIcontent.value = ans.value.answerG; |
|
|
|
const code = ans.value.code; |
|
|
|
const market = ans.value.market; |
|
|
|
const data = JSON.parse(ans.value.duobaoData); |
|
|
|
|
|
|
|
console.log("处理 K 线数据 - 开始"); |
|
|
|
console.log(data, "data"); |
|
|
|
|
|
|
|
const Kline20 = { |
|
|
|
name: data.data.HomePage.StockInformation.Name, |
|
|
|
Kline: data.data.AIBull.KLine20 |
|
|
|
} |
|
|
|
|
|
|
|
// 打印K线数据结构 |
|
|
|
console.log("K线数据结构:", Kline20); |
|
|
|
console.log("K线数据名称:", Kline20.name); |
|
|
|
console.log("K线数据数组长度:", Kline20.Kline ? Kline20.Kline.length : 0); |
|
|
|
if (ans.value.platform !== "" && ans.value.platform !== null) { // 判断是否是平台问题 |
|
|
|
AIcontent.value = ans.value.platform; |
|
|
|
} else if (ans.value.news !== "" && ans.value.news !== null) { // 判断是否是新闻问题 |
|
|
|
AIcontent.value = ans.value.news; |
|
|
|
} else if (ans.value.other !== "" && ans.value.other !== null) { // 判断是否是其他问题 |
|
|
|
AIcontent.value = ans.value.other; |
|
|
|
} else { // 判断是否是股票问题 |
|
|
|
var status; |
|
|
|
if (ans.value.resp !== "") { |
|
|
|
status = JSON.parse(ans.value.resp); |
|
|
|
} else { |
|
|
|
status = null; |
|
|
|
} |
|
|
|
console.log(status, "status") |
|
|
|
if (status === null || status.code == 200) { // 判断是否有剩余次数 |
|
|
|
if (ans.value.stock !== "") { |
|
|
|
AIcontent.value = ans.value.stock; |
|
|
|
const code = ans.value.code; |
|
|
|
const market = ans.value.market; |
|
|
|
const data = JSON.parse(ans.value.data); |
|
|
|
|
|
|
|
console.log("处理 K 线数据 - 开始"); |
|
|
|
console.log(data, "data"); |
|
|
|
|
|
|
|
const Kline20 = { |
|
|
|
name: data.data.HomePage.StockInformation.Name, |
|
|
|
Kline: data.data.AIBull.KLine20 |
|
|
|
} |
|
|
|
|
|
|
|
// 输出第一个数据点作为示例 |
|
|
|
if (Kline20.Kline && Kline20.Kline.length > 0) { |
|
|
|
console.log("K线首个数据点:", Kline20.Kline[0]); |
|
|
|
} |
|
|
|
// 打印K线数据结构 |
|
|
|
console.log("K线数据结构:", Kline20); |
|
|
|
console.log("K线数据名称:", Kline20.name); |
|
|
|
console.log("K线数据数组长度:", Kline20.Kline ? Kline20.Kline.length : 0); |
|
|
|
|
|
|
|
// 设置数据有效标志 |
|
|
|
hasValidData.value = true; |
|
|
|
console.log("hasValidData设置为:", hasValidData.value); |
|
|
|
// 设置数据有效标志 |
|
|
|
hasValidData.value = true; |
|
|
|
console.log("hasValidData设置为:", hasValidData.value); |
|
|
|
|
|
|
|
chatStore.messages.pop(); |
|
|
|
chatStore.messages.pop(); |
|
|
|
|
|
|
|
// 先推送K线图消息 |
|
|
|
const klineMessageId = `kline-${Date.now()}`; |
|
|
|
console.log("生成K线消息ID:", klineMessageId); |
|
|
|
// 先推送K线图消息 |
|
|
|
const klineMessageId = `kline-${Date.now()}`; |
|
|
|
console.log("生成K线消息ID:", klineMessageId); |
|
|
|
|
|
|
|
chatStore.messages.push({ |
|
|
|
sender: "ai", |
|
|
|
type: "kline", |
|
|
|
chartData: Kline20, |
|
|
|
messageId: klineMessageId, |
|
|
|
hasValidData: true // 添加hasValidData标志 |
|
|
|
}); |
|
|
|
chatStore.messages.push({ |
|
|
|
sender: "ai", |
|
|
|
type: "kline", |
|
|
|
chartData: Kline20, |
|
|
|
messageId: klineMessageId, |
|
|
|
hasValidData: true // 添加hasValidData标志 |
|
|
|
}); |
|
|
|
|
|
|
|
console.log("K线消息已添加到聊天列表"); |
|
|
|
console.log("K线消息已添加到聊天列表"); |
|
|
|
|
|
|
|
// 再推送文字分析内容的消息 |
|
|
|
chatStore.messages.push({ |
|
|
|
sender: "ai", |
|
|
|
content: "AI正在思考中..." |
|
|
|
}); |
|
|
|
// 再推送文字分析内容的消息 |
|
|
|
chatStore.messages.push({ |
|
|
|
sender: "ai", |
|
|
|
content: "AI正在思考中..." |
|
|
|
}); |
|
|
|
|
|
|
|
// 在渲染完成后初始化图表 |
|
|
|
nextTick(() => { |
|
|
|
console.log("nextTick开始 - 准备渲染图表"); |
|
|
|
console.log("消息列表:", chatStore.messages); |
|
|
|
|
|
|
|
// 寻找最新添加的K线消息索引 |
|
|
|
let klineIndex = -1; |
|
|
|
for (let i = 0; i < chatStore.messages.length; i++) { |
|
|
|
if (chatStore.messages[i].messageId === klineMessageId) { |
|
|
|
klineIndex = i; |
|
|
|
break; |
|
|
|
// 在渲染完成后初始化图表 |
|
|
|
nextTick(() => { |
|
|
|
console.log("nextTick开始 - 准备渲染图表"); |
|
|
|
console.log("消息列表:", chatStore.messages); |
|
|
|
|
|
|
|
// 寻找最新添加的K线消息索引 |
|
|
|
let klineIndex = -1; |
|
|
|
for (let i = 0; i < chatStore.messages.length; i++) { |
|
|
|
if (chatStore.messages[i].messageId === klineMessageId) { |
|
|
|
klineIndex = i; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
console.log("找到的K线消息索引:", klineIndex); |
|
|
|
|
|
|
|
if (klineIndex !== -1) { |
|
|
|
const containerId = `kline-container-${klineIndex}`; |
|
|
|
console.log("图表容器ID:", containerId); |
|
|
|
console.log("找到的K线消息索引:", klineIndex); |
|
|
|
|
|
|
|
// 确保DOM已经渲染完成 |
|
|
|
setTimeout(() => { |
|
|
|
console.log("延时执行,确保DOM已渲染"); |
|
|
|
KlineCanvsEcharts(containerId); |
|
|
|
}, 100); // 短暂延时确保DOM已渲染 |
|
|
|
} else { |
|
|
|
console.warn("未找到K线消息"); |
|
|
|
} |
|
|
|
}); |
|
|
|
if (klineIndex !== -1) { |
|
|
|
const containerId = `kline-container-${klineIndex}`; |
|
|
|
console.log("图表容器ID:", containerId); |
|
|
|
|
|
|
|
} else if (ans.value.answerN !== "") { |
|
|
|
AIcontent.value = ans.value.answerN; |
|
|
|
} else if (ans.value.answerO !== "") { |
|
|
|
AIcontent.value = ans.value.answerO; |
|
|
|
// 确保DOM已经渲染完成 |
|
|
|
setTimeout(() => { |
|
|
|
console.log("延时执行,确保DOM已渲染"); |
|
|
|
KlineCanvsEcharts(containerId); |
|
|
|
}, 100); // 短暂延时确保DOM已渲染 |
|
|
|
} else { |
|
|
|
console.warn("未找到K线消息"); |
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
AIcontent.value = status.msg; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// // 使用marked库将Markdown转换为HTML |
|
|
|
// AIcontent.value = marked(AIcontent.value,); |
|
|
|
// // 使用 KaTeX 渲染数学公式 |
|
|
|
// const katexRegex = /\$\$(.*?)\$\$/g; |
|
|
|
// AIcontent.value = AIcontent.value.replace(katexRegex, (match, formula) => { |
|
|
|
// try { |
|
|
|
// return katex.renderToString(formula, { throwOnError: false }); |
|
|
|
// } catch (error) { |
|
|
|
// console.error('KaTeX 渲染错误:', error); |
|
|
|
// return match; |
|
|
|
// } |
|
|
|
// }); |
|
|
|
|
|
|
|
// chatStore.messages.push({ |
|
|
|
// sender: "ai", |
|
|
|
// content: AIcontent.value |
|
|
|
// }) |
|
|
|
|
|
|
|
// 修改后的消息处理逻辑 |
|
|
|
const processedContent = marked(AIcontent.value); |
|
|
|
const katexRegex = /\$\$(.*?)\$\$/g; |
|
|
|
const plainTextContent = htmlToText(processedContent); |
|
|
|
|
|
|
|
// 获取音频数据 |
|
|
|
const TTSResult = (await TTSAPI({ |
|
|
|
language: "cn", |
|
|
|
content: plainTextContent |
|
|
|
})).json() |
|
|
|
|
|
|
|
const tts = ref(); |
|
|
|
await TTSResult.then((res) => { |
|
|
|
tts.value = JSON.parse(res.data); |
|
|
|
}) |
|
|
|
|
|
|
|
const ttsUrl = ref(); |
|
|
|
if (tts.value.tts_cn !== null) { |
|
|
|
audioStore.ttsUrl = tts.value.tts_cn.url; |
|
|
|
ttsUrl.value = tts.value.tts_cn.url; |
|
|
|
} else if (tts.value.tts_en !== null) { |
|
|
|
audioStore.ttsUrl = tts.value.tts_en.url; |
|
|
|
ttsUrl.value = tts.value.tts_en.url; |
|
|
|
} |
|
|
|
// if (status === null || status.code == 200) { |
|
|
|
// if (ans.value.answerG !== "") { |
|
|
|
// AIcontent.value = ans.value.answerG; |
|
|
|
// const code = ans.value.code; |
|
|
|
// const market = ans.value.market; |
|
|
|
// const data = JSON.parse(ans.value.duobaoData); |
|
|
|
|
|
|
|
// console.log("处理 K 线数据 - 开始"); |
|
|
|
// console.log(data, "data"); |
|
|
|
|
|
|
|
// const Kline20 = { |
|
|
|
// name: data.data.HomePage.StockInformation.Name, |
|
|
|
// Kline: data.data.AIBull.KLine20 |
|
|
|
// } |
|
|
|
|
|
|
|
// // 打印K线数据结构 |
|
|
|
// console.log("K线数据结构:", Kline20); |
|
|
|
// console.log("K线数据名称:", Kline20.name); |
|
|
|
// console.log("K线数据数组长度:", Kline20.Kline ? Kline20.Kline.length : 0); |
|
|
|
|
|
|
|
// // 输出第一个数据点作为示例 |
|
|
|
// if (Kline20.Kline && Kline20.Kline.length > 0) { |
|
|
|
// console.log("K线首个数据点:", Kline20.Kline[0]); |
|
|
|
// } |
|
|
|
|
|
|
|
// // 设置数据有效标志 |
|
|
|
// hasValidData.value = true; |
|
|
|
// console.log("hasValidData设置为:", hasValidData.value); |
|
|
|
|
|
|
|
// chatStore.messages.pop(); |
|
|
|
|
|
|
|
// // 先推送K线图消息 |
|
|
|
// const klineMessageId = `kline-${Date.now()}`; |
|
|
|
// console.log("生成K线消息ID:", klineMessageId); |
|
|
|
|
|
|
|
// chatStore.messages.push({ |
|
|
|
// sender: "ai", |
|
|
|
// type: "kline", |
|
|
|
// chartData: Kline20, |
|
|
|
// messageId: klineMessageId, |
|
|
|
// hasValidData: true // 添加hasValidData标志 |
|
|
|
// }); |
|
|
|
|
|
|
|
// console.log("K线消息已添加到聊天列表"); |
|
|
|
|
|
|
|
// // 再推送文字分析内容的消息 |
|
|
|
// chatStore.messages.push({ |
|
|
|
// sender: "ai", |
|
|
|
// content: "AI正在思考中..." |
|
|
|
// }); |
|
|
|
|
|
|
|
// // 在渲染完成后初始化图表 |
|
|
|
// nextTick(() => { |
|
|
|
// console.log("nextTick开始 - 准备渲染图表"); |
|
|
|
// console.log("消息列表:", chatStore.messages); |
|
|
|
|
|
|
|
// // 寻找最新添加的K线消息索引 |
|
|
|
// let klineIndex = -1; |
|
|
|
// for (let i = 0; i < chatStore.messages.length; i++) { |
|
|
|
// if (chatStore.messages[i].messageId === klineMessageId) { |
|
|
|
// klineIndex = i; |
|
|
|
// break; |
|
|
|
// } |
|
|
|
// } |
|
|
|
|
|
|
|
// console.log("找到的K线消息索引:", klineIndex); |
|
|
|
|
|
|
|
// if (klineIndex !== -1) { |
|
|
|
// const containerId = `kline-container-${klineIndex}`; |
|
|
|
// console.log("图表容器ID:", containerId); |
|
|
|
|
|
|
|
// // 确保DOM已经渲染完成 |
|
|
|
// setTimeout(() => { |
|
|
|
// console.log("延时执行,确保DOM已渲染"); |
|
|
|
// KlineCanvsEcharts(containerId); |
|
|
|
// }, 100); // 短暂延时确保DOM已渲染 |
|
|
|
// } else { |
|
|
|
// console.warn("未找到K线消息"); |
|
|
|
// } |
|
|
|
// }); |
|
|
|
|
|
|
|
// } else if (ans.value.answerN !== "") { |
|
|
|
// AIcontent.value = ans.value.answerN; |
|
|
|
// } else if (ans.value.answerO !== "") { |
|
|
|
// AIcontent.value = ans.value.answerO; |
|
|
|
// } |
|
|
|
|
|
|
|
// // 使用marked库将Markdown转换为HTML |
|
|
|
// AIcontent.value = marked(AIcontent.value,); |
|
|
|
// // 使用 KaTeX 渲染数学公式 |
|
|
|
// const katexRegex = /\$\$(.*?)\$\$/g; |
|
|
|
// AIcontent.value = AIcontent.value.replace(katexRegex, (match, formula) => { |
|
|
|
// try { |
|
|
|
// return katex.renderToString(formula, { throwOnError: false }); |
|
|
|
// } catch (error) { |
|
|
|
// console.error('KaTeX 渲染错误:', error); |
|
|
|
// return match; |
|
|
|
// } |
|
|
|
// }); |
|
|
|
|
|
|
|
// chatStore.messages.push({ |
|
|
|
// sender: "ai", |
|
|
|
// content: AIcontent.value |
|
|
|
// }) |
|
|
|
|
|
|
|
// 修改后的消息处理逻辑 |
|
|
|
const processedContent = marked(AIcontent.value); |
|
|
|
const katexRegex = /\$\$(.*?)\$\$/g; |
|
|
|
const plainTextContent = htmlToText(processedContent); |
|
|
|
|
|
|
|
// 获取音频数据 |
|
|
|
const TTSResult = (await TTSAPI({ |
|
|
|
language: "cn", |
|
|
|
content: plainTextContent |
|
|
|
})).json() |
|
|
|
|
|
|
|
if (ttsUrl.value) { |
|
|
|
nextTick(() => { |
|
|
|
if (audioStore.isVoiceEnabled) { |
|
|
|
console.log("ttsUrl.value", ttsUrl.value) |
|
|
|
// 播放音频 |
|
|
|
playAudio(ttsUrl.value) |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
const tts = ref(); |
|
|
|
await TTSResult.then((res) => { |
|
|
|
tts.value = JSON.parse(res.data); |
|
|
|
}) |
|
|
|
|
|
|
|
const ttsUrl = ref(); |
|
|
|
if (tts.value.tts_cn !== null) { |
|
|
|
audioStore.ttsUrl = tts.value.tts_cn.url; |
|
|
|
ttsUrl.value = tts.value.tts_cn.url; |
|
|
|
} else if (tts.value.tts_en !== null) { |
|
|
|
audioStore.ttsUrl = tts.value.tts_en.url; |
|
|
|
ttsUrl.value = tts.value.tts_en.url; |
|
|
|
} |
|
|
|
|
|
|
|
chatStore.messages.pop(); |
|
|
|
// 先推送初始消息 |
|
|
|
const aiMessage = reactive({ |
|
|
|
sender: "ai", |
|
|
|
content: "", |
|
|
|
isTyping: true, |
|
|
|
if (ttsUrl.value) { |
|
|
|
nextTick(() => { |
|
|
|
if (audioStore.isVoiceEnabled) { |
|
|
|
console.log("ttsUrl.value", ttsUrl.value) |
|
|
|
// 播放音频 |
|
|
|
playAudio(ttsUrl.value) |
|
|
|
} |
|
|
|
}); |
|
|
|
chatStore.messages.push(aiMessage); |
|
|
|
} |
|
|
|
|
|
|
|
chatStore.messages.pop(); |
|
|
|
// 先推送初始消息 |
|
|
|
const aiMessage = reactive({ |
|
|
|
sender: "ai", |
|
|
|
content: "", |
|
|
|
isTyping: true, |
|
|
|
}); |
|
|
|
chatStore.messages.push(aiMessage); |
|
|
|
|
|
|
|
let index = 0; |
|
|
|
const typingInterval = setInterval(() => { |
|
|
|
if (index < processedContent.length) { |
|
|
|
aiMessage.content += processedContent.charAt(index); |
|
|
|
index++; |
|
|
|
let index = 0; |
|
|
|
const typingInterval = setInterval(() => { |
|
|
|
if (index < processedContent.length) { |
|
|
|
aiMessage.content += processedContent.charAt(index); |
|
|
|
index++; |
|
|
|
|
|
|
|
} else { |
|
|
|
clearInterval(typingInterval); |
|
|
|
aiMessage.isTyping = false; |
|
|
|
} else { |
|
|
|
clearInterval(typingInterval); |
|
|
|
aiMessage.isTyping = false; |
|
|
|
|
|
|
|
// 延迟处理KaTeX确保DOM已更新 |
|
|
|
nextTick(() => { |
|
|
|
aiMessage.content = aiMessage.content.replace(katexRegex, (match, formula) => { |
|
|
|
try { |
|
|
|
return katex.renderToString(formula, { throwOnError: false }); |
|
|
|
} catch (error) { |
|
|
|
console.error('KaTeX 渲染错误:', error); |
|
|
|
return match; |
|
|
|
} |
|
|
|
}); |
|
|
|
chatStore.setLoading(false); |
|
|
|
// 延迟处理KaTeX确保DOM已更新 |
|
|
|
nextTick(() => { |
|
|
|
aiMessage.content = aiMessage.content.replace(katexRegex, (match, formula) => { |
|
|
|
try { |
|
|
|
return katex.renderToString(formula, { throwOnError: false }); |
|
|
|
} catch (error) { |
|
|
|
console.error('KaTeX 渲染错误:', error); |
|
|
|
return match; |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
}, 50); // 调整速度为50ms/字符 |
|
|
|
} else { |
|
|
|
chatStore.messages.pop(); |
|
|
|
chatStore.messages.push({ |
|
|
|
sender: "ai", |
|
|
|
content: status.msg |
|
|
|
}); |
|
|
|
|
|
|
|
chatStore.setLoading(false); |
|
|
|
} |
|
|
|
chatStore.setLoading(false); |
|
|
|
}); |
|
|
|
} |
|
|
|
}, 50); // 调整速度为50ms/字符 |
|
|
|
// } else { |
|
|
|
// chatStore.messages.pop(); |
|
|
|
// chatStore.messages.push({ |
|
|
|
// sender: "ai", |
|
|
|
// content: status.msg |
|
|
|
// }); |
|
|
|
|
|
|
|
// chatStore.setLoading(false); |
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|