fix: 一系列优化和调整:左侧筛选空串处理、下拉增加网络质量和链路、app风险等级映射

This commit is contained in:
chenjinsong
2022-02-13 23:20:24 +08:00
parent cba743199c
commit 7bdcd1c598
19 changed files with 318 additions and 60 deletions

View File

@@ -3,12 +3,12 @@
.chart-list { .chart-list {
.vue-grid-layout > .vue-grid-item { .vue-grid-layout > .vue-grid-item {
.cn-chart { .cn-chart {
.app-detail__related-domain { .app-detail__related-domain {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
height: 100%; height: 100%;
width: 100%; width: 100%;
.related-domain__list { .related-domain__list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 0 0 25%; flex: 0 0 25%;

View File

@@ -34,9 +34,9 @@
} }
} }
.chart-drawing{ /*.chart-drawing{
height: calc(100% - 36px) !important; height: calc(100% - 36px) !important;
} }*/
} }
.cn-chart__body.pie-with-table { .cn-chart__body.pie-with-table {
flex-basis: 40%; flex-basis: 40%;

View File

@@ -14,6 +14,11 @@
.single-value__content { .single-value__content {
.content__data { .content__data {
font-size: 14px; font-size: 14px;
color: #333;
.single-value__unit {
font-size: 14px;
color: #333;
}
} }
.content__title { .content__title {
font-size: 12px; font-size: 12px;

View File

@@ -11,6 +11,12 @@
width: 550px; width: 550px;
height: 350px; height: 350px;
&.overview-map--ip {
height: 300px;
}
&.overview-map--app {
height: 325px;
}
.cn-chart { .cn-chart {
height: 100%; height: 100%;
width: 100%; width: 100%;
@@ -128,11 +134,11 @@
border-radius: 4px; border-radius: 4px;
.tag__value { .tag__value {
padding-right: 5px;
color: #3976CB; color: #3976CB;
font-weight: bold; font-weight: bold;
} }
.tag__desc { .tag__desc {
padding-right: 5px;
color: #3976CB; color: #3976CB;
} }
} }

View File

@@ -36,7 +36,7 @@
<!-- --> <!-- -->
<div class="condition__value"> <div class="condition__value">
<div v-if="meta.value.isEditing"> <div v-if="meta.value.isEditing">
<el-input v-model="meta.value.value" size="mini" @blur="valueBlur(meta)" ref="valueInput"></el-input> <el-input v-model="meta.value.value" size="mini" @blur="valueBlur(meta)" ref="valueInput" @keyup.enter="valueBlur(meta)"></el-input>
</div> </div>
<span v-else @click="valueClick(meta)">{{meta.value.label}}</span> <span v-else @click="valueClick(meta)">{{meta.value.label}}</span>
</div> </div>

View File

@@ -1,5 +1,6 @@
import { GenericSQL, SqlParserVisitor } from 'dt-sql-parser' import { GenericSQL, SqlParserVisitor } from 'dt-sql-parser'
import Meta, { connection, condition, columnType, cloneMeta } from '@/components/advancedSearch/meta/meta' import Meta, { connection, condition, columnType, cloneMeta } from '@/components/advancedSearch/meta/meta'
import { riskLevelMapping } from '@/utils/constants'
import _ from 'lodash' import _ from 'lodash'
// 补全语句,用于解析 // 补全语句,用于解析
const sqlPrev = 'select a from b where ' const sqlPrev = 'select a from b where '
@@ -87,7 +88,7 @@ export default class SqlParser extends SqlParserVisitor {
if (isFullText) { if (isFullText) {
if (meta.meta === condition) { if (meta.meta === condition) {
if (meta.column.type !== columnType.fullText) { if (meta.column.type !== columnType.fullText) {
sql += `${meta.column.name}${meta.operator.value}${meta.value.value} ` sql += `${meta.column.name}${meta.operator.value}${valueHandle(meta.value.value, meta.column.name)} `
} else { } else {
sql += "QUERY('" sql += "QUERY('"
this.columnList.forEach(column => { this.columnList.forEach(column => {
@@ -100,7 +101,7 @@ export default class SqlParser extends SqlParserVisitor {
if (meta.meta === condition) { if (meta.meta === condition) {
sql += (meta.column.name) sql += (meta.column.name)
if (meta.column.type !== columnType.fullText) { if (meta.column.type !== columnType.fullText) {
sql += `${meta.operator.value}${meta.value.value} ` sql += `${meta.operator.value}${valueHandle(meta.value.value, meta.column.name)} `
} else { } else {
sql += ' ' sql += ' '
} }
@@ -275,3 +276,19 @@ function handleInOrLike (value, type) {
handleValue: v handleValue: v
} }
} }
function valueHandle (value, columnName) {
if (value === "'unknown'") {
return "''"
} else {
if (columnName) {
if (columnName === 'app_risk') {
const m = riskLevelMapping.find(mapping => {
return `'${mapping.name}'` === value || `'${mapping.value}'` === value
})
return (m && m.value) || value
}
}
return value
}
}

View File

@@ -9,9 +9,9 @@
:current-row-key="tableNameColumn" :current-row-key="tableNameColumn"
tooltip-effect="light" tooltip-effect="light"
:expand-row-keys="expandRowKeys" :expand-row-keys="expandRowKeys"
:size="'mini'" size="mini"
:height="'100%'"> height="100%">
<el-table-column type="expand" :min-width="'5%'"> <el-table-column type="expand" min-width="5%">
<template #default="props"> <template #default="props">
<div style="position: relative"> <div style="position: relative">
<div class="chart__loading" style="top: 0; height: 100%; z-index: 1;" v-show="loading"> <div class="chart__loading" style="top: 0; height: 100%; z-index: 1;" v-show="loading">
@@ -37,7 +37,7 @@
:prop="item.prop" :prop="item.prop"
#default="{row}"> #default="{row}">
<span v-if="item.prop === 'nameColumn'"> <span v-if="item.prop === 'nameColumn'">
{{ nameColumn === 'domainCategoryName' ? row['categoryName'] :(nameColumn === 'domainReputationLevel'? row['reputationLevel']:(nameColumn==='appCategory'?row['appCategoryName']:row['appRiskLevel']))}} {{ nameColumn === 'domainCategoryName' ? row['categoryName'] :(nameColumn === 'domainReputationLevel'? row['reputationLevel']:(nameColumn==='appCategory'?row['appCategoryName']:appRisk(row['appRiskLevel'])))}}
</span> </span>
<span v-else-if="item.prop === 'tableNameColumn'"> <span v-else-if="item.prop === 'tableNameColumn'">
{{ tableNameColumn === 'appName' ? row['appName'] : row['domain']}} {{ tableNameColumn === 'appName' ? row['appName'] : row['domain']}}
@@ -65,7 +65,7 @@
:prop="item.prop" :prop="item.prop"
#default="{row}"> #default="{row}">
<span v-if="item.prop === 'nameColumn'"> <span v-if="item.prop === 'nameColumn'">
{{ nameColumn === 'domainCategoryName' ? row['categoryName'] :(nameColumn === 'domainReputationLevel'? row['reputationLevel']:(nameColumn==='appCategory'?row['appCategoryName']:row['appRiskLevel']))}} {{ nameColumn === 'domainCategoryName' ? row['categoryName'] :(nameColumn === 'domainReputationLevel'? row['reputationLevel']:(nameColumn==='appCategory'?row['appCategoryName']:appRisk(row['appRiskLevel'])))}}
</span> </span>
<span v-else-if="item.prop === 'tableNameColumn'"> <span v-else-if="item.prop === 'tableNameColumn'">
{{ tableNameColumn === 'appName' ? row['appName'] : row['domain']}} {{ tableNameColumn === 'appName' ? row['appName'] : row['domain']}}
@@ -87,7 +87,7 @@
import unitConvert from '@/utils/unit-convert' import unitConvert from '@/utils/unit-convert'
import { get } from '@/utils/http' import { get } from '@/utils/http'
import { replaceUrlPlaceholder } from '@/utils/tools' import { replaceUrlPlaceholder } from '@/utils/tools'
import { unitTypes } from '@/utils/constants' import { unitTypes, riskLevelMapping } from '@/utils/constants'
export default { export default {
name: 'PieTable', name: 'PieTable',
@@ -119,6 +119,16 @@ export default {
} }
} }
}, },
computed: {
appRisk () {
return function (level) {
const m = riskLevelMapping.find(mapping => {
return mapping.value == level
})
return (m && m.name) || level
}
}
},
data () { data () {
return { return {
nameColumn: '', nameColumn: '',
@@ -133,7 +143,7 @@ export default {
width: '20%' width: '20%'
}, },
{ {
label: this.$t('entities.category'), label: this.$t(this.chartInfo.params.tableTypeColumnLabel),
prop: 'nameColumn', prop: 'nameColumn',
width: '22%' width: '22%'
}, },

View File

@@ -81,9 +81,12 @@ export default {
this.entityTopTenData = data.map(d => { this.entityTopTenData = data.map(d => {
return { return {
...d, ...d,
name: d.name || 'unknown',
percent: (parseFloat(d.count / totalCount) * 100).toFixed(2) percent: (parseFloat(d.count / totalCount) * 100).toFixed(2)
} }
}) })
} else {
this.entityTopTenData = []
} }
}, },
indexMethod (index) { indexMethod (index) {

View File

@@ -42,6 +42,9 @@ export const api = {
// app detail // app detail
entityAppDetailTraffic: '/interface/entity/detail/overview/app/traffic', entityAppDetailTraffic: '/interface/entity/detail/overview/app/traffic',
entityAppDetailRelation: '/interface/entity/detail/overview/app/relation', entityAppDetailRelation: '/interface/entity/detail/overview/app/relation',
entityAppDetailNetworkQuantity: '/interface/entity/detail/overview/app/networkQuantity',
entityAppDetailLinkIn: '/interface/entity/detail/overview/app/linkIn',
entityAppDetailLinkOut: '/interface/entity/detail/overview/app/linkOut',
entityAppDetailAlert: '/interface/entity/detail/overview/app/alert', entityAppDetailAlert: '/interface/entity/detail/overview/app/alert',
entityAppDetailSecurity: '/interface/entity/detail/overview/app/security', entityAppDetailSecurity: '/interface/entity/detail/overview/app/security',
// domain detail // domain detail
@@ -59,6 +62,9 @@ export const api = {
entityDomainDetailTrafficMap: '/interface/entity/detail/domain/trafficMap', entityDomainDetailTrafficMap: '/interface/entity/detail/domain/trafficMap',
entityAppDetailTrafficMap: '/interface/entity/detail/app/trafficMap', entityAppDetailTrafficMap: '/interface/entity/detail/app/trafficMap',
entityIpDetailRelation: '/interface/entity/detail/overview/ip/relation', entityIpDetailRelation: '/interface/entity/detail/overview/ip/relation',
entityIpDetailNetworkQuantity: '/interface/entity/detail/overview/ip/networkQuantity',
entityIpDetailLinkIn: '/interface/entity/detail/overview/ip/linkIn',
entityIpDetailLinkOut: '/interface/entity/detail/overview/ip/linkOut',
entityIpDetailAlert: '/interface/entity/detail/overview/ip/alert', entityIpDetailAlert: '/interface/entity/detail/overview/ip/alert',
entityIpDetailSecurity: '/interface/entity/detail/overview/ip/security' entityIpDetailSecurity: '/interface/entity/detail/overview/ip/security'
} }

View File

@@ -136,7 +136,13 @@ export const chartPieTableTopOptions = [
{ name: 'Packets', value: 'packets' }, { name: 'Packets', value: 'packets' },
{ name: 'Bytes', value: 'bytes' } { name: 'Bytes', value: 'bytes' }
] ]
export const riskLevelMapping = [
{ name: 'Trustworthy', value: 1 },
{ name: 'Low Risk', value: 2 },
{ name: 'Moderate Risk', value: 3 },
{ name: 'Suspicious', value: 4 },
{ name: 'High Risk', value: 5 }
]
export const iso36112 = { export const iso36112 = {
[storageKey.iso36112Capital]: 'data/countriesWithCapital', [storageKey.iso36112Capital]: 'data/countriesWithCapital',
[storageKey.iso36112WorldLow]: 'worldChinaLow', [storageKey.iso36112WorldLow]: 'worldChinaLow',

View File

@@ -19,6 +19,7 @@ import { getUnitType } from '@/utils/unit-convert'
import { replaceUrlPlaceholder } from '@/utils/tools' import { replaceUrlPlaceholder } from '@/utils/tools'
import { get } from '@/utils/http' import { get } from '@/utils/http'
import chartEchartMixin from './chart-echart-mixin' import chartEchartMixin from './chart-echart-mixin'
import { riskLevelMapping } from '@/utils/constants'
export default { export default {
name: 'ChartEchartWithTable', name: 'ChartEchartWithTable',
@@ -38,7 +39,15 @@ export default {
components: { components: {
PieTable PieTable
}, },
mounted () { computed: {
appRisk () {
return function (level) {
const m = riskLevelMapping.find(mapping => {
return mapping.value == level
})
return (m && m.name) || level
}
}
}, },
methods: { methods: {
handleQueryParams (queryParams) { handleQueryParams (queryParams) {
@@ -61,7 +70,7 @@ export default {
} }
return { return {
data: d, data: d,
name: d[chartParams.nameColumn], name: this.appRisk(d[chartParams.nameColumn]),
value: parseInt(d[chartParams.valueColumn]), value: parseInt(d[chartParams.valueColumn]),
unitType: unitType unitType: unitType
} }

View File

@@ -23,7 +23,7 @@
</div> </div>
<div class="content__desc" > <div class="content__desc" >
<span class="desc__label">{{$t('entities.risk')}}:&nbsp;</span> <span class="desc__label">{{$t('entities.risk')}}:&nbsp;</span>
<span>{{entityData.appRisk || '-'}}</span> <span>{{appRisk(entityData.appRisk) || '-'}}</span>
</div> </div>
</template> </template>
</div> </div>

View File

@@ -49,17 +49,17 @@
<div class="basic-info__item"> <div class="basic-info__item">
<i class="cn-icon cn-icon-id"></i> <i class="cn-icon cn-icon-id"></i>
<span>{{$t('entities.category')}}&nbsp;:&nbsp;&nbsp;</span> <span>{{$t('entities.category')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{entityData.appId || '-'}}</span> <span>{{entityData.appCategory || '-'}}</span>
</div> </div>
<div class="basic-info__item"> <div class="basic-info__item">
<i class="cn-icon cn-icon-category"></i> <i class="cn-icon cn-icon-category"></i>
<span>{{$t('entities.subcategory')}}&nbsp;:&nbsp;&nbsp;</span> <span>{{$t('entities.subcategory')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{entityData.appCategory || '-'}}</span> <span>{{entityData.appSubategory || '-'}}</span>
</div> </div>
<div class="basic-info__item"> <div class="basic-info__item">
<i class="cn-icon cn-icon-sub-category"></i> <i class="cn-icon cn-icon-sub-category"></i>
<span>{{$t('entities.risk')}}&nbsp;:&nbsp;&nbsp;</span> <span>{{$t('entities.risk')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{entityData.appSubategory || '-'}}</span> <span>{{appRisk(entityData.appRisk) || '-'}}</span>
</div> </div>
</template> </template>
<!-- 通用字段 --> <!-- 通用字段 -->

View File

@@ -63,6 +63,35 @@
</div> </div>
</div> </div>
</div> </div>
<div class="overview-item">
<div class="overview__title">{{$t('overall.networkQuality')}}</div>
<div class="overview__content">
<div class="overview__row">
<chart-single-value
v-for="(chartInfo, i) in singleValues.chartInfos"
:chart-info="chartInfo"
:chart-data="singleValues.chartDatas[i]"
:key="i"
class="cn-chart__single-value--detail-overview"
></chart-single-value>
</div>
</div>
</div>
<div class="overview-item">
<div class="overview__title">{{$t('entities.accessLink')}}</div>
<div class="overview__content">
<div class="overview__tags">
<div class="overview__tag">
<span class="tag__desc">{{$t('entities.outLinkTrafficPercentage')}}</span>
<span class="tag__value">{{entityData.linkOutPercent ? unitConvert(entityData.linkOutPercent, unitTypes.percent).join(' ') + '%' : '-'}}</span>
</div>
<div class="overview__tag">
<span class="tag__desc">{{$t('entities.inLinkTrafficPercentage')}}</span>
<span class="tag__value">{{entityData.linkInPercent ? unitConvert(entityData.linkInPercent, unitTypes.percent).join(' ') + '%' : '-'}}</span>
</div>
</div>
</div>
</div>
<div class="overview-item"> <div class="overview-item">
<div class="overview__title">{{$t('overall.alert')}}</div> <div class="overview__title">{{$t('overall.alert')}}</div>
<div class="overview__content"> <div class="overview__content">
@@ -103,7 +132,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="overview-map"> <div class="overview-map overview-map--app">
<chart2 <chart2
:chart-info="chart" :chart-info="chart"
:chart-data="chartData" :chart-data="chartData"
@@ -122,13 +151,15 @@ import { unitTypes } from '@/utils/constants'
import unitConvert from '@/utils/unit-convert' import unitConvert from '@/utils/unit-convert'
import Chart2 from '@/views/charts/Chart2' import Chart2 from '@/views/charts/Chart2'
import _ from 'lodash' import _ from 'lodash'
import {get} from "@/utils/http"; import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
import { get } from '@/utils/http'
export default { export default {
name: 'App', name: 'App',
mixins: [entityDetailMixin], mixins: [entityDetailMixin],
components: { components: {
Chart2 Chart2,
ChartSingleValue
}, },
data () { data () {
return { return {
@@ -136,11 +167,59 @@ export default {
entityType: 'app', entityType: 'app',
trafficUrl: api.entityAppDetailTraffic, trafficUrl: api.entityAppDetailTraffic,
relationUrl: api.entityAppDetailRelation, relationUrl: api.entityAppDetailRelation,
networkQuantityUrl: api.entityAppDetailNetworkQuantity,
linkInUrl: api.entityAppDetailLinkIn,
linkOutUrl: api.entityAppDetailLinkOut,
alertUrl: api.entityAppDetailAlert, alertUrl: api.entityAppDetailAlert,
securityUrl: api.entityAppDetailSecurity, securityUrl: api.entityAppDetailSecurity,
trafficUrlMap: api.entityAppDetailTrafficMap, trafficUrlMap: api.entityAppDetailTrafficMap,
chartData: null, chartData: null,
listMode: 'list' listMode: 'list',
singleValues: {
chartInfos: [
{
params: {
icon: 'cn-icon cn-icon-time',
unitType: unitTypes.time
},
type: 51,
i18n: 'entities.avgRoundTripTime'
},
{
params: {
icon: 'cn-icon cn-icon-http',
unitType: unitTypes.time
},
type: 51,
i18n: 'entities.httpResponseLatency'
},
{
params: {
icon: 'cn-icon cn-icon-ssl',
unitType: unitTypes.time
},
type: 51,
i18n: 'entities.sslConLatency'
},
{
params: {
icon: 'cn-icon cn-icon-package-loss',
unitType: unitTypes.percent
},
type: 51,
i18n: 'entities.sequenceGapLossPercent'
},
{
params: {
icon: 'cn-icon cn-icon-upload',
unitType: unitTypes.percent
},
type: 51,
i18n: 'entities.pktRetransPercent'
}
],
chartDatas: [null, null, null, null, null]
}
} }
}, },
methods: { methods: {
@@ -164,8 +243,21 @@ export default {
}) })
} }
}, },
mounted() { watch: {
this.$nextTick(() => { setTimeout(() => { this.chartGetMap()}, 250)}) entityData: {
immediate: true,
deep: true,
handler (n) {
this.singleValues.chartDatas.splice(0, 1, this.$_.get(n, 'establishLatency'))
this.singleValues.chartDatas.splice(1, 1, this.$_.get(n, 'httpResponseLatency'))
this.singleValues.chartDatas.splice(2, 1, this.$_.get(n, 'sslConLatency'))
this.singleValues.chartDatas.splice(3, 1, this.$_.get(n, 'sequenceGapLossPercent'))
this.singleValues.chartDatas.splice(4, 1, this.$_.get(n, 'pktRetransPercent'))
}
}
},
mounted () {
this.$nextTick(() => { setTimeout(() => { this.chartGetMap() }, 250) })
}, },
setup (props) { setup (props) {
return { return {

View File

@@ -160,7 +160,7 @@ import { unitTypes } from '@/utils/constants'
import unitConvert from '@/utils/unit-convert' import unitConvert from '@/utils/unit-convert'
import Chart2 from '@/views/charts/Chart2' import Chart2 from '@/views/charts/Chart2'
import _ from 'lodash' import _ from 'lodash'
import {get} from "@/utils/http"; import { get } from '@/utils/http'
export default { export default {
name: 'Domain', name: 'Domain',
components: { components: {
@@ -170,7 +170,7 @@ export default {
mixins: [entityDetailMixin], mixins: [entityDetailMixin],
data () { data () {
return { return {
entityData: {}, // entityData: {},
entityType: 'domain', entityType: 'domain',
trafficUrl: api.entityDomainDetailTraffic, trafficUrl: api.entityDomainDetailTraffic,
relationUrl: api.entityDomainDetailRelation, relationUrl: api.entityDomainDetailRelation,
@@ -211,7 +211,7 @@ export default {
{ {
params: { params: {
icon: 'cn-icon cn-icon-package-loss', icon: 'cn-icon cn-icon-package-loss',
unitType: unitTypes.time unitType: unitTypes.percent
}, },
type: 51, type: 51,
i18n: 'entities.sequenceGapLossPercent' i18n: 'entities.sequenceGapLossPercent'
@@ -219,10 +219,10 @@ export default {
{ {
params: { params: {
icon: 'cn-icon cn-icon-upload', icon: 'cn-icon cn-icon-upload',
unitType: unitTypes.time unitType: unitTypes.percent
}, },
type: 51, type: 51,
i18n: 'entities.avgRoundTripTime' i18n: 'entities.pktRetransPercent'
} }
], ],
chartDatas: [null, null, null, null, null] chartDatas: [null, null, null, null, null]
@@ -255,17 +255,15 @@ export default {
immediate: true, immediate: true,
deep: true, deep: true,
handler (n) { handler (n) {
if ((n.pktRetransPercent && n.sequenceGapLossPercent && n.sslConLatency && n.establishLatency && n.httpResponseLatency) !== undefined) { this.singleValues.chartDatas.splice(0, 1, this.$_.get(n, 'establishLatency'))
this.singleValues.chartDatas.splice(0, 1, this.$_.get(n, 'establishLatency') || null) this.singleValues.chartDatas.splice(1, 1, this.$_.get(n, 'httpResponseLatency'))
this.singleValues.chartDatas.splice(1, 1, this.$_.get(n, 'httpResponseLatency') || null) this.singleValues.chartDatas.splice(2, 1, this.$_.get(n, 'sslConLatency'))
this.singleValues.chartDatas.splice(2, 1, this.$_.get(n, 'sslConLatency') || null) this.singleValues.chartDatas.splice(3, 1, this.$_.get(n, 'sequenceGapLossPercent'))
this.singleValues.chartDatas.splice(3, 1, this.$_.get(n, 'sequenceGapLossPercent') || null) this.singleValues.chartDatas.splice(4, 1, this.$_.get(n, 'pktRetransPercent'))
this.singleValues.chartDatas.splice(4, 1, this.$_.get(n, 'pktRetransPercent') || null)
}
} }
} }
}, },
mounted() { mounted () {
this.$nextTick(() => { setTimeout(() => { this.chartGetMap()}, 250)}) this.$nextTick(() => { setTimeout(() => { this.chartGetMap()}, 250)})
}, },
setup (props) { setup (props) {

View File

@@ -55,6 +55,35 @@
</div> </div>
</div> </div>
</div> </div>
<div class="overview-item">
<div class="overview__title">{{$t('overall.networkQuality')}}</div>
<div class="overview__content">
<div class="overview__row">
<chart-single-value
v-for="(chartInfo, i) in singleValues.chartInfos"
:chart-info="chartInfo"
:chart-data="singleValues.chartDatas[i]"
:key="i"
class="cn-chart__single-value--detail-overview"
></chart-single-value>
</div>
</div>
</div>
<div class="overview-item">
<div class="overview__title">{{$t('entities.accessLink')}}</div>
<div class="overview__content">
<div class="overview__tags">
<div class="overview__tag">
<span class="tag__desc">{{$t('entities.outLinkTrafficPercentage')}}</span>
<span class="tag__value">{{entityData.linkOutPercent ? unitConvert(entityData.linkOutPercent, unitTypes.percent).join(' ') + '%' : '-'}}</span>
</div>
<div class="overview__tag">
<span class="tag__desc">{{$t('entities.inLinkTrafficPercentage')}}</span>
<span class="tag__value">{{entityData.linkInPercent ? unitConvert(entityData.linkInPercent, unitTypes.percent).join(' ') + '%' : '-'}}</span>
</div>
</div>
</div>
</div>
<div class="overview-item"> <div class="overview-item">
<div class="overview__title">{{$t('overall.alert')}}</div> <div class="overview__title">{{$t('overall.alert')}}</div>
<div class="overview__content"> <div class="overview__content">
@@ -95,7 +124,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="overview-map"> <div class="overview-map overview-map--ip">
<chart2 <chart2
:chart-info="chart" :chart-info="chart"
:chart-data="chartData" :chart-data="chartData"
@@ -109,18 +138,20 @@
<script> <script>
import entityDetailMixin from './entityDetailMixin' import entityDetailMixin from './entityDetailMixin'
import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
import { api } from '@/utils/api' import { api } from '@/utils/api'
import { unitTypes } from '@/utils/constants' import { unitTypes } from '@/utils/constants'
import unitConvert from '@/utils/unit-convert' import unitConvert from '@/utils/unit-convert'
import Chart2 from '@/views/charts/Chart2' import Chart2 from '@/views/charts/Chart2'
import _ from 'lodash' import _ from 'lodash'
import {get} from "@/utils/http"; import { get } from '@/utils/http'
export default { export default {
name: 'Ip', name: 'Ip',
mixins: [entityDetailMixin], mixins: [entityDetailMixin],
components: { components: {
Chart2 Chart2,
ChartSingleValue
}, },
data () { data () {
return { return {
@@ -129,10 +160,58 @@ export default {
trafficUrl: api.entityIpDetailTraffic, trafficUrl: api.entityIpDetailTraffic,
trafficUrlMap: api.entityIpDetailTrafficMap, trafficUrlMap: api.entityIpDetailTrafficMap,
relationUrl: api.entityIpDetailRelation, relationUrl: api.entityIpDetailRelation,
networkQuantityUrl: api.entityIpDetailNetworkQuantity,
linkInUrl: api.entityIpDetailLinkIn,
linkOutUrl: api.entityIpDetailLinkOut,
alertUrl: api.entityIpDetailAlert, alertUrl: api.entityIpDetailAlert,
securityUrl: api.entityIpDetailSecurity, securityUrl: api.entityIpDetailSecurity,
listMode: 'list', listMode: 'list',
chartData: null chartData: null,
singleValues: {
chartInfos: [
{
params: {
icon: 'cn-icon cn-icon-time',
unitType: unitTypes.time
},
type: 51,
i18n: 'entities.avgRoundTripTime'
},
{
params: {
icon: 'cn-icon cn-icon-http',
unitType: unitTypes.time
},
type: 51,
i18n: 'entities.httpResponseLatency'
},
{
params: {
icon: 'cn-icon cn-icon-ssl',
unitType: unitTypes.time
},
type: 51,
i18n: 'entities.sslConLatency'
},
{
params: {
icon: 'cn-icon cn-icon-package-loss',
unitType: unitTypes.percent
},
type: 51,
i18n: 'entities.sequenceGapLossPercent'
},
{
params: {
icon: 'cn-icon cn-icon-upload',
unitType: unitTypes.percent
},
type: 51,
i18n: 'entities.pktRetransPercent'
}
],
chartDatas: [null, null, null, null, null]
}
} }
}, },
methods: { methods: {
@@ -155,10 +234,23 @@ export default {
this.chartData = response.data.result this.chartData = response.data.result
} }
}) })
}, }
}, },
mounted() { watch: {
this.$nextTick(() => { setTimeout(() => { this.chartGetMap()}, 250)}) entityData: {
immediate: true,
deep: true,
handler (n) {
this.singleValues.chartDatas.splice(0, 1, this.$_.get(n, 'establishLatency'))
this.singleValues.chartDatas.splice(1, 1, this.$_.get(n, 'httpResponseLatency'))
this.singleValues.chartDatas.splice(2, 1, this.$_.get(n, 'sslConLatency'))
this.singleValues.chartDatas.splice(3, 1, this.$_.get(n, 'sequenceGapLossPercent'))
this.singleValues.chartDatas.splice(4, 1, this.$_.get(n, 'pktRetransPercent'))
}
}
},
mounted () {
this.$nextTick(() => { setTimeout(() => { this.chartGetMap() }, 250) })
}, },
setup (props) { setup (props) {
const entityCopy = { const entityCopy = {

View File

@@ -160,10 +160,18 @@ export default {
queryEntityDetailLinkOutUrl () { queryEntityDetailLinkOutUrl () {
if (this.linkOutUrl) { if (this.linkOutUrl) {
get(this.linkOutUrl, this.getQueryParams()).then(response => { get(this.linkOutUrl, this.getQueryParams()).then(response => {
if (response.code === 200 && response.data.aggregation) { if (response.code === 200) {
const sum = response.data.aggregation.sum if (!this.$_.isEmpty(response.data.result)) {
const max = response.data.aggregation.max let sum = 0
this.entityData.linkOutPercent = (parseFloat(max / sum) * 100).toFixed(2) response.data.result.forEach(r => {
sum += parseFloat(r.bytes)
})
const sorted = response.data.result.sort((r1, r2) => {
return parseFloat(r2.bytes) - parseFloat(r1.bytes)
})
const max = parseFloat(sorted[0].bytes)
this.entityData.linkOutPercent = (parseFloat(max / sum) * 100).toFixed(2)
}
} }
}) })
} }
@@ -192,11 +200,9 @@ export default {
this.queryEntityDetailRelation() this.queryEntityDetailRelation()
this.queryEntityDetailAlert() this.queryEntityDetailAlert()
this.queryEntityDetailSecurity() this.queryEntityDetailSecurity()
if (this.entityData.entityType === 'domain') { this.queryEntityDetailNetworkQuantity()
this.queryEntityDetailNetworkQuantity() this.queryEntityDetailLinkOutUrl()
this.queryEntityDetailLinkOutUrl() this.queryEntityDetailLinkInUrl()
this.queryEntityDetailLinkInUrl()
}
} }
}, },
setup () { setup () {

View File

@@ -3,7 +3,7 @@ import { get } from '@/utils/http'
import { api } from '@/utils/api' import { api } from '@/utils/api'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { entityListLineOption } from '@/components/charts/chart-options' import { entityListLineOption } from '@/components/charts/chart-options'
import { unitTypes } from '@/utils/constants' import {riskLevelMapping, unitTypes} from '@/utils/constants'
export default { export default {
props: { props: {
@@ -75,6 +75,14 @@ export default {
} }
return url return url
}, },
appRisk () {
return function (level) {
const m = riskLevelMapping.find(mapping => {
return mapping.value == level
})
return (m && m.name) || level
}
},
queryParams () { queryParams () {
let params let params
const now = window.$dayJs.tz().valueOf() const now = window.$dayJs.tz().valueOf()

View File

@@ -187,12 +187,12 @@ export default {
}, },
{ {
name: 'app_risk', name: 'app_risk',
type: 'long', type: 'string',
// label: this.$t('trafficSummary.appRisk') // label: this.$t('trafficSummary.appRisk')
label: 'APP risk' label: 'APP risk'
} }
], ],
operatorList: ['=', '!=', '>', '<', '>=', '<=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE'], operatorList: ['=', '!=', '>', '<', '>=', '<='/*, 'IN', 'NOT IN', 'LIKE', 'NOT LIKE'*/],
connectionList: [ connectionList: [
{ {
value: 'AND', value: 'AND',