CN-257 Entity Explorer--接口对接

This commit is contained in:
hanyuxia
2021-12-31 10:40:37 +08:00
parent da27149185
commit 21018274d5
7 changed files with 288 additions and 19 deletions

View File

@@ -93,7 +93,7 @@
} }
.body__drawing-box { .body__drawing-box {
position: relative; position: relative;
height: 100px; height: 60px;
.chart__loading { .chart__loading {
top: 0; top: 0;
height: 100%; height: 100%;
@@ -102,7 +102,7 @@
.body__drawing { .body__drawing {
position: absolute; position: absolute;
padding: 10px 30px; padding: 10px 30px;
height: 100px; height: 60px;
width: 100%; width: 100%;
} }

View File

@@ -27,7 +27,17 @@ export const api = {
ipThroughput: '/interface/entity/ip/detail/throughput', ipThroughput: '/interface/entity/ip/detail/throughput',
domainThroughput: '/interface/entity/domain/detail/throughput', domainThroughput: '/interface/entity/domain/detail/throughput',
appThroughput: '/interface/entity/app/detail/throughput', appThroughput: '/interface/entity/app/detail/throughput',
filterTop: '/interface/entity/filter/top' filterTop: '/interface/entity/filter/top',
entityTotal: '/interface/entity/index/total',
entityNew: '/interface/entity/index/new',
entityActive: '/interface/entity/index/active',
entityTraffic: '/interface/entity/list/traffic',
entityAlertNum: '/interface/entity/list/alertNum',
entitySecurityNum: '/interface/entity/list/detectionNum',
ipBytes: '/interface/entity/detail/ip/bytes',
domainBytes: '/interface/entity/detail/domain/bytes',
appBytes: '/interface/entity/detail/app/bytes'
} }
/* panel */ /* panel */

View File

@@ -32,57 +32,57 @@
<el-divider direction="vertical"></el-divider> <el-divider direction="vertical"></el-divider>
<div class="entity-overview"> <div class="entity-overview">
<div class="overview-left"> <div class="overview-left">
<span>86</span> <span>{{entityAppTotal}}</span>
<span>APP</span> <span>APP</span>
</div> </div>
<div class="overview-right"> <div class="overview-right">
<div class="right-row"> <div class="right-row">
<i class="cn-icon cn-icon-increase"></i> <i class="cn-icon cn-icon-increase"></i>
<div class="right-label">New</div> <div class="right-label">New</div>
<div class="right-value">51</div> <div class="right-value">{{entityAppNew}}</div>
</div> </div>
<div class="right-row"> <div class="right-row">
<i class="cn-icon cn-icon-active"></i> <i class="cn-icon cn-icon-active"></i>
<div class="right-label">Active</div> <div class="right-label">Active</div>
<div class="right-value">56</div> <div class="right-value">{{entityAppActive}}</div>
</div> </div>
</div> </div>
</div> </div>
<el-divider direction="vertical"></el-divider> <el-divider direction="vertical"></el-divider>
<div class="entity-overview"> <div class="entity-overview">
<div class="overview-left"> <div class="overview-left">
<span>186</span> <span>{{entityDomainTotal}}</span>
<span>DOMAIN</span> <span>DOMAIN</span>
</div> </div>
<div class="overview-right"> <div class="overview-right">
<div class="right-row"> <div class="right-row">
<i class="cn-icon cn-icon-increase"></i> <i class="cn-icon cn-icon-increase"></i>
<div class="right-label">New</div> <div class="right-label">New</div>
<div class="right-value">40</div> <div class="right-value">{{entityDomainNew}}</div>
</div> </div>
<div class="right-row"> <div class="right-row">
<i class="cn-icon cn-icon-active"></i> <i class="cn-icon cn-icon-active"></i>
<div class="right-label">Active</div> <div class="right-label">Active</div>
<div class="right-value">18</div> <div class="right-value">{{entityDomainActive}}</div>
</div> </div>
</div> </div>
</div> </div>
<el-divider direction="vertical"></el-divider> <el-divider direction="vertical"></el-divider>
<div class="entity-overview"> <div class="entity-overview">
<div class="overview-left"> <div class="overview-left">
<span>861</span> <span>{{entityIpTotal}}</span>
<span>IP</span> <span>IP</span>
</div> </div>
<div class="overview-right"> <div class="overview-right">
<div class="right-row"> <div class="right-row">
<i class="cn-icon cn-icon-increase"></i> <i class="cn-icon cn-icon-increase"></i>
<div class="right-label">New</div> <div class="right-label">New</div>
<div class="right-value">99</div> <div class="right-value">{{entityIpNew}}</div>
</div> </div>
<div class="right-row"> <div class="right-row">
<i class="cn-icon cn-icon-active"></i> <i class="cn-icon cn-icon-active"></i>
<div class="right-label">Active</div> <div class="right-label">Active</div>
<div class="right-value">37</div> <div class="right-value">{{entityIpActive}}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -99,6 +99,8 @@ import TimeRefresh from '@/components/common/TimeRange/TimeRefresh'
import EntityFilter from '@/views/entityExplorer/EntityFilter' import EntityFilter from '@/views/entityExplorer/EntityFilter'
import EntityList from '@/views/entityExplorer/entityList/EntityList' import EntityList from '@/views/entityExplorer/entityList/EntityList'
import { entityType, entityFilterType } from '@/utils/constants' import { entityType, entityFilterType } from '@/utils/constants'
import { get } from '@/utils/http'
import { api } from '@/utils/api'
export default { export default {
name: 'entity-explorer', name: 'entity-explorer',
@@ -115,6 +117,18 @@ export default {
listMode: 'list', // entity列表的模式list|block listMode: 'list', // entity列表的模式list|block
timeFilter: {}, timeFilter: {},
entityAppTotal: '-',
entityAppNew: '-',
entityAppActive: '-',
entityDomainTotal: '-',
entityDomainNew: '-',
entityDomainActive: '-',
entityIpTotal: '-',
entityIpNew: '-',
entityIpActive: '-',
filterData: [ filterData: [
{ {
type: 'ip', type: 'ip',
@@ -382,7 +396,62 @@ export default {
}, },
queryList () { queryList () {
},
getEntityIndexData () {
// Total
get(api.entityTotal, { entityType: 'app' }).then(response => {
if (response.code === 200) {
this.entityAppTotal = response.data.result
}
}),
get(api.entityTotal, { entityType: 'domain' }).then(response => {
if (response.code === 200) {
this.entityDomainTotal = response.data.result
}
}),
get(api.entityTotal, { entityType: 'ip' }).then(response => {
if (response.code === 200) {
this.entityIpTotal = response.data.result
}
}),
// New
get(api.entityNew, { entityType: 'app' }).then(response => {
if (response.code === 200) {
this.entityAppNew = response.data.result
}
}),
get(api.entityNew, { entityType: 'domain' }).then(response => {
if (response.code === 200) {
this.entityDomainNew = response.data.result
}
}),
get(api.entityNew, { entityType: 'ip' }).then(response => {
if (response.code === 200) {
this.entityIpNew = response.data.result
}
})
// Active
get(api.entityActive, { entityType: 'app' }).then(response => {
if (response.code === 200) {
this.entityAppActive = response.data.result
}
}),
get(api.entityActive, { entityType: 'domain' }).then(response => {
if (response.code === 200) {
this.entityDomainActive = response.data.result
}
}),
get(api.entityActive, { entityType: 'ip' }).then(response => {
if (response.code === 200) {
this.entityIpActive = response.data.result
}
})
} }
},
mounted () {
this.getEntityIndexData()
} }
} }
</script> </script>

View File

@@ -115,7 +115,7 @@
</div> </div>
<!-- 曲线--> <!-- 曲线-->
<div class="body__drawing-box"> <div class="body__drawing-box">
<div class="body__drawing" :id="`entityListChart${entityData.appId}`"></div> <div class="body__drawing" :id="`entityListChart${entityData.appName}`"></div>
</div> </div>
<div class="body__statics"> <div class="body__statics">
<div class="entity-statics-down"><i class="cn-icon cn-icon-fall entity-statics-icon"></i>{{entityData.bytesReceivedRate || 0}} bps</div> <div class="entity-statics-down"><i class="cn-icon cn-icon-fall entity-statics-icon"></i>{{entityData.bytesReceivedRate || 0}} bps</div>

View File

@@ -11,6 +11,8 @@
<entity-row <entity-row
v-for="(data, index) in listData" v-for="(data, index) in listData"
:entity="data" :entity="data"
:listMode="listMode"
:timeFilter="timeFilter"
:key="index" :key="index"
:ref="`entityRow${index}`" :ref="`entityRow${index}`"
:index="index" :index="index"
@@ -24,6 +26,8 @@
<entity-card <entity-card
v-for="(data, index) in listData" v-for="(data, index) in listData"
:entity="data" :entity="data"
:listMode="listMode"
:timeFilter="timeFilter"
:key="index" :key="index"
></entity-card> ></entity-card>
</div> </div>
@@ -62,7 +66,8 @@ export default {
from: String, from: String,
pageObj: Object, pageObj: Object,
loading: Boolean, loading: Boolean,
listMode: String listMode: String,
timeFilter: Object
}, },
components: { components: {
'entity-card': Card, 'entity-card': Card,

View File

@@ -106,7 +106,8 @@ import DetailOverview from '@/views/entityExplorer/entityList/detailOverview/Det
export default { export default {
name: 'Row', name: 'Row',
props: { props: {
index: Number index: Number,
timeFilter: Object
}, },
components: { components: {
DetailOverview DetailOverview

View File

@@ -1,12 +1,20 @@
import _ from 'lodash' import _ from 'lodash'
import { get } from '@/utils/http'
import { api } from '@/utils/api'
import * as echarts from 'echarts'
import { entityListLineOption } from '@/components/charts/chart-options'
import { unitTypes } from '@/utils/constants'
export default { export default {
props: { props: {
entity: Object entity: Object,
timeFilter: {},
listMode: ''
}, },
data () { data () {
return { return {
entityData: {} entityData: {},
chartOption: null
} }
}, },
computed: { computed: {
@@ -28,6 +36,82 @@ export default {
default: break default: break
} }
return className return className
},
entityName () {
let name
switch (this.entityData.entityType) {
case ('ip'): {
name = this.entity.ip
break
}
case ('domain'): {
name = this.entity.domainName
break
}
case ('app'): {
name = this.entity.appName
break
}
default: break
}
return name
},
queryUrl () {
let url
switch (this.entityData.entityType) {
case ('ip'): {
url = api.ipBytes
break
}
case ('domain'): {
url = api.domainBytes
break
}
case ('app'): {
url = api.appBytes
break
}
default: break
}
return url
},
queryParams () {
let params
const now = new Date()
switch (this.entityData.entityType) {
case ('ip'): {
params = {
queryTimeRange: {
startTime: Math.floor(now.getTime() / 1000 - 3600),
endTime: Math.floor(now.getTime() / 1000)
},
ip: this.entityData.ip
}
break
}
case ('domain'): {
params = {
queryTimeRange: {
startTime: Math.floor(now.getTime() / 1000 - 3600),
endTime: Math.floor(now.getTime() / 1000)
},
domain: this.entityData.domainName
}
break
}
case ('app'): {
params = {
queryTimeRange: {
startTime: Math.floor(now.getTime() / 1000 - 3600),
endTime: Math.floor(now.getTime() / 1000)
},
appName: this.entityData.appName
}
break
}
default: break
}
return params
} }
}, },
methods: { methods: {
@@ -35,13 +119,110 @@ export default {
}, },
queryTraffic () { queryTraffic () {
get(api.entityTraffic, { entityType: this.entityData.entityType, name: this.entityName }).then(response => {
if (response.code === 200) {
response.data.result.forEach(t => {
if (t.name === 'bytes_sent_rate') {
this.entityData.bytesSentRate = t.value
}
if (t.name === 'bytes_received_rate') {
this.entityData.bytesReceivedRate = t.value
}
})
}
})
}, },
querySecurity () { querySecurity () {
get(api.entitySecurityNum, { entityType: this.entityData.entityType, name: this.entityName }).then(response => {
if (response.code === 200) {
this.entityData.securityCount = response.data.result[0].count
}
})
}, },
queryAlert () { queryAlert () {
get(api.entityAlertNum, { entityType: this.entityData.entityType, name: this.entityName }).then(response => {
if (response.code === 200) {
this.entityData.securityCount = response.data.result[0].value
}
})
},
queryTrafficLine () {
let chartOption
this.chartOption = this.$_.cloneDeep(entityListLineOption)
get(this.queryUrl, this.queryParams).then(response => {
if (response.code === 200) {
const seriesTemplate = this.chartOption.series[0]
const series = response.data.result.map((r, i) => {
if (r.legend === 'bytes_sent_rate') {
return {
...seriesTemplate,
name: this.$t('entities.sentThroughput'), // 'bytes_sent_rate',//legendMapping[`ip_${r.legend}`],
data: r.values.map(v => [Number(v[0]), Number(v[1]), unitTypes.byte]),
itemStyle: {
normal: {
color: '#69b072',
lineStyle: {
width: 1.5
}
}
},
smooth: true,
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#f0fff8'
},
{
offset: 1,
color: '#f0fff8'
}
])
}
}
} else if (r.legend === 'bytes_received_rate') {
return {
...seriesTemplate,
name: this.$t('entities.receivedThroughput'), // legendMapping[`ip_${r.legend}`],
data: r.values.map(v => [Number(v[0]), Number(v[1]), unitTypes.byte]),
itemStyle: {
normal: {
color: '#7899c6',
lineStyle: {
width: 1.5
}
}
},
smooth: true,
areaStyle: {
opacity: 0.8,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: '#f0f4ff'
},
{
offset: 1,
color: '#f0f4ff'
}
])
}
}
}
})
chartOption = {
...this.chartOption,
series
}
}
}).finally(() => {
this.$nextTick(() => {
const myChart = echarts.init(document.getElementById(`entityListChart${this.entityName}`))
myChart.setOption(chartOption)
})
})
} }
}, },
mounted () { mounted () {
@@ -49,5 +230,8 @@ export default {
setTimeout(() => { this.queryTraffic() }) setTimeout(() => { this.queryTraffic() })
setTimeout(() => { this.querySecurity() }) setTimeout(() => { this.querySecurity() })
setTimeout(() => { this.queryAlert() }) setTimeout(() => { this.queryAlert() })
if (this.listMode === 'block') {
setTimeout(() => { this.queryTrafficLine() })
}
} }
} }