|
|
@ -25,7 +25,7 @@
|
|
|
|
<!-- 内容 -->
|
|
|
|
<!-- 内容 -->
|
|
|
|
<div class="message-content">
|
|
|
|
<div class="message-content">
|
|
|
|
<div class="message-time">{{ item.time }}</div>
|
|
|
|
<div class="message-time">{{ item.time }}</div>
|
|
|
|
<div class="message-text">
|
|
|
|
<div class="message-text" :id="`box${index}`">
|
|
|
|
<!-- 纯文本 -->
|
|
|
|
<!-- 纯文本 -->
|
|
|
|
<div class="text-ros">
|
|
|
|
<div class="text-ros">
|
|
|
|
<span>{{ item.text }}</span>
|
|
|
|
<span>{{ item.text }}</span>
|
|
|
@ -76,7 +76,24 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- 免责 -->
|
|
|
|
<!-- 免责 -->
|
|
|
|
<div class="ai-hint" v-show="item.from === 'ai' && (item.text || item.chartType)">
|
|
|
|
<div class="ai-hint" v-show="item.from === 'ai' && (item.text || item.chartType)">
|
|
|
|
(注:本回答由AI生成,内容仅供参考)
|
|
|
|
<span>注:本回答由AI生成,内容仅供参考</span>
|
|
|
|
|
|
|
|
<div class="upload-text" @click="uploadImage(index)">
|
|
|
|
|
|
|
|
<n-icon size="14">
|
|
|
|
|
|
|
|
<svg
|
|
|
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
|
|
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
|
|
|
|
|
|
viewBox="0 0 16 16"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<g fill="none">
|
|
|
|
|
|
|
|
<path
|
|
|
|
|
|
|
|
d="M3.5 13h9a.75.75 0 0 1 .102 1.493l-.102.007h-9a.75.75 0 0 1-.102-1.493L3.5 13h9h-9zM7.898 1.007L8 1a.75.75 0 0 1 .743.648l.007.102v7.688l2.255-2.254a.75.75 0 0 1 .977-.072l.084.072a.75.75 0 0 1 .072.977l-.072.084L8.53 11.78a.75.75 0 0 1-.976.073l-.084-.073l-3.536-3.535a.75.75 0 0 1 .977-1.133l.084.072L7.25 9.44V1.75a.75.75 0 0 1 .648-.743L8 1l-.102.007z"
|
|
|
|
|
|
|
|
fill="currentColor"
|
|
|
|
|
|
|
|
></path>
|
|
|
|
|
|
|
|
</g>
|
|
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
|
|
</n-icon>
|
|
|
|
|
|
|
|
<span>下载图片</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
@ -110,6 +127,15 @@ import { LineChart, BarChart, PieChart } from './class/index'
|
|
|
|
import { AiHint } from '../components'
|
|
|
|
import { AiHint } from '../components'
|
|
|
|
import userIcon from '@/assets/images/ai/user-icon.png'
|
|
|
|
import userIcon from '@/assets/images/ai/user-icon.png'
|
|
|
|
import aiIcon from '@/assets/images/ai/ai-icon.png'
|
|
|
|
import aiIcon from '@/assets/images/ai/ai-icon.png'
|
|
|
|
|
|
|
|
import { useMessage } from 'naive-ui'
|
|
|
|
|
|
|
|
import useMessageRoomStore from '@/store/modules/messageRoom'
|
|
|
|
|
|
|
|
import { canvasCut } from '@/utils'
|
|
|
|
|
|
|
|
import { historyMessageRoomById } from '@/api/path'
|
|
|
|
|
|
|
|
import { useRoute } from 'vue-router'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
|
|
const useMessageRoom = useMessageRoomStore()
|
|
|
|
|
|
|
|
const messageDialog = useMessage()
|
|
|
|
//输入框加载
|
|
|
|
//输入框加载
|
|
|
|
let loading = ref(false)
|
|
|
|
let loading = ref(false)
|
|
|
|
//搜索关键字
|
|
|
|
//搜索关键字
|
|
|
@ -128,25 +154,55 @@ let stopWatch = null
|
|
|
|
* 页面初始完成
|
|
|
|
* 页面初始完成
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
onMounted(() => {
|
|
|
|
onMounted(() => {
|
|
|
|
// bar = new PieChart('barEcharts', {
|
|
|
|
startWatching()
|
|
|
|
// title:'图表标题',
|
|
|
|
|
|
|
|
// unit:'元',
|
|
|
|
getMessageInfo()
|
|
|
|
// data: [
|
|
|
|
|
|
|
|
// { value: 1048, name: 'Search Engine' },
|
|
|
|
|
|
|
|
// { value: 735, name: 'Direct' },
|
|
|
|
|
|
|
|
// { value: 580, name: 'Email' },
|
|
|
|
|
|
|
|
// { value: 484, name: 'Union Ads' },
|
|
|
|
|
|
|
|
// { value: 300, name: 'Video Ads' },
|
|
|
|
|
|
|
|
// { value: 200, name: 'qq Ads' },
|
|
|
|
|
|
|
|
// { value: 100, name: 'vx Ads' }
|
|
|
|
|
|
|
|
// ]
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 获取聊天详情
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
const getMessageInfo = async () => {
|
|
|
|
|
|
|
|
const id = checkLastPartIsTimestamp(route.path)
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const res = await historyMessageRoomById(id)
|
|
|
|
|
|
|
|
if (res.code == 200 && res.data) {
|
|
|
|
|
|
|
|
res.data.content = JSON.parse(res.data.content)
|
|
|
|
|
|
|
|
useMessageRoom.resetList(res.data)
|
|
|
|
|
|
|
|
res.data.content.map((item, index) => {
|
|
|
|
|
|
|
|
messageList.push(item)
|
|
|
|
|
|
|
|
initEcharts(item, index)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
console.log(res.data)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
messageDialog.error('获取聊天室记录失败!')
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const checkLastPartIsTimestamp = str => {
|
|
|
|
|
|
|
|
// 找到最后一个 / 的位置
|
|
|
|
|
|
|
|
const lastSlashIndex = str.lastIndexOf('/')
|
|
|
|
|
|
|
|
if (lastSlashIndex === -1) {
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 截取最后一个 / 后面的值
|
|
|
|
|
|
|
|
const lastPart = str.slice(lastSlashIndex + 1)
|
|
|
|
|
|
|
|
return lastPart
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 问答
|
|
|
|
* 问答
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
const handleSend = async () => {
|
|
|
|
const handleSend = async () => {
|
|
|
|
|
|
|
|
if (!keyWord.value.trim()) {
|
|
|
|
|
|
|
|
messageDialog.warning('请先输入需要统计的数据!')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (useMessageRoom.messageRoom.content.length >= 35) {
|
|
|
|
|
|
|
|
messageDialog.warning('每个聊天室上限问题为15条!')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
loading.value = true
|
|
|
|
loading.value = true
|
|
|
|
//存储用户回答
|
|
|
|
//存储用户回答
|
|
|
|
setMessageItem({
|
|
|
|
setMessageItem({
|
|
|
@ -156,7 +212,8 @@ const handleSend = async () => {
|
|
|
|
add: true
|
|
|
|
add: true
|
|
|
|
})
|
|
|
|
})
|
|
|
|
//先存储AI回答,作为交互提示,接口响应后再做更新
|
|
|
|
//先存储AI回答,作为交互提示,接口响应后再做更新
|
|
|
|
setMessageItem({
|
|
|
|
setMessageItem(
|
|
|
|
|
|
|
|
{
|
|
|
|
from: 'ai',
|
|
|
|
from: 'ai',
|
|
|
|
text: '',
|
|
|
|
text: '',
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss'),
|
|
|
@ -166,7 +223,9 @@ const handleSend = async () => {
|
|
|
|
chartType: null,
|
|
|
|
chartType: null,
|
|
|
|
xData: [],
|
|
|
|
xData: [],
|
|
|
|
yData: []
|
|
|
|
yData: []
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
false
|
|
|
|
|
|
|
|
)
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const res = await getAiMsg({ prompt: keyWord.value })
|
|
|
|
const res = await getAiMsg({ prompt: keyWord.value })
|
|
|
|
if (res.type) {
|
|
|
|
if (res.type) {
|
|
|
@ -184,6 +243,7 @@ const handleSend = async () => {
|
|
|
|
title: res.title,
|
|
|
|
title: res.title,
|
|
|
|
unit: res.unit
|
|
|
|
unit: res.unit
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
nextTick(() => {
|
|
|
|
const itemData = messageList[lastIndex.value]
|
|
|
|
const itemData = messageList[lastIndex.value]
|
|
|
|
//饼图
|
|
|
|
//饼图
|
|
|
@ -228,14 +288,53 @@ const handleSend = async () => {
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 同意渲染图表
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
const initEcharts = (item, index) => {
|
|
|
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
|
|
|
//饼图
|
|
|
|
|
|
|
|
if (item.chartType === 'pie') {
|
|
|
|
|
|
|
|
item.chartInstanceItem = new PieChart(`${item.chartType}${index}`, {
|
|
|
|
|
|
|
|
title: item.title,
|
|
|
|
|
|
|
|
unit: item.unit,
|
|
|
|
|
|
|
|
xData: item.xData,
|
|
|
|
|
|
|
|
data: item.yData
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} else if (item.chartType === 'bar') {
|
|
|
|
|
|
|
|
item.chartInstanceItem = new BarChart(`${item.chartType}${index}`, {
|
|
|
|
|
|
|
|
title: item.title,
|
|
|
|
|
|
|
|
unit: item.unit,
|
|
|
|
|
|
|
|
xData: item.xData,
|
|
|
|
|
|
|
|
data: item.yData
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} else if (item.chartType === 'line') {
|
|
|
|
|
|
|
|
item.chartInstanceItem = new LineChart(`${item.chartType}${index}`, {
|
|
|
|
|
|
|
|
title: item.title,
|
|
|
|
|
|
|
|
unit: item.unit,
|
|
|
|
|
|
|
|
xData: item.xData,
|
|
|
|
|
|
|
|
data: item.yData
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 存储聊天室数据
|
|
|
|
* 存储聊天室数据
|
|
|
|
* @param obj
|
|
|
|
* @param obj
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
const setMessageItem = obj => {
|
|
|
|
const setMessageItem = (obj, set = true) => {
|
|
|
|
messageList.push(obj)
|
|
|
|
messageList.push(obj)
|
|
|
|
lastIndex.value = messageList.length - 1
|
|
|
|
lastIndex.value = messageList.length - 1
|
|
|
|
|
|
|
|
if (set) {
|
|
|
|
|
|
|
|
useMessageRoom.setMessage({
|
|
|
|
|
|
|
|
from: obj.from,
|
|
|
|
|
|
|
|
text: obj.text,
|
|
|
|
|
|
|
|
time: obj.time,
|
|
|
|
|
|
|
|
add: true
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -246,6 +345,19 @@ const updataMessageItem = data => {
|
|
|
|
messageList[lastIndex.value] = data
|
|
|
|
messageList[lastIndex.value] = data
|
|
|
|
keyWord.value = ''
|
|
|
|
keyWord.value = ''
|
|
|
|
loading.value = false
|
|
|
|
loading.value = false
|
|
|
|
|
|
|
|
useMessageRoom.setMessage({
|
|
|
|
|
|
|
|
from: data.from,
|
|
|
|
|
|
|
|
text: data.text,
|
|
|
|
|
|
|
|
chartType: data.chartType,
|
|
|
|
|
|
|
|
loading: false, //ai思考中
|
|
|
|
|
|
|
|
time: data.time,
|
|
|
|
|
|
|
|
chartInstanceItem: data.chartInstanceItem,
|
|
|
|
|
|
|
|
chartInstanceActiveIndex: 0,
|
|
|
|
|
|
|
|
xData: data.xData,
|
|
|
|
|
|
|
|
yData: data.yData,
|
|
|
|
|
|
|
|
title: data.title,
|
|
|
|
|
|
|
|
unit: data.unit
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -256,10 +368,25 @@ const handlerTheme = (item, index) => {
|
|
|
|
pauseWatching()
|
|
|
|
pauseWatching()
|
|
|
|
item.chartInstanceActiveIndex = index
|
|
|
|
item.chartInstanceActiveIndex = index
|
|
|
|
item.chartInstanceItem.changeColorStyle(index)
|
|
|
|
item.chartInstanceItem.changeColorStyle(index)
|
|
|
|
setTimeout(()=>{
|
|
|
|
setTimeout(() => {
|
|
|
|
startWatching()
|
|
|
|
startWatching()
|
|
|
|
},1000)
|
|
|
|
}, 1000)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 下载AI回答为图片
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
const uploadImage = index => {
|
|
|
|
|
|
|
|
// 导出图片
|
|
|
|
|
|
|
|
const range = document.getElementById(`box${index}`)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 隐藏边距线
|
|
|
|
|
|
|
|
if (!range) {
|
|
|
|
|
|
|
|
window['$message'].error('下载失败!')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
canvasCut(range)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 聊天室自动滚动条下拉
|
|
|
|
// 聊天室自动滚动条下拉
|
|
|
@ -280,8 +407,14 @@ const pauseWatching = () => {
|
|
|
|
stopWatch = null
|
|
|
|
stopWatch = null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
onMounted(() => {
|
|
|
|
onUnmounted(() => {
|
|
|
|
startWatching()
|
|
|
|
//清除
|
|
|
|
|
|
|
|
messageList.forEach(instance => {
|
|
|
|
|
|
|
|
if (instance.chartType) {
|
|
|
|
|
|
|
|
instance.chartInstanceItem.dispose()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|