refactor(intelligent-agent): 重构智能体概览页面

-移除冗余代码,优化数据结构
- 新增应用类型枚举,统一应用类型数据
- 重构 Echarts 组件,提高图表绘制灵活性和可维护性- 优化智能体列表展示,增加应用类型图标和描述
- 调整页面样式,提升用户体验
This commit is contained in:
陈昱达
2025-05-08 13:09:13 +08:00
parent 0dea699f1f
commit b565c90150
9 changed files with 302 additions and 237 deletions

View File

@@ -30,3 +30,37 @@ export const segmentedModeOptionsMap = [
value: '1'
}
]
// 应用类型
export const agentType = [
{
label: '聊天助手',
value: 'chat',
icon: 'chat',
desc: '简单配置即可构建基于 LLM 的对话机器人'
},
{
label: 'Agent',
value: 'agent-chat',
icon: 'agent-chat',
desc: '具备推理与自主工具调用的智能助手'
},
{
label: '文本生成应用',
value: 'completion',
icon: 'completion',
desc: '用于文本生成任务的 AI 助手'
},
{
label: 'Chatflow',
value: 'advanced-chat',
icon: 'advanced-chat',
desc: '支持记忆的复杂多轮对话工作流'
},
{
label: '工作流',
value: 'workflow',
icon: 'workflow',
desc: '面向单轮自动化任务的编排工作流'
}
]

View File

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 637 B

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -30,8 +30,7 @@ for (let item in generatedComponents) {
import '@/icons' // icon
import '@/assets/js/utils/permission' // permission control
import * as echarts from 'echarts'
// 引入柱状图图表,图表后缀都为 Chart
import { LineChart } from 'echarts/charts'
// 引入标题,提示框,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
TitleComponent,
@@ -52,7 +51,7 @@ echarts.use([
GridComponent,
DatasetComponent,
TransformComponent,
LineChart,
// LineChart,
LabelLayout,
UniversalTransition,
CanvasRenderer

View File

@@ -1,61 +0,0 @@
<template>
<div style="background: #f0f4fa;border-radius: 8px" class="mv10 p10">
<div :id="echartsId" style="width: 100%;height: 100%"></div>
</div>
</template>
<script>
// import * as echarts from 'echarts'
import uuid from 'uuid'
export default {
name: 'overveiw',
data() {
return {
echartsId: 'main-' + uuid()
}
},
props: {
options: {
type: Object,
default: () => {
return {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
areaStyle: {}
}
]
}
},
required: true
}
},
watch: {},
components: {},
filters: {},
methods: {
drawEcharts() {
let myChart = this.$echarts.init(document.getElementById(this.echartsId))
let option = {
...this.options
}
myChart.setOption(option)
}
},
created() {},
mounted() {
this.drawEcharts()
},
computed: {}
}
</script>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,139 @@
<template>
<div style="background: #f0f4fa;border-radius: 8px" class="mv10 p10">
<div :id="echartsId" style="width: 100%;height: 100%"></div>
</div>
</template>
<script>
import uuid from 'uuid'
export default {
name: 'overveiw',
data() {
return {
echartsId: 'main-' + uuid()
}
},
props: {
options: {
type: Object,
default: () => {
return {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
areaStyle: {}
}
]
}
},
required: true
}
},
watch: {},
components: {},
filters: {},
methods: {
// 设置网格线
echartsSetGrid() {
return {
left: '10%',
right: '10%',
bottom: '10%',
top: '20%',
backgroundColor: '#f9f9f9', // 设置网格背景色
borderWidth: 1 // 可选:去掉边框
}
},
// 设置tooltip
echartsSetTooltip() {
return {
trigger: 'axis',
backgroundColor: 'rgba(255,255,255,0.9)',
borderColor: '#ccc',
textStyle: {
color: '#333'
},
formatter: params => {
return (
`${params[0].axisValue} ${params[0].marker}<br/>` +
params.map(p => `${p.seriesName}${p.value}`).join('<br/>')
)
}
}
},
// 设置渐变色
echartsSetSeriesColor(colors) {
// 魔改了 areaStyle 如果是一个list [{offset:'1',color:'#AAA'}] 就获取 [0].color 如果list包含两个 就是渐变色 如果color 单纯为一个颜色 就直接渲染颜色
if (!colors) {
return ''
}
if (colors.length > 1 && colors[0].color) {
return new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, colors)
}
return colors[0].color ? colors[0].color : colors
},
// 显示纵向网格线(默认是显示的)
echartsSetXAxisLine() {
return {
show: true, // 显示纵向网格线(默认是显示的)
lineStyle: {
width: 1,
type: 'slide' // 可选:虚线
}
}
},
// 画图
drawEcharts() {
let myChart = this.$echarts.init(document.getElementById(this.echartsId))
console.log(this.options)
let option = {
...this.options,
title: {
...this.options.title,
textStyle: {
fontSize: 13
}
},
xAxis: {
...this.options.xAxis,
type: 'category',
splitLine: this.echartsSetXAxisLine()
},
yAxis: {
type: 'value',
...this.options.yAxis
},
tooltip: this.echartsSetTooltip(),
grid: this.echartsSetGrid(),
series: this.options.series.map(item => {
return {
...item,
areaStyle: {
color:
item.areaStyle && item.areaStyle.color
? this.echartsSetSeriesColor(item.areaStyle.color)
: null
},
type: 'line'
}
})
}
myChart.setOption(option)
}
},
created() {},
mounted() {
this.drawEcharts()
},
computed: {}
}
</script>
<style scoped lang="scss"></style>

