369 lines
12 KiB
JavaScript
369 lines
12 KiB
JavaScript
import _ from 'lodash'
|
||
import axios from 'axios'
|
||
import { api } from '@/utils/api'
|
||
import * as echarts from 'echarts'
|
||
import { entityListLineOption } from '@/views/charts/charts/chart-options'
|
||
import { riskLevelMapping, unitTypes } from '@/utils/constants'
|
||
import { getSecond } from '@/utils/date-util'
|
||
import { valueToRangeValue } from '@/utils/unit-convert'
|
||
import { shallowRef } from 'vue'
|
||
import { computeScore } from '@/utils/tools'
|
||
import i18n from '@/i18n'
|
||
|
||
export default {
|
||
props: {
|
||
entity: Object,
|
||
timeFilter: Object,
|
||
listMode: String
|
||
},
|
||
data () {
|
||
return {
|
||
entityData: {},
|
||
trafficUrl: '',
|
||
chartOption: null,
|
||
unitTypes,
|
||
valueToRangeValue,
|
||
echartsArray: [],
|
||
loadingNetworkQuality: false,
|
||
score: '-', // 网络质量评分
|
||
scoreUrl: '', // 网络质量评分url
|
||
eventNum: 0, // 性能事件和安全事件数量之和
|
||
loadingEvent: false, // event的loading
|
||
performanceEventUrl: '', // 性能事件接口url
|
||
securityEventUrl: '', // 安全事件接口url
|
||
performanceScoreData: {},
|
||
scoreDataState: false
|
||
}
|
||
},
|
||
computed: {
|
||
iconClass () {
|
||
let className
|
||
switch (this.entityData.entityType) {
|
||
case ('ip'): {
|
||
className = 'cn-icon cn-icon-ip2'
|
||
break
|
||
}
|
||
case ('domain'): {
|
||
className = 'cn-icon cn-icon-domain2'
|
||
break
|
||
}
|
||
case ('app'): {
|
||
className = 'cn-icon cn-icon-app2'
|
||
break
|
||
}
|
||
case ('subscriber_id'): {
|
||
className = 'cn-icon cn-icon-pedestrian'
|
||
break
|
||
}
|
||
default: break
|
||
}
|
||
return className
|
||
},
|
||
entityType () {
|
||
return this.entity.entityValue
|
||
},
|
||
entityName () {
|
||
return this.entity.entityValue
|
||
},
|
||
appRisk () {
|
||
return function (level) {
|
||
const m = riskLevelMapping.find(mapping => {
|
||
return mapping.value == level
|
||
})
|
||
return (m && m.name) || level
|
||
}
|
||
},
|
||
queryParams () {
|
||
let params
|
||
const now = window.$dayJs.tz().valueOf()
|
||
// eslint-disable-next-line prefer-const
|
||
params = {
|
||
startTime: this.timeFilter.startTime ? getSecond(this.timeFilter.startTime) : Math.floor(now / 1000 - 3600),
|
||
endTime: this.timeFilter.endTime ? getSecond(this.timeFilter.endTime) : Math.floor(now / 1000),
|
||
resource: this.entityData.entityValue
|
||
}
|
||
return params
|
||
},
|
||
scoreBaseState () {
|
||
return this.$store.getters.scoreBaseReady
|
||
},
|
||
scoreDot () {
|
||
const dots = []
|
||
if (this.score === '-') {
|
||
for (let i = 0; i < 6; i++) {
|
||
dots.push({
|
||
class: 'score-dot'
|
||
})
|
||
}
|
||
} else {
|
||
for (let i = 0; i < 6; i++) {
|
||
if (i < this.score) {
|
||
dots.push({
|
||
class: `score-dot ${handleClass(this.score)}`
|
||
})
|
||
} else {
|
||
dots.push({
|
||
class: 'score-dot'
|
||
})
|
||
}
|
||
}
|
||
}
|
||
return dots
|
||
|
||
function handleClass (score) {
|
||
if (score <= 2) {
|
||
return 'score-dot--red'
|
||
} else if (score <= 4) {
|
||
return 'score-dot--yellow'
|
||
} else if (score <= 6) {
|
||
return 'score-dot--green'
|
||
}
|
||
return ''
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
showDetail () {
|
||
const { href } = this.$router.resolve({
|
||
path: '/entity/detail',
|
||
query: {
|
||
entityType: this.entityData.entityType,
|
||
entityName: this.entityData.entityValue,
|
||
range: this.timeFilter.dateRangeValue
|
||
}
|
||
})
|
||
window.open(href, '_blank')
|
||
},
|
||
showGraph () {
|
||
const { href } = this.$router.resolve({
|
||
path: '/entity/graph',
|
||
query: {
|
||
entityType: this.entityData.entityType,
|
||
entityName: this.entityData.entityValue
|
||
}
|
||
})
|
||
window.open(href, '_blank')
|
||
},
|
||
getQueryParams (dateRangeValue) {
|
||
if (dateRangeValue) {
|
||
// range取 config.js 中配置的值
|
||
const endTime = window.$dayJs.tz().valueOf()
|
||
const startTime = endTime - dateRangeValue * 60 * 1000
|
||
return {
|
||
startTime: getSecond(startTime),
|
||
endTime: getSecond(endTime),
|
||
resource: this.entityType
|
||
}
|
||
} else {
|
||
return {
|
||
startTime: getSecond(this.timeFilter.startTime),
|
||
endTime: getSecond(this.timeFilter.endTime),
|
||
resource: this.entityType
|
||
}
|
||
}
|
||
},
|
||
queryEntityDetailTraffic () {
|
||
this.loading = true
|
||
axios.get(this.trafficUrl, { params: this.getQueryParams(DEFAULT_TIME_FILTER_RANGE.entity.trafficLine) }).then(response => {
|
||
if (response.status === 200 && response.data.data.result && response.data.data.result.length > 0) {
|
||
let sentSeries
|
||
let receivedSeries
|
||
response.data.data.result.forEach(t => {
|
||
if (t.legend === 'rate') {
|
||
this.entityData.max = t.aggregation.max
|
||
this.entityData.avg = t.aggregation.avg
|
||
this.entityData.p50 = t.aggregation.p50
|
||
this.entityData.p90 = t.aggregation.p90
|
||
} else if (t.legend === 'sentRate') {
|
||
this.entityData.bytesSentRate = t.aggregation.avg
|
||
sentSeries = {
|
||
name: i18n.global.t('entities.sentThroughput'),
|
||
type: 'line',
|
||
legendHoverLink: false,
|
||
itemStyle: {
|
||
lineStyle: {
|
||
width: 1
|
||
}
|
||
},
|
||
color: '#69b072',
|
||
data: _.dropRight(t.values, 2).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.bps]),
|
||
showSymbol: false
|
||
}
|
||
} else if (t.legend === 'receivedRate') {
|
||
this.entityData.bytesReceivedRate = t.aggregation.avg
|
||
receivedSeries = {
|
||
name: i18n.global.t('entities.receivedThroughput'),
|
||
type: 'line',
|
||
legendHoverLink: false,
|
||
itemStyle: {
|
||
lineStyle: {
|
||
width: 1
|
||
}
|
||
},
|
||
color: '#7899c6',
|
||
data: t.values.map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.bps]),
|
||
showSymbol: false
|
||
}
|
||
}
|
||
})
|
||
if (this.listMode === 'block') {
|
||
const chart = echarts.init(document.getElementById(`entityListChart${this.entityName}${this.listMode}`))
|
||
this.echartsArray.push(shallowRef(chart))
|
||
chart.setOption({
|
||
...this.chartOption,
|
||
series: [sentSeries, receivedSeries]
|
||
})
|
||
} else if (this.listMode === 'list') {
|
||
const sentChart = echarts.init(document.getElementById(`entityDetailSend${this.entityName}${this.listMode}`))
|
||
const receivedChart = echarts.init(document.getElementById(`entityDetailReceived${this.entityName}${this.listMode}`))
|
||
this.echartsArray.push(shallowRef(sentChart), shallowRef(receivedChart))
|
||
sentChart.setOption({
|
||
...this.chartOption,
|
||
series: [sentSeries]
|
||
})
|
||
receivedChart.setOption({
|
||
...this.chartOption,
|
||
series: [receivedSeries]
|
||
})
|
||
}
|
||
this.loading = false
|
||
} else {
|
||
this.loading = false
|
||
}
|
||
}).finally(() => {
|
||
setTimeout(() => {
|
||
try {
|
||
this.$nextTick(() => {
|
||
this.sentChart && this.sentChart.resize()
|
||
this.receivedChart && this.receivedChart.resize()
|
||
})
|
||
} catch (e) {}
|
||
}, 250)
|
||
})
|
||
},
|
||
resize () {
|
||
this.echartsArray.forEach(item => { item.value.resize() })
|
||
},
|
||
initUrl () {
|
||
if (this.entity.entityType) {
|
||
switch (this.entity.entityType) {
|
||
case 'ip': {
|
||
this.scoreUrl = api.entity.entityList.ipPerformance
|
||
this.trafficUrl = api.entity.entityList.ipThroughput
|
||
this.securityEventUrl = api.entity.entityList.ipSecurity
|
||
this.performanceEventUrl = api.entity.entityList.ipEventPerformance
|
||
break
|
||
}
|
||
case 'domain': {
|
||
this.scoreUrl = api.entity.entityList.domainPerformance
|
||
this.trafficUrl = api.entity.entityList.domainThroughput
|
||
this.securityEventUrl = api.entity.entityList.domainSecurity
|
||
this.performanceEventUrl = api.entity.entityList.domainEventPerformance
|
||
break
|
||
}
|
||
case 'app': {
|
||
this.scoreUrl = api.entity.entityList.appPerformance
|
||
this.trafficUrl = api.entity.entityList.appThroughput
|
||
this.securityEventUrl = api.entity.entityList.appSecurity
|
||
this.performanceEventUrl = api.entity.entityList.appEventPerformance
|
||
break
|
||
}
|
||
case 'subscriber_id': {
|
||
this.trafficUrl = api.entity.entityList.subscriberThroughput
|
||
break
|
||
}
|
||
default:
|
||
break
|
||
}
|
||
}
|
||
},
|
||
/** 获取网络评分 */
|
||
queryNetworkQuantity () {
|
||
this.loadingNetworkQuality = true
|
||
this.performanceScoreData = {}
|
||
this.scoreDataState = false
|
||
axios.get(this.scoreUrl, { params: this.getQueryParams(DEFAULT_TIME_FILTER_RANGE.entity.trafficLine) }).then(response => {
|
||
if (response.status === 200) {
|
||
this.performanceScoreData = {
|
||
establishLatencyMs: _.get(response, 'data.data.result.establishLatencyMsAvg', null),
|
||
httpResponseLatency: _.get(response, 'data.data.result.httpResponseLatencyAvg', null),
|
||
sslConLatency: _.get(response, 'data.data.result.sslConLatencyAvg', null),
|
||
tcpLostlenPercent: _.get(response, 'data.data.result.tcpLostlenPercentAvg', null),
|
||
pktRetransPercent: _.get(response, 'data.data.result.pktRetransPercentAvg', null)
|
||
}
|
||
}
|
||
}).finally(() => {
|
||
this.loadingNetworkQuality = false
|
||
this.scoreDataState = true
|
||
})
|
||
},
|
||
/** 获取事件数量 */
|
||
queryEventNum () {
|
||
this.loadingEvent = true
|
||
// const performance = axios.get(this.performanceEventUrl, { params: this.getQueryParams() })
|
||
// const security = axios.get(this.securityEventUrl, { params: this.getQueryParams() })
|
||
// performance接口修改,暂时不能访问,故只调用security的,后续加上
|
||
this.eventNum = 0
|
||
const param = {
|
||
params: {
|
||
...this.getQueryParams(),
|
||
pageSize: -1
|
||
}
|
||
}
|
||
axios.get(this.securityEventUrl, param).then(res => {
|
||
if (res.status === 200) {
|
||
this.eventNum = res.data.data.result.length
|
||
}
|
||
}).finally(() => {
|
||
this.loadingEvent = false
|
||
})
|
||
|
||
// Promise.all([performance, security]).then(response => {
|
||
// this.eventNum = response[0].data.data.result.length + response[1].data.data.result.length
|
||
// }).catch(e => {
|
||
// this.eventNum = 0
|
||
// }).finally(() => {
|
||
// this.loadingEvent = false
|
||
// })
|
||
},
|
||
handleScoreData () {
|
||
this.score = computeScore(this.performanceScoreData, this.$store.getters.getScoreBase)
|
||
}
|
||
},
|
||
watch: {
|
||
entityData: {
|
||
deep: true,
|
||
handler (n) {
|
||
this.initUrl()
|
||
}
|
||
},
|
||
scoreBaseState (n) {
|
||
if (n && this.scoreDataState) {
|
||
this.handleScoreData()
|
||
}
|
||
},
|
||
scoreDataState (n) {
|
||
if (n && this.scoreBaseState) {
|
||
this.handleScoreData()
|
||
}
|
||
}
|
||
},
|
||
mounted () {
|
||
this.debounceFunc = this.$_.debounce(this.resize, 200)
|
||
window.addEventListener('resize', this.debounceFunc)
|
||
this.chartOption = _.cloneDeep(entityListLineOption)
|
||
this.entityData = { ...this.entityData, ...this.entity }
|
||
this.initUrl()
|
||
setTimeout(() => {
|
||
this.queryEntityDetailTraffic()
|
||
if (this.entity.entityType !== 'subscriber_id') {
|
||
this.queryNetworkQuantity()
|
||
this.queryEventNum()
|
||
}
|
||
})
|
||
},
|
||
beforeUnmount () {
|
||
window.removeEventListener('resize', this.debounceFunc)
|
||
}
|
||
}
|