feat: 完善饼图类的修改主题功能

main
许宏杰 1 month ago
parent e011329313
commit 63b4a53d0c

@ -16,6 +16,7 @@ import * as echarts from 'echarts';
private currentColor: string = '#1890ff'; // 默认颜色
constructor(containerId: string, chartData: ChartData) {
this.dom = document.getElementById(containerId)!;
this.xData = chartData.xData;
this.yData = chartData.yData;

@ -0,0 +1,178 @@
import * as echarts from 'echarts'
interface BarChartOptions {
title?: string
unit?: string
xData: string[]
data: number[]
}
export class BarChart {
private chart: echarts.ECharts | null = null
private dom: HTMLElement
private chartData: any = {}
private styleColor:any = {
backgroundColor: '#30333B',
titleColor: '#fff',
axisLabelColor: '#5C6272',
axisLineColor: '#3F404D',
barColor: '#3071EC',
barValueColor: '#fff'
}
constructor(containerId: string, chartData: BarChartOptions) {
this.dom = document.getElementById(containerId)!
this.chartData = chartData
this.initChart()
}
private initChart(): void {
this.chart = echarts.init(this.dom)
this.setChartOptions()
}
private setChartOptions(): void {
const option = {
backgroundColor: this.styleColor.backgroundColor,
title: {
text: '图表标题',
left: 'center',
top: '3%',
textStyle: {
color: this.styleColor.titleColor,
fontSize: 14
}
},
grid: {
top: '18%',
left: '3%',
right: '3%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: this.chartData.xData,
axisLine: { lineStyle: { color: this.styleColor.axisLineColor, width: 1 } }, //x轴线
axisTick: {
show: false //不显示X轴刻度线
},
axisLabel: {
color: this.styleColor.axisLabelColor,
fontSize: 12
} //x轴标题
},
yAxis: {
type: 'value',
axisLabel: {
color: this.styleColor.axisLabelColor,
fontSize: 12
},
splitLine: {
lineStyle: {
color: this.styleColor.axisLineColor,
opacity: 0.5
}
}
},
series: [
{
type: 'bar',
data: this.chartData.data,
label: {
show: true,
position: 'top',
color: this.styleColor.barValueColor
},
itemStyle: {
color: this.styleColor.barColor
}
}
]
}
this.chart?.setOption(option)
}
/**
* 0- 1- ,2-
* @param index
*/
changeColorStyle(index: number): void {
if (!this.chart) {
console.warn('未读取到元素!')
return
}
if (index === 0) {
this.styleColor = {
backgroundColor: '#30333B',
titleColor: '#fff',
axisLabelColor: '#5C6272',
axisLineColor: '#3F404D',
barColor: '#3071EC',
barValueColor: '#fff'
}
} else if (index === 1) {
this.styleColor = {
backgroundColor: '#FFFFFF',
titleColor: '#333',
axisLabelColor: '#737373',
axisLineColor: '#D9D9D9',
barColor: '#6790EA',
barValueColor: '#333'
}
}else{
this.styleColor = {
backgroundColor: 'rgba(80,122,252,0.1)',
titleColor: '#fff',
axisLabelColor: '#7A8195',
axisLineColor: '#3F404D',
barColor:new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(80, 122, 252, 1)' },
{ offset: 1, color: 'rgba(80, 122, 252, 0)' }
]),
barValueColor: '#fff'
}
}
this.chart.setOption({
backgroundColor: this.styleColor.backgroundColor,
title: {
textStyle: {
color: this.styleColor.titleColor
}
},
xAxis: {
axisLine: { lineStyle: { color: this.styleColor.axisLineColor } }, //x轴线
axisLabel: {
color: this.styleColor.axisLabelColor
} //x轴标题
},
yAxis: {
axisLabel: {
color: this.styleColor.axisLabelColor
},
splitLine: {
lineStyle: {
color: this.styleColor.axisLineColor
}
}
},
series: [
{
label: {
color: this.styleColor.barValueColor
},
itemStyle: {
color: this.styleColor.barColor
}
}
]
})
}
dispose(): void {
if (this.chart) {
this.chart.dispose()
this.chart = null
}
}
}

@ -0,0 +1,4 @@
export { BarChart } from './bar';

