|
|
|
@ -26,9 +26,10 @@
|
|
|
|
|
<div class="message-content">
|
|
|
|
|
<div class="message-time">{{ item.time }}</div>
|
|
|
|
|
<div class="message-text">
|
|
|
|
|
<!-- 纯文本 -->
|
|
|
|
|
<div class="text-ros">
|
|
|
|
|
<span>{{ item.text }}</span>
|
|
|
|
|
<div v-show="item.from === 'user'">
|
|
|
|
|
<div v-show="item.add">
|
|
|
|
|
<n-tooltip placement="bottom" trigger="hover">
|
|
|
|
|
<template #trigger>
|
|
|
|
|
<n-icon size="14" style="cursor: pointer">
|
|
|
|
@ -50,11 +51,33 @@
|
|
|
|
|
</n-tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 图表 -->
|
|
|
|
|
<section v-if="item.chartType">
|
|
|
|
|
<div class="echarts-box" :id="item.chartType + index"></div>
|
|
|
|
|
<div class="echatrs-theme">
|
|
|
|
|
<div class="theme-title">风格切换:</div>
|
|
|
|
|
<div class="theme-list">
|
|
|
|
|
<div
|
|
|
|
|
class="theme-item"
|
|
|
|
|
@click="handlerTheme(item, themeIndex)"
|
|
|
|
|
v-for="(themeItem, themeIndex) in echartsTheme"
|
|
|
|
|
:key="themeIndex"
|
|
|
|
|
:class="item.chartInstanceActiveIndex == themeIndex ? 'activeTheme' : ''"
|
|
|
|
|
>
|
|
|
|
|
{{ themeItem }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<!-- 思考 -->
|
|
|
|
|
<div v-show="item.from === 'ai' && item.loading" class="ai-loading">
|
|
|
|
|
<span>思考中</span> <n-spin size="small" />
|
|
|
|
|
<span>思考中</span> <n-spin size="small" content-class="spin-class" />
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 免责 -->
|
|
|
|
|
<div class="ai-hint" v-show="item.from === 'ai' && (item.text || item.chartType)">
|
|
|
|
|
(注:本回答由AI生成,内容仅供参考)
|
|
|
|
|
</div>
|
|
|
|
|
<div class="ai-hint" v-show="item.from === 'ai'">(注:本回答由AI生成,内容仅供参考)</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -93,12 +116,13 @@ let loading = ref(false)
|
|
|
|
|
let keyWord = ref('')
|
|
|
|
|
//聊天记录list
|
|
|
|
|
let messageList = reactive([])
|
|
|
|
|
//聊天室容器
|
|
|
|
|
const scrollContainer = ref(null)
|
|
|
|
|
//聊天记录最后一个索引
|
|
|
|
|
let lastIndex = ref(0)
|
|
|
|
|
//主题
|
|
|
|
|
const echartsTheme = ['简约风', '商务风', '科技风']
|
|
|
|
|
|
|
|
|
|
// let bar = null
|
|
|
|
|
let stopWatch = null
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 页面初始完成
|
|
|
|
@ -128,36 +152,81 @@ const handleSend = async () => {
|
|
|
|
|
setMessageItem({
|
|
|
|
|
from: 'user',
|
|
|
|
|
text: keyWord.value,
|
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss')
|
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
|
add: true
|
|
|
|
|
})
|
|
|
|
|
// //先存储AI回答,作为交互提示,接口响应后再做更新
|
|
|
|
|
// setMessageItem({
|
|
|
|
|
// from: 'ai',
|
|
|
|
|
// text: '',
|
|
|
|
|
// time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
|
// loading: true //ai思考中
|
|
|
|
|
// })
|
|
|
|
|
// try {
|
|
|
|
|
// const res = await getAiMsg({ prompt: keyWord.value })
|
|
|
|
|
// if (res.type) {
|
|
|
|
|
// console.log('图表形式')
|
|
|
|
|
// } else {
|
|
|
|
|
// //纯文本
|
|
|
|
|
// updataMessageItem({
|
|
|
|
|
// from: 'ai',
|
|
|
|
|
// text: res,
|
|
|
|
|
// time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
|
// loading: false
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
// } catch {
|
|
|
|
|
// updataMessageItem({
|
|
|
|
|
// from: 'ai',
|
|
|
|
|
// text: '服务器繁忙,请稍后再试。',
|
|
|
|
|
// time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
|
// loading: false
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
//先存储AI回答,作为交互提示,接口响应后再做更新
|
|
|
|
|
setMessageItem({
|
|
|
|
|
from: 'ai',
|
|
|
|
|
text: '',
|
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
|
loading: true, //ai思考中
|
|
|
|
|
chartInstanceItem: null,
|
|
|
|
|
chartInstanceActiveIndex: 0,
|
|
|
|
|
chartType: null,
|
|
|
|
|
xData: [],
|
|
|
|
|
yData: []
|
|
|
|
|
})
|
|
|
|
|
try {
|
|
|
|
|
const res = await getAiMsg({ prompt: keyWord.value })
|
|
|
|
|
if (res.type) {
|
|
|
|
|
// 更新
|
|
|
|
|
updataMessageItem({
|
|
|
|
|
from: 'ai',
|
|
|
|
|
text: '',
|
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
|
loading: false, //ai思考中
|
|
|
|
|
chartInstanceItem: null,
|
|
|
|
|
chartInstanceActiveIndex: 0,
|
|
|
|
|
chartType: res.chartType,
|
|
|
|
|
xData: res.xData,
|
|
|
|
|
yData: res.yData,
|
|
|
|
|
title: res.title,
|
|
|
|
|
unit: res.unit
|
|
|
|
|
})
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
const itemData = messageList[lastIndex.value]
|
|
|
|
|
//饼图
|
|
|
|
|
if (res.chartType === 'pie') {
|
|
|
|
|
itemData.chartInstanceItem = new PieChart(`${res.chartType}${lastIndex.value}`, {
|
|
|
|
|
title: res.title,
|
|
|
|
|
unit: res.unit,
|
|
|
|
|
xData: res.xData,
|
|
|
|
|
data: res.yData
|
|
|
|
|
})
|
|
|
|
|
} else if (res.chartType === 'bar') {
|
|
|
|
|
itemData.chartInstanceItem = new BarChart(`${res.chartType}${lastIndex.value}`, {
|
|
|
|
|
title: res.title,
|
|
|
|
|
unit: res.unit,
|
|
|
|
|
xData: res.xData,
|
|
|
|
|
data: res.yData
|
|
|
|
|
})
|
|
|
|
|
} else if (res.chartType === 'line') {
|
|
|
|
|
itemData.chartInstanceItem = new LineChart(`${res.chartType}${lastIndex.value}`, {
|
|
|
|
|
title: res.title,
|
|
|
|
|
unit: res.unit,
|
|
|
|
|
xData: res.xData,
|
|
|
|
|
data: res.yData
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
//纯文本
|
|
|
|
|
updataMessageItem({
|
|
|
|
|
from: 'ai',
|
|
|
|
|
text: res,
|
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
|
loading: false
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
updataMessageItem({
|
|
|
|
|
from: 'ai',
|
|
|
|
|
text: '服务器繁忙,请稍后再试。',
|
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
|
loading: false
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 存储聊天室数据
|
|
|
|
@ -183,9 +252,42 @@ const updataMessageItem = data => {
|
|
|
|
|
* 图表切换主题
|
|
|
|
|
* @param index
|
|
|
|
|
*/
|
|
|
|
|
const handlerTheme = index => {
|
|
|
|
|
bar.changeColorStyle(index)
|
|
|
|
|
const handlerTheme = (item, index) => {
|
|
|
|
|
pauseWatching()
|
|
|
|
|
item.chartInstanceActiveIndex = index
|
|
|
|
|
item.chartInstanceItem.changeColorStyle(index)
|
|
|
|
|
setTimeout(()=>{
|
|
|
|
|
startWatching()
|
|
|
|
|
},1000)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 聊天室自动滚动条下拉
|
|
|
|
|
|
|
|
|
|
const startWatching = () => {
|
|
|
|
|
stopWatch = watch(messageList, newVal => {
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
if (scrollContainer.value) {
|
|
|
|
|
scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const pauseWatching = () => {
|
|
|
|
|
if (stopWatch) {
|
|
|
|
|
stopWatch() // 调用停止函数
|
|
|
|
|
stopWatch = null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
startWatching()
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped></style>
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
/* 设置滚动条整体样式 */
|
|
|
|
|
::-webkit-scrollbar {
|
|
|
|
|
width: 0px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|