View File

@@ -16,19 +16,17 @@
class="flex align-items-c justify-content-b mt10"
style="flex-wrap: wrap"
>
<REcharts
:key="item.options.title.subtext"
v-for="item in list"
<line-echarts
:key="item.options.title.subtext + index"
v-for="(item, index) in list"
:options="item.options"
style="width: calc(50% - 10px);height: 300px"
></REcharts>
></line-echarts>
</div>
</div>
</template>
<script>
import REcharts from '@/views/intelligent-agent/children/Logs&overview/components/echarts.vue'
import * as echarts from 'echarts'
import LineEcharts from '@/views/intelligent-agent/children/Logs&overview/components/lineEcharts.vue'
import { dailyConversations } from './API'
export default {
@@ -40,37 +38,28 @@ export default {
{
options: {
title: {
seriesName: '全部会话数', // 系列名称
text: '全部会话数',
textStyle: {
fontSize: 13
},
subtext: '所有时间'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: '会话数',
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
itemStyle: {
color: '#0694A2'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#0694A2'
},
color: [
{ offset: 0, color: '#0694A2' },
{
offset: 1,
color: '#F3F9FA'
}
])
]
}
}
]
@@ -80,36 +69,23 @@ export default {
options: {
title: {
text: '活跃用户数',
textStyle: {
fontSize: 13
},
subtext: '所有时间'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [820, 932, 901, 934, 1290, 430, 5556],
type: 'line',
name: '活跃用户',
data: [820, 932, 901, 934, 1290, 430, 9000],
itemStyle: {
color: '#FF8A4C'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#FF8A4C'
},
{
offset: 1,
color: '#FFF6F1'
}
])
color: [
{ offset: 0, color: '#FF8A4C' },
{ offset: 1, color: '#FFF6F1' }
]
}
}
]
@@ -119,36 +95,23 @@ export default {
options: {
title: {
text: '平均会话互动数',
textStyle: {
fontSize: 13
},
subtext: '所有时间'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: '平均会话互动数',
data: [20, 52, 1, 55, 666, 1330, 55],
type: 'line',
itemStyle: {
color: '#FF8A4C'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#FF8A4C'
},
{
offset: 1,
color: '#FFF6F1'
}
])
color: [
{ offset: 0, color: '#FF8A4C' },
{ offset: 1, color: '#FFF6F1' }
]
}
}
]
@@ -158,36 +121,23 @@ export default {
options: {
title: {
text: 'Token 输出速度',
textStyle: {
fontSize: 13
},
subtext: '所有时间'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: 'Token 输出速度',
data: [300, 555, 444, 22, 11, 333, 1],
type: 'line',
itemStyle: {
color: '#FF8A4C'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#FF8A4C'
},
{
offset: 1,
color: '#FFF6F1'
}
])
color: [
{ offset: 0, color: '#FF8A4C' },
{ offset: 1, color: '#FFF6F1' }
]
}
}
]
@@ -197,36 +147,23 @@ export default {
options: {
title: {
text: '用户满意度',
textStyle: {
fontSize: 13
},
subtext: '所有时间'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: '用户满意度',
data: [200, 300, 400, 444, 500, 555, 521],
type: 'line',
itemStyle: {
color: '#1C64F1'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#1C64F1'
},
{
offset: 1,
color: '#E3ECFD'
}
])
color: [
{ offset: 0, color: '#1C64F1' },
{ offset: 1, color: '#E3ECFD' }
]
}
}
]
@@ -236,36 +173,24 @@ export default {
options: {
title: {
text: '费用消耗',
textStyle: {
fontSize: 13
},
subtext: '所有时间'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
name: '费用消耗',
data: [820, 932, 901, 934, 1290, 200, 500],
type: 'line',
itemStyle: {
color: '#FF8A4C'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#FF8A4C'
},
{
offset: 1,
color: '#FFF6F1'
}
])
color: [
{ offset: 0, color: '#FF8A4C' },
{ offset: 1, color: '#FFF6F1' }
]
}
}
]
@@ -315,7 +240,7 @@ export default {
props: {},
watch: {},
components: {
REcharts
LineEcharts
},
filters: {},
methods: {
@@ -324,6 +249,22 @@ export default {
this.list = this.list.map(item => {
return {
options: {
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(255,255,255,0.9)',
borderColor: '#ccc',
textStyle: {
color: '#333'
},
formatter: params => {
console.log(params)
return (
`${params[0].axisValue} ${params[0].marker}<br/>` +
params.map(p => `${p.seriesName}${p.value}`).join('<br/>')
)
}
},
...item.options,
title: {
...item.options.title,

View File

@@ -3,6 +3,7 @@ import { agentEdit, agentAdd } from '@/api/intelligent-agent/list'
import { VEmojiPicker } from 'v-emoji-picker'
import cropper from '@/components/RenderCropper/components/cropper.vue'
import { uploadImage } from '@/api/generatedApi'
import { agentType } from '@/assets/js/utils/utilOptions'
export default {
name: 'info',
inject: ['dialog', 'fetchAgentList', 'resetList'],
@@ -35,38 +36,7 @@ export default {
'#ffe4e8'
],
// 应用类型
agentType: [
{
label: '聊天助手',
value: 'chat',
icon: 'chat',
desc: '简单配置即可构建基于 LLM 的对话机器人'
},
{
label: 'Agent',
value: 'agent-chat',
icon: 'agentChat',
desc: '具备推理与自主工具调用的智能助手'
},
{
label: '文本生成应用',
value: 'completion',
icon: 'completion',
desc: '用于文本生成任务的 AI 助手'
},
{
label: 'Chatflow',
value: 'advanced-chat',
icon: 'advancedChat',
desc: '支持记忆的复杂多轮对话工作流'
},
{
label: '工作流',
value: 'workflow',
icon: 'workflow',
desc: '面向单轮自动化任务的编排工作流'
}
],
agentType,
rules: {
appName: [
{ required: true, message: '请输入智能体名称', trigger: 'blur' }

View File

@@ -7,7 +7,7 @@ import {
} from '@/api/intelligent-agent/list'
import Info from '@/views/intelligent-agent/components/info'
import agent from '@/views/agent'
import { agentType } from '@/assets/js/utils/utilOptions'
export default {
name: 'intelligent-agent',
components: {
@@ -30,7 +30,7 @@ export default {
handleSearch: async () => {
this.page = 1
this.list = []
this.fetchAgentList({ nameLike: this.searchOption.nameLike })
await this.fetchAgentList({ nameLike: this.searchOption.nameLike })
}
},
/**
@@ -59,6 +59,10 @@ export default {
}
},
methods: {
findAppTypeLabel(item) {
return agentType.find(it => it.value === item).label
},
resetList() {
this.list = []
this.page = 0
@@ -244,19 +248,41 @@ export default {
<div v-else>
{{ listItem.image ? listItem.image : listItem.appName[0] }}
</div>
<!--listItem.name.获取字符串第一个-->
</div>
<div>
<svg-icon
:icon-class="listItem.appType"
class-name="appType"
:style="{
background: listItem.backgroundColor ? '#fff' : '#fff'
}"
></svg-icon>
</div>
</div>
<div class="dataset-body" style="flex:1">
<h4 class="dataset-title">{{ listItem.appName }}</h4>
<p class="dataset-desc">{{ listItem.description }}</p>
<div class="mt10">
<span class="theme-primary-desc-text-drank fs12 mt20 tag">
{{ findAppTypeLabel(listItem.appType) }}
</span>
<span
class="tag ml10 theme-primary-desc-text-drank fs12 mt10 fw500"
>
User{{ listItem.createdUser }}
</span>
</div>
</div>
</div>
<div class="grid grid-cols-2 mh20 mv10">
<div class="theme-primary-desc-text-drank fs12">
<p>创建者{{ listItem.createdUser }}</p>
</div>
<div class="mh20 mv15 flex justify-content-b">
<p
class="dataset-desc theme-primary-desc-text-drank fs13"
style="line-height:25px;height:20px"
>
{{ listItem.description }}
</p>
</div>
<div
class="opacity-button flex align-items-c mh20 mb10"
@@ -318,6 +344,7 @@ export default {
</template>
<style scoped lang="scss">
@import '@/assets/sass/renderSass/theme.scss';
#index-container {
background-image: url('../../assets/images/backimage.png');
background-size: 600px 300px;
@@ -376,7 +403,7 @@ export default {
& .folder-content {
text-align: center;
border-radius: 8px;
position: relative;
& .folder {
width: 50px;
height: 50px;
@@ -388,9 +415,27 @@ export default {
font-weight: 600;
color: #fff;
}
& .appType {
position: absolute;
right: 0;
bottom: -5px;
z-index: 1;
width: 20px;
height: 20px;
padding: 2px;
border-radius: 5px;
color: $--color-primary;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
}
}
.tag {
padding: 4px 8px;
background: #f0f4fa;
border-radius: 5px;
}
.opacity-button {
opacity: 0;
}
@@ -464,27 +509,25 @@ export default {
text-overflow: ellipsis;
max-width: 100%;
}
.dataset-desc {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 13px;
color: #666666;
line-height: 18px;
text-align: left;
font-style: normal;
height: 35px;
margin: 0;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
}
.dataset-desc {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 13px;
color: #666666;
line-height: 18px;
text-align: left;
font-style: normal;
height: 35px;
margin: 0;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.dataset-footer {
margin-top: auto;
display: flex;