@ -0,0 +1,375 @@
<template>
<div class="chat-container">
<div class="chat-list" ref="scrollContainer">
<!-- <div class="echarts-box" id="test"></div>
<div class="echarts-style-row">
<div class="style-row-name">风格切换</div>
<div class="echarts-style-list">
<div class="style-item" v-for="(echartItem, echartIndex) in styleColor" :key="echartIndex">
{{ echartItem }}
</div>
</div>
</div> -->
<div
v-for="(item, index) in messages"
:key="index"
:class="['chat-item', item.from == 'user' ? 'user-message' : 'ai-message']"
>
<!-- 头像 -->
<img :src="item.from == 'user' ? userIcon : aiIcon" class="user-icon" alt="" />
<!-- 内容 -->
<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.chartType">
<div :id="item.chartType + index" class="echarts-box"></div>
<div class="echarts-style-row">
<div class="style-row-name">风格切换</div>
<div class="echarts-style-list">
<div
class="style-item"
@click="hanlderStyleColor(item.chartType, index, echartIndex)"
:class="echartIndex == item.chartInstanceActiveIndex ? 'activeItem' : ''"
v-for="(echartItem, echartIndex) in styleColor"
:key="echartIndex"
>
{{ echartItem }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<n-input
class="chat-input"
round
v-model:value="keyWord"
type="textarea"
placeholder="请输入需要统计的数据"
:autosize="{ minRows: 5 }"
>
<template #suffix>
<div class="chat-suffix">
<span>常用问题</span>
<!-- <img src="~@/assets/images/ai/chat-send.png" class="chat-send" alt="" /> -->
<n-button :loading="loading" size="small" :class="['chat-send']" :bordered="false" @click="handleSend">
</n-button>
</div>
</template>
</n-input>
</div>
</template>
<script setup lang="ts">
import moment from 'moment'
// @ts-ignore
import { getAiMsg } from '@/api/ai.js'
// @ts-ignore
import { AiChatroomType } from './types'
// @ts-ignore
import { PieChart } from './class/PieChart'
// @ts-ignore
import { LineChart } from './class/LineChart'
// @ts-ignore
import { BarChart } from './class/BarChart'
import { ref, reactive, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { historyMessageRoomById } from '@/api/path'
import userIcon from '@/assets/images/ai/user-icon.png'
import aiIcon from '@/assets/images/ai/ai-icon.png'
import { useMessage } from 'naive-ui'
import { useRoute } from 'vue-router'
import useMessageRoomStore from '@/store/modules/messageRoom'
const useMessageRoom = useMessageRoomStore()
let infoData = ref({})
const route = useRoute()
const messageDialog = useMessage()
const scrollContainer = ref<HTMLDivElement | null>(null)
// const chartContainer = ref<HTMLDivElement | null>(null)
let loading = ref(false)
let keyWord = ref('')
let messages= reactive([])
let chartInstance: LineChart | null = null
//
const chartData = {
xData: ['Q1', 'Q2', 'Q3', 'Q4'],
yData: [120, 150, 130, 180],
seriesName: '年度营收', //
color: '#ff6b6b' //
}
const styleColor: string[] = ['简约风', '商务风', '科技风']
const handleSend = async () => {
if (!keyWord.value.trim()) {
messageDialog.warning('请先输入需要统计的数据!')
return
}
/**
*保存用户提问信息
*/
setMessageStore({
from: 'user',
text: keyWord.value,
time: moment().format('YYYY/MM/DD HH:mm:ss')
})
loading.value = true
try {
const res = await getAiMsg({ prompt: keyWord.value })
console.log('回答', res)
//AI
if (res.type) {
setMessageStore({
from: 'ai',
text: '以图表形式展示',
chartType: res.chartType,
time: moment().format('YYYY/MM/DD HH:mm:ss'),
chartInstanceItem: null,
chartInstanceActiveIndex: 0,
xData: res.xData,
yData: res.yData
})
nextTick(() => {
const lastIndex = messages.length - 1
const itemData = messages[lastIndex]
const xData = res.xData
const yData = res.yData.map((str: string) => parseInt(str, 10))
if (itemData.chartType === 'pie')
itemData.chartInstanceItem = new PieChart(`${itemData.chartType}${lastIndex}`, { xData, yData })
if (itemData.chartType === 'line') {
itemData.chartInstanceItem = new LineChart(`${itemData.chartType}${lastIndex}`, { xData, yData })
}
if (itemData.chartType === 'bar') {
itemData.chartInstanceItem = new BarChart(`${itemData.chartType}${lastIndex}`, { xData, yData })
}
})
} else {
//
setMessageStore({
from: 'ai',
text: res,
time: moment().format('YYYY/MM/DD HH:mm:ss')
})
}
keyWord.value = '' //
loading.value = false
} catch (error) {
//
setMessageStore({
from: 'ai',
text: '服务器繁忙,请稍后再试。',
time: moment().format('YYYY/MM/DD HH:mm:ss')
})
keyWord.value = '' //
loading.value = false
}
}
const setMessageStore = (messageItem: any) => {
messages.push(messageItem)
useMessageRoom.setMessage(messages[0].text, {
from: messageItem.from,
text: messageItem.text,
chartType: messageItem.chartType,
time: messageItem.time,
chartInstanceItem: null,
chartInstanceActiveIndex: 0,
xData: messageItem.xData,
yData: messageItem.yData
})
}
const hanlderStyleColor = (type: string, fatherIndex: number, childIndex: number) => {
const messagesItem = messages[fatherIndex]
if (messagesItem.chartInstanceActiveIndex == childIndex) return
messagesItem.chartInstanceActiveIndex = childIndex
messagesItem.chartInstanceItem?.changeColorStyle(childIndex)
}
onMounted(() => {
getInfo()
})
const getInfo = async () => {
const id = checkLastPartIsTimestamp(route.path)
const res = await historyMessageRoomById(id)
if (res?.data) {
res.data.content = JSON.parse(res.data.content)
infoData.value = res.data
// messages = infoData.value.content.list
infoData.value.content.list.forEach(item => {
messages.push(item);
});
}
// console.log(infoData.value.content.list)
}
const checkLastPartIsTimestamp = (str: string) => {
// /
const lastSlashIndex = str.lastIndexOf('/')
if (lastSlashIndex === -1) {
return false
}
// /
const lastPart = str.slice(lastSlashIndex + 1)
return lastPart
}
// messages
watch(
messages,
() => {
nextTick(() => {
if (scrollContainer.value) {
scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight
}
})
},
{ deep: true }
)
onUnmounted(() => {
//
messages.forEach(instance => {
if (instance.chartType) {
instance.chartInstanceItem?.dispose()
}
})
})
</script>
<style lang="scss" scoped>
.chat-container {
box-sizing: border-box;
padding: 20px;
height: 100%;
gap: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.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%;
}
.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: 40px;
width: 40px;
}
.user-message {
flex-direction: row-reverse;
.message-content {
display: flex;
flex-direction: column;
align-items: flex-end;
}
}
.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: 18px;
background: #282a31;
border-radius: 10px 10px 10px 10px;
}
}
::v-deep .n-input .n-input__suffix .n-base-loading {
color: #283e81 !important;
}
/* 设置滚动条整体样式 */
::-webkit-scrollbar {
width: 0px;
}
.echarts-box {
height: 300px;
width: 500px;
// border: 1px solid red;
}
.echarts-style-row {
display: flex;
align-items: center;
.style-row-name {
font-size: 14px;
color: #cfd5e5;
font-weight: 400;
}
.echarts-style-list {
display: flex;
align-items: center;
gap: 10px;
}
.style-item {
cursor: pointer;
font-size: 14px;
color: #cfd5e5;
font-weight: 400;
background: #31363e;
border-radius: 2px 2px 2px 2px;
padding: 3px 10px;
}
.activeItem {
background: rgba(63, 123, 248, 0.1);
color: #3f7bf8;
}
}
</style>

