|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="chat-container">
|
|
|
|
|
<div class="chat-list" ref="scrollContainer">
|
|
|
|
|
<div>
|
|
|
|
|
<!-- <div>
|
|
|
|
|
<div class="echarts-box" id="barEcharts"></div>
|
|
|
|
|
<div class="echatrs-theme">
|
|
|
|
|
<div class="theme-title">风格切换:</div>
|
|
|
|
@ -11,7 +11,9 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div> -->
|
|
|
|
|
|
|
|
|
|
<AiHint></AiHint>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
v-for="(item, index) in messageList"
|
|
|
|
@ -24,10 +26,35 @@
|
|
|
|
|
<div class="message-content">
|
|
|
|
|
<div class="message-time">{{ item.time }}</div>
|
|
|
|
|
<div class="message-text">
|
|
|
|
|
<span>{{ item.text }}</span>
|
|
|
|
|
<div v-if="item.from === 'ai' && item.loading" class="ai-loading">
|
|
|
|
|
<div class="text-ros">
|
|
|
|
|
<span>{{ item.text }}</span>
|
|
|
|
|
<div v-show="item.from === 'user'">
|
|
|
|
|
<n-tooltip placement="bottom" trigger="hover">
|
|
|
|
|
<template #trigger>
|
|
|
|
|
<n-icon size="14" style="cursor: pointer">
|
|
|
|
|
<svg
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
|
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
|
|
|
viewBox="0 0 12 12"
|
|
|
|
|
>
|
|
|
|
|
<g fill="none">
|
|
|
|
|
<path
|
|
|
|
|
d="M6.5 1.75a.75.75 0 0 0-1.5 0V5H1.75a.75.75 0 0 0 0 1.5H5v3.25a.75.75 0 0 0 1.5 0V6.5h3.25a.75.75 0 0 0 0-1.5H6.5V1.75z"
|
|
|
|
|
fill="currentColor"
|
|
|
|
|
></path>
|
|
|
|
|
</g>
|
|
|
|
|
</svg>
|
|
|
|
|
</n-icon>
|
|
|
|
|
</template>
|
|
|
|
|
<span> 添加为常用问题 </span>
|
|
|
|
|
</n-tooltip>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-show="item.from === 'ai' && item.loading" class="ai-loading">
|
|
|
|
|
<span>思考中</span> <n-spin size="small" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="ai-hint" v-show="item.from === 'ai'">(注:本回答由AI生成,内容仅供参考)</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -56,7 +83,8 @@
|
|
|
|
|
import { ref, reactive, onMounted, onUnmounted, watch, nextTick } from 'vue'
|
|
|
|
|
import { getAiMsg } from '@/api/ai.js'
|
|
|
|
|
import moment from 'moment'
|
|
|
|
|
import {LineChart, BarChart ,PieChart} from './class/index'
|
|
|
|
|
import { LineChart, BarChart, PieChart } from './class/index'
|
|
|
|
|
import { AiHint } from '../components'
|
|
|
|
|
import userIcon from '@/assets/images/ai/user-icon.png'
|
|
|
|
|
import aiIcon from '@/assets/images/ai/ai-icon.png'
|
|
|
|
|
//输入框加载
|
|
|
|
@ -70,26 +98,25 @@ let lastIndex = ref(0)
|
|
|
|
|
//主题
|
|
|
|
|
const echartsTheme = ['简约风', '商务风', '科技风']
|
|
|
|
|
|
|
|
|
|
let bar = null
|
|
|
|
|
// let bar = null
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 页面初始完成
|
|
|
|
|
*/
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
bar = new PieChart('barEcharts', {
|
|
|
|
|
title:'图表标题',
|
|
|
|
|
unit:'元',
|
|
|
|
|
|
|
|
|
|
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' }
|
|
|
|
|
]
|
|
|
|
|
})
|
|
|
|
|
// bar = new PieChart('barEcharts', {
|
|
|
|
|
// title:'图表标题',
|
|
|
|
|
// unit:'元',
|
|
|
|
|
// 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' }
|
|
|
|
|
// ]
|
|
|
|
|
// })
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -103,34 +130,34 @@ const handleSend = async () => {
|
|
|
|
|
text: keyWord.value,
|
|
|
|
|
time: moment().format('YYYY/MM/DD HH:mm:ss')
|
|
|
|
|
})
|
|
|
|
|
//先存储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思考中
|
|
|
|
|
// })
|
|
|
|
|
// 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
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 存储聊天室数据
|
|
|
|
@ -161,125 +188,4 @@ const handlerTheme = index => {
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.chat-container {
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding: 20px;
|
|
|
|
|
height: 100%;
|
|
|
|
|
gap: 15px;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
|
|
|
|
.chat-list {
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 25px;
|
|
|
|
|
width: 50%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
// border: 1px solid red;
|
|
|
|
|
|
|
|
|
|
.chat-item {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
}
|
|
|
|
|
.user-icon {
|
|
|
|
|
height: 50px;
|
|
|
|
|
width: 50px;
|
|
|
|
|
}
|
|
|
|
|
.user-message {
|
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
|
.message-content {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.ai-loading {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
.ai-message {
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
.message-content {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.message-content {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
.message-time {
|
|
|
|
|
color: #c3cad9;
|
|
|
|
|
}
|
|
|
|
|
width: calc(100% - 110px);
|
|
|
|
|
padding-top: 15px;
|
|
|
|
|
.message-text {
|
|
|
|
|
width: auto;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
padding: 10px 18px;
|
|
|
|
|
background: #282a31;
|
|
|
|
|
border-radius: 10px 10px 10px 10px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.chat-input {
|
|
|
|
|
width: 50%;
|
|
|
|
|
.chat-suffix {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
height: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
}
|
|
|
|
|
.chat-send {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
width: 46px;
|
|
|
|
|
height: 30px;
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
background: url('@/assets/images/ai/chat-send.png');
|
|
|
|
|
background-size: 100% 100%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.echarts-box {
|
|
|
|
|
height: 220px;
|
|
|
|
|
width: 400px;
|
|
|
|
|
}
|
|
|
|
|
.echatrs-theme {
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 6px;
|
|
|
|
|
.theme-title {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #cfd5e5;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
}
|
|
|
|
|
.theme-list {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
.theme-item {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
background: #31363e;
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #cfd5e5;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding: 2px 10px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
<style lang="scss" scoped></style>
|
|
|
|
|