perf: 优化组件监控组件

This commit is contained in:
“huailei000”
2023-08-09 14:48:59 +08:00
committed by Bryan
parent 03dc3e993c
commit c1543183a2
2 changed files with 232 additions and 74 deletions

View File

@@ -1,59 +1,51 @@
<template>
<div>
<div style="font-size: 24px;font-weight: 300">
<span>{{ componentName }} ( {{ componentMetric.total }} )</span>
</div>
<el-card class="box-card" shadow="never">
<el-row :gutter="10">
<el-col :md="18" :sm="24">
<div style="padding-top: 6px;padding-bottom: 8px;">
<h2 style="text-align: center;font-weight: 350">{{ $t('xpack.LoadStatus') }}</h2>
<div class="progress">
<div
class="progress-bar progress-bar-success"
role="progressbar"
:style="{'width':toPercent(componentMetric.normal) }"
/>
<div
class="progress-bar progress-bar-warning"
role="progressbar"
:style="{'width':toPercent(componentMetric.high) }"
/>
<div
class="progress-bar progress-bar-danger"
role="progressbar"
:style="{'width':toPercent(componentMetric.critical) }"
/>
<div
class="progress-bar progress-bar-offline"
role="progressbar"
:style="{'width':toPercent(componentMetric.offline) }"
/>
<el-col :md="19" :sm="24" style="padding-right: 15px;">
<div>
<div style="text-align: left;font-weight: 350; color: #000000;">
<span class="name">{{ componentName }}</span>
</div>
<div style="display: flex;justify-content: space-around;font-size: 14px;">
<span>
<i class="el-icon-circle-check" style="color: #13CE66;" />
{{ $t('xpack.NormalLoad') }}: {{ componentMetric.normal }}
</span>
<span>
<i class="el-icon-bell" style="color: #E6A23C;" />
{{ $t('xpack.HighLoad') }}: {{ componentMetric.high }}
</span>
<span>
<i class="el-icon-message-solid" style="color: #FF4949;" />
{{ $t('xpack.CriticalLoad') }}: {{ componentMetric.critical }}
</span>
<span>
<i class="el-icon-circle-close" style="color: #bfbaba;" />
{{ $t('xpack.Offline') }}: {{ componentMetric.offline }}
<div class="type">
<span v-for="(item) in componentTypes" :key="item.key">
<i v-if="item.icon" :class="item.icon" :style="{color: item.color}" />
<span style="color: #a3a3a4;">{{ item.name }}</span>
<el-popover
v-if="componentMetric[item.key].length > 0"
width="280"
trigger="hover"
placement="bottom"
popper-class="monitor-popover"
>
<ul>
<li v-for="(i, index) in componentMetric[item.key]" :key="index" @click="routeToList(i)">
{{ i }}
</li>
</ul>
<span slot="reference" class="num">
{{ componentMetric[item.key].length || 0 }}
</span>
</el-popover>
<span v-else>
{{ componentMetric[item.key] instanceof Array ? componentMetric[item.key].length : componentMetric[item.key] }}
</span>
</span>
</div>
<div class="progress" :class="componentMetric.type + '-progress'">
<div style="position: absolute; height: 100%; padding: 2px 0;">
<span v-for="(bar, index) in barArray" :key="index" class="box-bar" />
</div>
</div>
</div>
</el-col>
<el-col :md="6" :sm="24">
<div style="height: 100%;width: 100%;padding-top: 8px;">
<h2 style="text-align: center;font-weight: 350">{{ $t('dashboard.OnlineSessions') }}</h2>
<div style="text-align: center;font-size: 30px;">
<el-col :md="5" :sm="24" style="padding-left: 10px;">
<div class="session">
<div class="session-title" style="">
{{ $t('dashboard.OnlineSessions') }}
</div>
<div style="text-align: center;font-size: 22px;">
<i class="fa fa-comments-o" style="color: #00c360;" />
{{ componentMetric.session_active }}
</div>
</div>
@@ -69,7 +61,6 @@ export default {
name: 'MonitorCard',
components: {},
props: {
// koko/guacamole/omnidb/lion/core
type: {
type: String,
default: 'koko',
@@ -80,6 +71,18 @@ export default {
default: () => ({})
}
},
data() {
return {
resizeObserver: null,
barArray: new Array(77).fill(0).map((item, index) => index + 1),
typeWidths: {
normal: this.toPercent(this.componentMetric.normal),
high: this.toPercent(this.componentMetric.high),
critical: this.toPercent(this.componentMetric.critical),
offline: this.toPercent(this.componentMetric.offline)
}
}
},
computed: {
componentName() {
const nameMapper = {
@@ -98,63 +101,212 @@ export default {
video_worker: 'Video-Worker'
}
return nameMapper[this.componentMetric.type]
},
componentTypes() {
const types = [
{
name: this.$t('dashboard.Total'),
key: 'total',
color: '#13CE66'
},
{
name: this.$t('xpack.NormalLoad'),
key: 'normal',
color: '#13CE66',
icon: 'el-icon-circle-check'
},
{
name: this.$t('xpack.HighLoad'),
key: 'high',
color: '#E6A23C',
icon: 'el-icon-bell'
},
{
name: this.$t('xpack.CriticalLoad'),
key: 'critical',
color: '#FF4949',
icon: 'el-icon-message-solid'
},
{
name: this.$t('xpack.Offline'),
key: 'offline',
color: '#bfbaba',
icon: 'el-icon-circle-close'
}
]
return types
}
},
mounted() {
this.resizeObserver = new ResizeObserver(this.onResize)
this.resizeObserver.observe(document.querySelector('.box-card'))
},
beforeDestroy() {
const el = document.querySelector('.box-card')
if (el) {
this.resizeObserver.unobserve(el)
}
this.resizeObserver = null
},
methods: {
onResize: _.throttle(function() {
this.setBarColor()
}, 50),
setElementsColor(numArray) {
const className = `.${this.componentMetric.type}-progress .box-bar`
const elements = document.querySelectorAll(className)
numArray.reduce((prev, cur) => {
for (let i = prev; i < (cur.num + prev) && i < elements.length; i++) {
elements[i].style.backgroundColor = cur.color
}
return cur.num + prev
}, 0)
},
setBarColor() {
const el = document.querySelector(`.${this.componentMetric.type}-progress`)
if (!el) return
const numArray = []
const { normal, high, critical, offline } = this.typeWidths
const width = _.round(parseFloat(window.getComputedStyle(el).width), 2)
const normalWidth = normal ? width * normal / 100 : normal
const highWidth = high ? width * high / 100 : high
const criticalWidth = critical ? width * critical / 100 : critical
const offlineWidth = offline ? width * offline / 100 : offline
const normalBarNum = _.round(normalWidth / 10)
const highBarNum = _.round(highWidth / 10)
const criticalBarNum = _.round(criticalWidth / 10)
const offlineBarNum = _.round(offlineWidth / 10)
numArray.push(
{
color: '#13CE66',
num: normalBarNum
},
{
color: '#E6A23C',
num: highBarNum
},
{
color: '#FF4949',
num: criticalBarNum
},
{
color: '#bfbaba',
num: offlineBarNum
}
)
this.setElementsColor(numArray)
},
toPercent(num) {
return (Math.round(num / this.componentMetric.total * 10000) / 100.00 + '%')// 小数点后两位百分比
num = num instanceof Array ? num.length : num
return (Math.round(num / this.componentMetric.total * 10000) / 100.00) // 小数点后两位百分比
},
routeToList(name) {
this.$router.replace({
name: 'TerminalSetting',
query: {
activeTab: 'TerminalList',
name: name
}
})
}
}
}
</script>
<style lang="less" scoped>
<style lang="scss">
.el-popover.el-popper.monitor-popover {
ul {
padding-left: 15px;
margin: 0;
li {
line-height: 24px;
color: var(--color-primary);
cursor: pointer;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&:hover {
filter: opacity(65%)!important;
}
}
}
}
</style>
<style lang="less" scoped>
.echarts {
width: 100%;
height: 150px;
}
.name {
display: inline-block;
margin-bottom: 8px;
font-size: 18px;
color: #000000;
}
.el-card ::v-deep .el-card__body {
padding-top: 0;
padding-bottom: 0;
.type {
display: flex;
justify-content: space-between;
font-size: 14px;
margin-bottom: 8px;
.num {
margin-left: 2px;
cursor: pointer;
color: #00c360;
}
}
.progress {
height: 20px;
margin-bottom: 20px;
position: relative;
width: 100%;
height: 24px;
overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
}
.progress-bar-success {
background-color: #13CE66 !important;
}
.progress-bar-warning {
background-color: #E6A23C !important;
}
.progress-bar-danger {
background-color: #FF4949 !important;
}
.progress-bar-offline {
background-color: #bfbaba !important;
}
.progress-bar {
float: left;
width: 0;
height: 100%;
font-size: 12px;
line-height: 20px;
padding: 2px 0;
color: #fff;
text-align: center;
background-color: #337ab7;
-webkit-transition: width .6s ease;
-o-transition: width .6s ease;
transition: width .6s ease;
overflow: hidden;
}
.box-bar {
display: inline-block;
width: 5px !important;
height: 100%;
margin-right: 5px;
border-radius: 4px;
background-color: currentColor;
&:hover {
transform: scale(1.2);
}
&:last-child {
margin-right: 0;
}
}
.session {
margin-top: 13px;
border-left: 1px solid #f3f3f3;
.session-title {
margin-bottom: 8px;
color: #a3a3a4;
text-align: center;
font-weight: 350;
font-size: 14px;
}
}
</style>

View File

@@ -79,6 +79,12 @@ export default {
componentData() {
return {}
}
},
beforeRouteUpdate(to, from, next) {
if (to.name === from.name && to.path === from.path && to.query?.activeTab) {
this.$store.commit('common/reload')
}
next()
}
}
</script>