@ -1,17 +1,20 @@
<template>
<div class="chat-container">
<div class="chat-list" ref="scrollContainer">
<!-- <div class="echarts-box" id="test"></div>
<div class="echarts-style-row">
<div class="style-row-name">风格切换</div>
<div class="echarts-style-list">
<div class="style-item" v-for="(echartItem, echartIndex) in styleColor" :key="echartIndex">
{{ echartItem }}
<div>
<div class="echarts-box" id="barEcharts"></div>
<div class="echatrs-theme">
<div class="theme-title">风格切换</div>
<div class="theme-list">
<div class="theme-item" @click="handlerTheme(index)" v-for="(item, index) in echartsTheme" :key="index">
{{ item }}
</div>
</div>
</div>
</div> -->
</div>
<div
v-for="(item, index) in messages"
v-for="(item, index) in messageList"
:key="index"
:class="['chat-item', item.from == 'user' ? 'user-message' : 'ai-message']"
>
@ -22,27 +25,14 @@
<div class="message-time">{{ item.time }}</div>
<div class="message-text">
<span>{{ item.text }}</span>
<div v-if="item.from === 'ai' && item.chartType">
<div :id="item.chartType + index" class="echarts-box"></div>
<div class="echarts-style-row">
<div class="style-row-name">风格切换</div>
<div class="echarts-style-list">
<div
class="style-item"
@click="hanlderStyleColor(item.chartType, index, echartIndex)"
:class="echartIndex == item.chartInstanceActiveIndex ? 'activeItem' : ''"
v-for="(echartItem, echartIndex) in styleColor"
:key="echartIndex"
>
{{ echartItem }}
</div>
</div>
</div>
<div v-if="item.from === 'ai' && item.loading" class="ai-loading">
<span>思考中</span> <n-spin size="small" />
</div>
</div>
</div>
</div>
</div>
<!-- 搜索 -->
<n-input
class="chat-input"
round
@ -54,7 +44,6 @@
<template #suffix>
<div class="chat-suffix">
<span>常用问题</span>
<!-- <img src="~@/assets/images/ai/chat-send.png" class="chat-send" alt="" /> -->
<n-button :loading="loading" size="small" :class="['chat-send']" :bordered="false" @click="handleSend">
</n-button>
</div>
@ -63,187 +52,103 @@
</div>
</template>
<script setup lang="ts">
import moment from 'moment'
// @ts-ignore
import { getAiMsg } from '@/api/ai.js'
// @ts-ignore
import { AiChatroomType } from './types'
// @ts-ignore
import { PieChart } from './class/PieChart.ts'
// @ts-ignore
import { LineChart } from './class/LineChart.ts'
// @ts-ignore
import { BarChart } from './class/BarChart.ts'
<script setup>
import { ref, reactive, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { historyMessageRoomById } from '@/api/path'
import { getAiMsg } from '@/api/ai.js'
import moment from 'moment'
import { BarChart } from './class/index'
import userIcon from '@/assets/images/ai/user-icon.png'
import aiIcon from '@/assets/images/ai/ai-icon.png'
import { useMessage } from 'naive-ui'
import { useRoute } from 'vue-router'
import useMessageRoomStore from '@/store/modules/messageRoom'
const useMessageRoom = useMessageRoomStore()
let infoData = ref({})
const route = useRoute()
const messageDialog = useMessage()
const scrollContainer = ref<HTMLDivElement | null>(null)
// const chartContainer = ref<HTMLDivElement | null>(null)
//
let loading = ref(false)
//
let keyWord = ref('')
let messages= reactive([])
let chartInstance: LineChart | null = null
//list
let messageList = reactive([])
//
let lastIndex = ref(0)
//
const echartsTheme = ['简约风', '商务风', '科技风']
//
const chartData = {
xData: ['Q1', 'Q2', 'Q3', 'Q4'],
yData: [120, 150, 130, 180],
seriesName: '年度营收', //
color: '#ff6b6b' //
}
let bar = null
const styleColor: string[] = ['简约风', '商务风', '科技风']
/**
* 页面初始完成
*/
onMounted(() => {
bar = new BarChart('barEcharts', {
xData: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data: [120, 200, 150, 80, 70, 110, 130]
})
})
/**
* 问答
*/
const handleSend = async () => {
if (!keyWord.value.trim()) {
messageDialog.warning('请先输入需要统计的数据!')
return
}
/**
*保存用户提问信息
*/
setMessageStore({
loading.value = true
//
setMessageItem({
from: 'user',
text: keyWord.value,
time: moment().format('YYYY/MM/DD HH:mm:ss')
})
loading.value = 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 })
console.log('回答', res)
//AI
if (res.type) {
setMessageStore({
from: 'ai',
text: '以图表形式展示',
chartType: res.chartType,
time: moment().format('YYYY/MM/DD HH:mm:ss'),
chartInstanceItem: null,
chartInstanceActiveIndex: 0,
xData: res.xData,
yData: res.yData
})
nextTick(() => {
const lastIndex = messages.length - 1
const itemData = messages[lastIndex]
const xData = res.xData
const yData = res.yData.map((str: string) => parseInt(str, 10))
if (itemData.chartType === 'pie')
itemData.chartInstanceItem = new PieChart(`${itemData.chartType}${lastIndex}`, { xData, yData })
if (itemData.chartType === 'line') {
itemData.chartInstanceItem = new LineChart(`${itemData.chartType}${lastIndex}`, { xData, yData })
}
if (itemData.chartType === 'bar') {
itemData.chartInstanceItem = new BarChart(`${itemData.chartType}${lastIndex}`, { xData, yData })
}
})
console.log('图表形式')
} else {
//
setMessageStore({
//
updataMessageItem({
from: 'ai',
text: res,
time: moment().format('YYYY/MM/DD HH:mm:ss')
time: moment().format('YYYY/MM/DD HH:mm:ss'),
loading: false
})
}
keyWord.value = '' //
loading.value = false
} catch (error) {
//
setMessageStore({
} catch {
updataMessageItem({
from: 'ai',
text: '服务器繁忙,请稍后再试。',
time: moment().format('YYYY/MM/DD HH:mm:ss')
time: moment().format('YYYY/MM/DD HH:mm:ss'),
loading: false
})
keyWord.value = '' //
loading.value = false
}
}
/**
* 存储聊天室数据
* @param obj
*/
const setMessageStore = (messageItem: any) => {
messages.push(messageItem)
useMessageRoom.setMessage(messages[0].text, {
from: messageItem.from,
text: messageItem.text,
chartType: messageItem.chartType,
time: messageItem.time,
chartInstanceItem: null,
chartInstanceActiveIndex: 0,
xData: messageItem.xData,
yData: messageItem.yData
})
}
const hanlderStyleColor = (type: string, fatherIndex: number, childIndex: number) => {
const messagesItem = messages[fatherIndex]
if (messagesItem.chartInstanceActiveIndex == childIndex) return
messagesItem.chartInstanceActiveIndex = childIndex
messagesItem.chartInstanceItem?.changeColorStyle(childIndex)
const setMessageItem = obj => {
messageList.push(obj)
lastIndex.value = messageList.length - 1
}
onMounted(() => {
getInfo()
})
const getInfo = async () => {
const id = checkLastPartIsTimestamp(route.path)
const res = await historyMessageRoomById(id)
if (res?.data) {
res.data.content = JSON.parse(res.data.content)
infoData.value = res.data
// messages = infoData.value.content.list
infoData.value.content.list.forEach(item => {
messages.push(item);
});
}
// console.log(infoData.value.content.list)
/**
* ai回答后更新对应数据
* @param data
*/
const updataMessageItem = data => {
messageList[lastIndex.value] = data
keyWord.value = ''
loading.value = false
}
const checkLastPartIsTimestamp = (str: string) => {
// /
const lastSlashIndex = str.lastIndexOf('/')
if (lastSlashIndex === -1) {
return false
}
// /
const lastPart = str.slice(lastSlashIndex + 1)
return lastPart
/**
* 图表切换主题
* @param index
*/
const handlerTheme = index => {
bar.changeColorStyle(index)
}
// messages
watch(
messages,
() => {
nextTick(() => {
if (scrollContainer.value) {
scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight
}
})
},
{ deep: true }
)
onUnmounted(() => {
//
messages.forEach(instance => {
if (instance.chartType) {
instance.chartInstanceItem?.dispose()
}
})
})
</script>
<style lang="scss" scoped>
@ -251,125 +156,120 @@ onUnmounted(() => {
box-sizing: border-box;
padding: 20px;
height: 100%;
gap: 20px;
gap: 15px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.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%;
}
.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 {
.chat-list {
overflow-y: auto;
display: flex;
flex-direction: column;
align-items: flex-end;
}
}
.ai-message {
flex-direction: row;
.message-content {
display: flex;
flex-direction: column;
align-items: flex-start;
}
}
gap: 25px;
width: 50%;
height: 100%;
// border: 1px solid red;
.message-content {
font-size: 14px;
font-weight: 400;
.message-time {
color: #c3cad9;
.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;
}
}
}
width: calc(100% - 110px);
padding-top: 15px;
.message-text {
width: auto;
color: #ffffff;
font-size: 15px;
margin-top: 10px;
padding: 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%;
}
}
}
::v-deep .n-input .n-input__suffix .n-base-loading {
color: #283e81 !important;
}
/* 设置滚动条整体样式 */
::-webkit-scrollbar {
width: 0px;
}
.echarts-box {
height: 300px;
width: 500px;
// border: 1px solid red;
height: 220px;
width: 400px;
}
.echarts-style-row {
.echatrs-theme {
margin-top: 10px;
display: flex;
align-items: center;
.style-row-name {
gap: 6px;
.theme-title {
font-size: 14px;
color: #cfd5e5;
font-weight: 400;
}
.echarts-style-list {
.theme-list {
display: flex;
align-items: center;
gap: 10px;
}
.style-item {
cursor: pointer;
font-size: 14px;
color: #cfd5e5;
font-weight: 400;
background: #31363e;
border-radius: 2px 2px 2px 2px;
padding: 3px 10px;
}
.activeItem {
background: rgba(63, 123, 248, 0.1);
color: #3f7bf8;
.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>

Loading…
Cancel
Save