CN-333 feat : Dashboard--dns 实时告警信息图表开发 以及CN-332的一些样式修改
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
@import './views/charts/ChartTwoSituationStatistics';
|
||||
@import './views/charts/chartAlarmInfo';
|
||||
@import './views/chartHeader';
|
||||
@import './views/charts/chartMap';
|
||||
|
||||
|
||||
//@import '../chart';
|
||||
|
||||
60
src/assets/css/components/views/charts/chartMap.scss
Normal file
60
src/assets/css/components/views/charts/chartMap.scss
Normal file
@@ -0,0 +1,60 @@
|
||||
.cn-chart__map {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.map-drawing {
|
||||
flex: 1;
|
||||
}
|
||||
.map-chart__legends {
|
||||
flex-basis: 116px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding: 0 30px;
|
||||
|
||||
.map-chart__legend {
|
||||
padding-bottom: 5px;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
border: 1px solid #E0E6EF;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;;
|
||||
cursor: pointer;
|
||||
|
||||
&:first-of-type {
|
||||
border-left-color: #E0E6EF;
|
||||
}
|
||||
&:last-of-type {
|
||||
border-right-color: #E0E6EF;
|
||||
}
|
||||
&.map-chart__legend--active {
|
||||
border-color: #59ABFF;
|
||||
|
||||
.legend__value {
|
||||
color: #1890FF;
|
||||
}
|
||||
}
|
||||
.legend__circle-marker {
|
||||
flex: 0 0 12px;
|
||||
margin: 12px 0 8px 0;
|
||||
width: 12px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.legend__value {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
.legend__name {
|
||||
padding: 0 10px;
|
||||
color: #666666;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,8 @@
|
||||
import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import * as echarts from 'echarts'
|
||||
import { getChartColor, entityListLineOption } from '@/views/charts/charts/chart-options'
|
||||
import { entityListLineOption } from '@/views/charts/charts/chart-options'
|
||||
import { getChartColor } from '@/views/charts/charts/tools'
|
||||
import { legendMapping } from '@/views/charts/charts/chart-table-title'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
|
||||
@@ -84,15 +84,17 @@ export const api = {
|
||||
victimLocation: '/interface/detection/security/filter/victimLocation',
|
||||
eventSeverity: '/interface/detection/security/filter/severity',
|
||||
listBasic: '/interface/detection/security/list/basic',
|
||||
listCount: '/interface/detection/security/list/count',
|
||||
overviewBasic: '/interface/detection/security/detail/overview/basic',
|
||||
overviewEvent: '/interface/detection/security/detail/overview/event'
|
||||
},
|
||||
performanceEvent: {
|
||||
eventSeverityTrend: '/interface/detection/performance/filter/severityTrend',
|
||||
securityType: '/interface/detection/performance/filter/eventType',
|
||||
eventType: '/interface/detection/performance/filter/eventType',
|
||||
eventSeverity: '/interface/detection/performance/filter/severity',
|
||||
activeEntity: '/interface/detection/performance/filter/activeEntity',
|
||||
listBasic: '/interface/detection/performance/list/basic',
|
||||
listCount: '/interface/detection/performance/list/count',
|
||||
overviewBasic: '/interface/detection/performance/detail/overview/basic'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -130,7 +130,19 @@ export const unitTypes = {
|
||||
export const chartTableDefaultPageSize = 10 // table类型图表默认每页数据量
|
||||
export const chartTableTopOptions = [10, 100] // table类型图表的TOP-N选项
|
||||
export const chartActiveIpTableOrderOptions = ['machine'] // active ip table类型图表的order 选项
|
||||
// table类型图表的TOP-N选项
|
||||
// table类型图表column映射
|
||||
export const chartTableColumnMapping = {
|
||||
sessions: 'overall.sessions',
|
||||
packets: 'overall.packets',
|
||||
bytes: 'overall.bytes',
|
||||
clientIp: 'overall.clientIp',
|
||||
serverIp: 'overall.serverIp',
|
||||
domain: 'overall.domain',
|
||||
appName: 'overall.appName',
|
||||
queryRate: 'dns.queryRate',
|
||||
dnsLatency: 'dns.averageResolveLatency',
|
||||
responseFailRate: 'dns.responseFailureRate'
|
||||
}
|
||||
export const chartPieTableTopOptions = [
|
||||
{ name: 'Sessions', value: 'sessions' },
|
||||
{ name: 'Packets', value: 'packets' },
|
||||
@@ -170,6 +182,20 @@ export const detectionPageType = {
|
||||
performanceEvent: 'performanceEvent'
|
||||
}
|
||||
|
||||
export const dnsServerRole = {
|
||||
RTDNS: 'RTDNS',
|
||||
TLDNS: 'TLDNS',
|
||||
OPRDNS: 'OPRDNS',
|
||||
ADNS: 'ADNS',
|
||||
SBDNS: 'SBDNS',
|
||||
RTDNSM: 'RTDNSM'
|
||||
}
|
||||
|
||||
export const chartColor = ['#5370C6', '#90CC74', '#FAC858', '#EE6666',
|
||||
'#73BFDE', '#3BA172', '#FC8452', '#9960B4',
|
||||
'#E97CCC', '#FEA69E', '#0F8AB2', '#57CBAC',
|
||||
'#5888BC', '#63B6AC', '#EDC6B2', '#D5746B']
|
||||
|
||||
export const iso36112 = {
|
||||
[storageKey.iso36112Capital]: 'data/countriesWithCapital',
|
||||
[storageKey.iso36112WorldLow]: 'worldChinaLow',
|
||||
|
||||
@@ -29,7 +29,7 @@ export function getMillisecond (time) {
|
||||
ms = Math.floor(time * (10 ** (0 - difference)))
|
||||
}
|
||||
}
|
||||
return ms
|
||||
return ms ? Number(ms) : null
|
||||
}
|
||||
// 初始化日期
|
||||
export function getNowTime (interval) {
|
||||
@@ -40,3 +40,7 @@ export function getNowTime (interval) {
|
||||
endTime
|
||||
}
|
||||
}
|
||||
// 日期格式转换
|
||||
export function rTime (date) {
|
||||
return window.$dayJs.tz(new Date(date)).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
@@ -444,12 +444,18 @@ export function lineToHump (name) {
|
||||
}
|
||||
// 下划线转换空格首位大写
|
||||
export function lineToSpace (name) {
|
||||
if (_.isEmpty(name)) {
|
||||
return ''
|
||||
}
|
||||
return _.upperFirst(name.replace(/\_(\w)/g, function (all, letter) {
|
||||
return ` ${letter.toUpperCase()}`
|
||||
}))
|
||||
}
|
||||
// 驼峰转换下划线
|
||||
export function humpToLine (name) {
|
||||
if (_.isEmpty(name)) {
|
||||
return ''
|
||||
}
|
||||
return name.replace(/([A-Z])/g, '_$1').toLowerCase()
|
||||
}
|
||||
// 搜索功能:对象转字符串
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
:chart-data="chartData"
|
||||
:query-params="queryParams"
|
||||
:entity="entity"
|
||||
@query="query"
|
||||
@showLoading="showLoading"
|
||||
></chart-map>
|
||||
|
||||
@@ -79,7 +80,7 @@
|
||||
></chart-ip-open-port-bar>
|
||||
|
||||
<chart-table
|
||||
v-else-if="isTable && isCurrentTable"
|
||||
v-else-if="isTable && isBasicTable"
|
||||
:chart-info="chartInfo"
|
||||
:chart-data="chartData"
|
||||
:table="table"
|
||||
@@ -245,7 +246,7 @@ import {
|
||||
isEchartsLine,
|
||||
isSingleValue,
|
||||
isTable,
|
||||
isCurrentTable,
|
||||
isBasicTable,
|
||||
isActiveIpTable,
|
||||
isTitle,
|
||||
isMap,
|
||||
@@ -371,6 +372,9 @@ export default {
|
||||
`chart${this.chartInfo.id}`
|
||||
)
|
||||
},
|
||||
query (params) {
|
||||
this.$emit('query', params)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
@@ -401,7 +405,7 @@ export default {
|
||||
),
|
||||
isRelationShip: isRelationShip(props.chartInfo.type),
|
||||
isTable: isTable(props.chartInfo.type),
|
||||
isCurrentTable: isCurrentTable(props.chartInfo.type),
|
||||
isBasicTable: isBasicTable(props.chartInfo.type),
|
||||
isActiveIpTable: isActiveIpTable(props.chartInfo.type),
|
||||
isMap: isMap(props.chartInfo.type),
|
||||
isTitle: isTitle(props.chartInfo.type),
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
{{ chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name }}
|
||||
</div>
|
||||
<template v-if="isCurrentTable">
|
||||
<div class="chart-header__title" v-else-if="!isBasicTable" :class="{'chart-header__title--block': isBlock}" :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div>
|
||||
<template v-if="isBasicTable">
|
||||
<div class="chart-header__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{
|
||||
chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name
|
||||
@@ -257,6 +259,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chartTableColumnMapping,
|
||||
dropdownMenuShow: false,
|
||||
errorText: '',
|
||||
isFocus:false,
|
||||
@@ -369,7 +372,7 @@ export default {
|
||||
isBlock: isBlock(props.chartInfo.type),
|
||||
isTabs: isTabs(props.chartInfo.type),
|
||||
isTable: isTable(props.chartInfo.type),
|
||||
isCurrentTable: isCurrentTable(props.chartInfo.type),
|
||||
isBasicTable: isBasicTable(props.chartInfo.type),
|
||||
isActiveIpTable: isActiveIpTable(props.chartInfo.type),
|
||||
isEchartsWithTable: isEchartsWithTable(props.chartInfo.type),
|
||||
isGroup: isGroup(props.chartInfo.type),
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<script>
|
||||
import ChartHeader from './ChartHeader'
|
||||
import Chart from '@/views/charts/Chart'
|
||||
import testData from './charts/testData'
|
||||
import { dnsServerRole, chartPieTableTopOptions, chartTableDefaultPageSize, chartTableTopOptions } from '@/utils/constants'
|
||||
import {
|
||||
isEcharts,
|
||||
isSingleValue,
|
||||
@@ -81,7 +81,7 @@ import {
|
||||
import { tableTitleMapping, legendMapping } from '@/views/charts/charts/chart-table-title'
|
||||
import { replaceUrlPlaceholder } from '@/utils/tools'
|
||||
import { getNowTime, getSecond } from '@/utils/date-util'
|
||||
import { chartPieTableTopOptions, chartTableDefaultPageSize, chartTableTopOptions } from '@/utils/constants'
|
||||
|
||||
import { get } from '@/utils/http'
|
||||
import { ref } from 'vue'
|
||||
import _ from 'lodash'
|
||||
@@ -194,6 +194,10 @@ export default {
|
||||
...extraParams
|
||||
}
|
||||
const requestUrl = url || (chartParams && chartParams.url)
|
||||
// 默认参数特殊处理
|
||||
if (requestUrl && requestUrl.indexOf('dnsServerRole') > -1) {
|
||||
this.queryParams.dnsServerRole = extraParams.dnsServerRole || dnsServerRole.RTDNS
|
||||
}
|
||||
if (requestUrl) {
|
||||
get(replaceUrlPlaceholder(requestUrl, this.queryParams)).then(response => {
|
||||
// if (this.chartInfo.type === 23 && testData) {
|
||||
@@ -201,6 +205,27 @@ export default {
|
||||
// } else if (this.chartInfo.type === 24 && testData) {
|
||||
// response = testData.data2
|
||||
// }
|
||||
if (this.chartInfo.type === 3) {
|
||||
response = {
|
||||
code: 200,
|
||||
data: {
|
||||
result: [
|
||||
{
|
||||
dnsServerRole: extraParams.dnsServerRole || dnsServerRole.RTDNS,
|
||||
ipLocationCountry: 'China',
|
||||
ipLocationId: 'CN',
|
||||
count: 161
|
||||
},
|
||||
{
|
||||
dnsServerRole: extraParams.dnsServerRole || dnsServerRole.RTDNS,
|
||||
ipLocationCountry: 'Japan',
|
||||
ipLocationId: 'JP',
|
||||
count: 222
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
if (response.code === 200) {
|
||||
if (Array.isArray(response.data.result)) {
|
||||
response.data.result.forEach(item => {
|
||||
@@ -210,9 +235,6 @@ export default {
|
||||
})
|
||||
}
|
||||
this.chartData = response.data.result
|
||||
this.table.tableData = response.data.result
|
||||
this.table.tableColumns = this.getTableTitle(response.data.result)
|
||||
this.table.currentPageData = this.getTargetPageData(1, this.table.pageSize, this.table.tableData)
|
||||
this.resultType = response.data.resultType
|
||||
if (this.chartInfo.type === 12) {
|
||||
const newArr = []
|
||||
@@ -231,7 +253,12 @@ export default {
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.isSingleValue) {
|
||||
if (this.isTable) {
|
||||
this.table.tableData = response.data.result
|
||||
// this.table.tableColumns = chartParams.columns
|
||||
// this.table.tableColumns = this.getTableTitle(response.data.result)
|
||||
this.table.currentPageData = this.getTargetPageData(1, this.table.pageSize, this.table.tableData)
|
||||
} else if (this.isSingleValue) {
|
||||
if (chartParams && chartParams.dataKey) {
|
||||
if (response.data.result && (response.data.result[chartParams.dataKey] || response.data.result[chartParams.dataKey] === 0)) {
|
||||
this.chartData = response.data.result[chartParams.dataKey]
|
||||
@@ -377,7 +404,19 @@ export default {
|
||||
const dateRangeValue = 60
|
||||
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||
const chartTimeFilter = ref({ startTime, endTime, dateRangeValue })
|
||||
let table = {}
|
||||
if (isTable(props.chartInfo.type)) {
|
||||
table = {
|
||||
pageSize: chartTableDefaultPageSize,
|
||||
limit: chartTableTopOptions[0], // top-n
|
||||
orderBy: props.chartInfo.params.columns.order[0],
|
||||
tableColumns: props.chartInfo.params.columns, // table字段
|
||||
tableData: [], // table的所有数据
|
||||
currentPageData: [] // table当前页的数据
|
||||
}
|
||||
}
|
||||
return {
|
||||
table,
|
||||
chartTimeFilter,
|
||||
isEcharts: isEcharts(props.chartInfo.type),
|
||||
isEchartsTimeBar: isEchartsTimeBar(props.chartInfo.type),
|
||||
|
||||
@@ -28,18 +28,18 @@
|
||||
v-for="(c, i) in table.tableColumns"
|
||||
show-overflow-tooltip
|
||||
:key="i"
|
||||
:label="c.label"
|
||||
:prop="c.prop"
|
||||
:label="$t(chartTableOrderOptionsMapping[c])"
|
||||
:prop="c"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<span v-if="c.prop === 'bytes'">
|
||||
{{unitConvert(row[c.prop], unitTypes.byte).join(' ')}}
|
||||
<span v-if="c === 'bytes'">
|
||||
{{unitConvert(row[c], unitTypes.byte).join(' ')}}
|
||||
</span>
|
||||
<span v-else-if="c.prop === 'packets' || c.prop === 'sessions'">
|
||||
{{unitConvert(row[c.prop], unitTypes.number).join(' ')}}
|
||||
<span v-else-if="c === 'packets' || c === 'sessions'">
|
||||
{{unitConvert(row[c], unitTypes.number).join(' ')}}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{row[c.prop]}}
|
||||
{{row[c]}}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -49,7 +49,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import { unitTypes, chartTableOrderOptionsMapping } from '@/utils/constants'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
export default {
|
||||
name: 'ChartActiveIpTable',
|
||||
@@ -61,6 +61,7 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
chartTableOrderOptionsMapping,
|
||||
unitConvert,
|
||||
unitTypes,
|
||||
activeIpTable: {
|
||||
|
||||
@@ -6,14 +6,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import StatisticsLegend from '@/views/charts/charts/StatisticsLegend'
|
||||
import {
|
||||
lineWithStatistics
|
||||
} from '@/views/charts/charts/options/line'
|
||||
import {
|
||||
getChartColor
|
||||
} from '@/views/charts/charts/chart-options'
|
||||
} from '@/views/charts/charts/tools'
|
||||
import chartEchartMixin from './chart-echart-mixin'
|
||||
|
||||
export default {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<script>
|
||||
import lodash from 'lodash'
|
||||
import { ipOpenPortBar } from '@/views/charts/charts/options/bar'
|
||||
import { getChartColor } from '@/views/charts/charts/chart-options'
|
||||
import { getChartColor } from '@/views/charts/charts/tools'
|
||||
import * as echarts from 'echarts'
|
||||
export default {
|
||||
name: 'ChartIpOpenPortBar',
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
import * as am4Core from '@amcharts/amcharts4/core'
|
||||
import * as am4Maps from '@amcharts/amcharts4/maps'
|
||||
import { getGeoData, replaceUrlPlaceholder } from '@/utils/tools'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
|
||||
import { isMapBlock } from './tools'
|
||||
import { storageKey, dnsServerRole } from '@/utils/constants'
|
||||
import { isMapBlock, isMapPoint } from './tools'
|
||||
import unitConvert, { valueToRangeValue } from '@/utils/unit-convert'
|
||||
import { HeatLegend } from '@/components/amcharts/heatLegend'
|
||||
import { getData } from '@/utils/api'
|
||||
@@ -72,6 +71,7 @@ export default {
|
||||
})
|
||||
},
|
||||
loadAm4ChartMap (polygonSeries, country, chartData) {
|
||||
// chartData不为空是下钻
|
||||
if (chartData) {
|
||||
this.$emit('showLoading', true)
|
||||
}
|
||||
@@ -111,8 +111,9 @@ export default {
|
||||
showValue: (r.value || r.value === 0) ? valueToRangeValue(r.value, chartParams.unitType).join(' ') : ''
|
||||
}))
|
||||
!this.$_.isEmpty(seriesData) && (polygonSeries.data = [...seriesData])
|
||||
// 数据全为0的情况,legend只显示1个颜色
|
||||
const sorted = seriesData.sort((a, b) => b.value - a.value)
|
||||
const allZero = this.$_.isEmpty(sorted) || Number(sorted[0].value) === 0 // 数据全为0的情况,legend只显示1个颜色
|
||||
const allZero = this.$_.isEmpty(sorted) || Number(sorted[0].value) === 0
|
||||
|
||||
polygonSeries.heatRules.push({
|
||||
property: 'fill',
|
||||
@@ -142,6 +143,56 @@ export default {
|
||||
heatLegend.valueAxis.renderer.labels.template.adapter.add('text', function (labelText) {
|
||||
return ''
|
||||
})
|
||||
} else if (data && this.isMapPoint) {
|
||||
const seriesData = []
|
||||
data.forEach(d => {
|
||||
seriesData.push({
|
||||
id: d.ipLocationId,
|
||||
count: d.count,
|
||||
dnsServerRole: d.dnsServerRole,
|
||||
location: d.ipLocationCity || d.ipLocationProvince || d.ipLocationCountry,
|
||||
desc: this.$t(this.dnsTypeI18n(d.dnsServerRole)),
|
||||
color: this.circleColor[d.dnsServerRole].background,
|
||||
border: this.circleColor[d.dnsServerRole].border
|
||||
})
|
||||
})
|
||||
console.info(seriesData)
|
||||
const imageSeries = this.myChart.series.push(new am4Maps.MapImageSeries())
|
||||
imageSeries.data = seriesData
|
||||
imageSeries.dataFields.value = 'count'
|
||||
|
||||
const imageTemplate = imageSeries.mapImages.template
|
||||
imageTemplate.nonScaling = true
|
||||
|
||||
imageTemplate.adapter.add('latitude', function (latitude, target) {
|
||||
const polygon = polygonSeries.getPolygonById(target.dataItem.dataContext.id)
|
||||
if (polygon) {
|
||||
return polygon.visualLatitude
|
||||
}
|
||||
return latitude
|
||||
})
|
||||
|
||||
imageTemplate.adapter.add('longitude', function (longitude, target) {
|
||||
const polygon = polygonSeries.getPolygonById(target.dataItem.dataContext.id)
|
||||
if (polygon) {
|
||||
return polygon.visualLongitude
|
||||
}
|
||||
return longitude
|
||||
})
|
||||
|
||||
const circle = imageTemplate.createChild(am4Core.Circle)
|
||||
circle.propertyFields.fill = 'color'
|
||||
circle.propertyFields.stroke = 'border'
|
||||
circle.strokeWidth = 1
|
||||
circle.tooltipText = '[bold]{location}[/]\n{desc}: {count}'
|
||||
|
||||
imageSeries.heatRules.push({
|
||||
target: circle,
|
||||
property: 'radius',
|
||||
min: 6,
|
||||
max: 25,
|
||||
dataField: 'value'
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
@@ -161,6 +212,37 @@ export default {
|
||||
this.myChart.goHome()
|
||||
})
|
||||
},
|
||||
dnsTypeI18n (role) {
|
||||
let i18n = ''
|
||||
switch (role) {
|
||||
case dnsServerRole.RTDNS: {
|
||||
i18n = 'dns.rootDomainServers'
|
||||
break
|
||||
}
|
||||
case dnsServerRole.TLDNS: {
|
||||
i18n = 'dns.topLevelDomainServers'
|
||||
break
|
||||
}
|
||||
case dnsServerRole.OPRDNS: {
|
||||
i18n = 'dns.publicRecursiveDomainServers'
|
||||
break
|
||||
}
|
||||
case dnsServerRole.ADNS: {
|
||||
i18n = 'dns.authoritativeDomainServers'
|
||||
break
|
||||
}
|
||||
case dnsServerRole.SBDNS: {
|
||||
i18n = 'dns.selfBuiltDomainServers'
|
||||
break
|
||||
}
|
||||
case dnsServerRole.RTDNSM: {
|
||||
i18n = 'RTDNSM'
|
||||
break
|
||||
}
|
||||
default: break
|
||||
}
|
||||
return i18n
|
||||
},
|
||||
generateTooltipHTML () {
|
||||
return `
|
||||
<div class="map-tooltip" style="padding-bottom: 10px;">
|
||||
@@ -206,8 +288,35 @@ export default {
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const circleColor = {}
|
||||
circleColor[dnsServerRole.RTDNS] = {
|
||||
background: '#C0DEFE',
|
||||
border: '#478AD5'
|
||||
}
|
||||
circleColor[dnsServerRole.TLDNS] = {
|
||||
background: '#DBCFFA',
|
||||
border: '#AA8CF2'
|
||||
}
|
||||
circleColor[dnsServerRole.ADNS] = {
|
||||
background: '#A0E8E0',
|
||||
border: '#1CC9B5'
|
||||
}
|
||||
circleColor[dnsServerRole.OPRDNS] = {
|
||||
background: '#FFE1B5',
|
||||
border: '#FFB84E'
|
||||
}
|
||||
circleColor[dnsServerRole.SBDNS] = {
|
||||
background: '#FDC6C6',
|
||||
border: '#FA7777'
|
||||
}
|
||||
circleColor[dnsServerRole.RTDNSM] = {
|
||||
background: '#ECC6F7',
|
||||
border: '#BF49DF'
|
||||
}
|
||||
return {
|
||||
isMapBlock: isMapBlock(props.chartInfo.type)
|
||||
circleColor,
|
||||
isMapBlock: isMapBlock(props.chartInfo.type),
|
||||
isMapPoint: isMapPoint(props.chartInfo.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ import {
|
||||
import { get } from '@/utils/http'
|
||||
import { replaceUrlPlaceholder } from '@/utils/tools'
|
||||
import * as echarts from 'echarts'
|
||||
import { getOption, getChartColor } from '@/views/charts/charts/chart-options'
|
||||
import { getOption, getChartColor } from '@/views/charts/charts/tools'
|
||||
export default {
|
||||
name: 'chartSingleValue',
|
||||
props: {
|
||||
|
||||
@@ -9,22 +9,30 @@
|
||||
<el-table-column v-if="table.currentPageData.length" type="index" label="#">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="(c, i) in table.tableColumns"
|
||||
v-for="(c, i) in table.tableColumns.common"
|
||||
show-overflow-tooltip
|
||||
:key="i"
|
||||
:label="c.label"
|
||||
:prop="c.prop"
|
||||
:label="$t(chartTableColumnMapping[c])"
|
||||
:prop="c"
|
||||
>
|
||||
<template #header>{{$t(c.label)}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="(c, i) in table.tableColumns.order"
|
||||
show-overflow-tooltip
|
||||
:key="i"
|
||||
:label="$t(chartTableColumnMapping[c])"
|
||||
:prop="c"
|
||||
>
|
||||
<template #header>{{$t(chartTableColumnMapping[c])}}</template>
|
||||
<template #default="{ row }">
|
||||
<span v-if="c.prop === 'bytes'">
|
||||
{{unitConvert(row[c.prop], unitTypes.byte).join(' ')}}
|
||||
<span v-if="c === 'bytes'">
|
||||
{{unitConvert(row[c], unitTypes.byte).join(' ')}}
|
||||
</span>
|
||||
<span v-else-if="c.prop === 'packets' || c.prop === 'sessions'">
|
||||
{{unitConvert(row[c.prop], unitTypes.number).join(' ')}}
|
||||
<span v-else-if="c === 'packets' || c === 'sessions'">
|
||||
{{unitConvert(row[c], unitTypes.number).join(' ')}}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{row[c.prop]}}
|
||||
{{row[c]}}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -41,7 +49,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import { unitTypes, chartTableColumnMapping } from '@/utils/constants'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import ChartTablePagination from '@/views/charts/charts/ChartTablePagination'
|
||||
export default {
|
||||
@@ -57,6 +65,7 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
chartTableColumnMapping,
|
||||
unitConvert,
|
||||
unitTypes
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getChartColor } from '@/views/charts/charts/chart-options'
|
||||
import { getChartColor } from '@/views/charts/charts/tools'
|
||||
import unitConvert, { valueToRangeValue } from '@/utils/unit-convert'
|
||||
export default {
|
||||
name: 'StatisticsLegend',
|
||||
|
||||
@@ -1,333 +1,6 @@
|
||||
/**
|
||||
* @author 陈劲松
|
||||
* @date 2021/6/16
|
||||
* @description chart option和一些工具
|
||||
*/
|
||||
import { format } from 'echarts'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import _ from 'lodash'
|
||||
export const chartColor = ['#5370C6', '#90CC74', '#FAC858', '#EE6666',
|
||||
'#73BFDE', '#3BA172', '#FC8452', '#9960B4',
|
||||
'#E97CCC', '#FEA69E', '#0F8AB2', '#57CBAC',
|
||||
'#5888BC', '#63B6AC', '#EDC6B2', '#D5746B']
|
||||
export const chartBarColor = ['#0F8AB2', '#57CBAC']
|
||||
export function getChartColor (index) {
|
||||
return chartColor[index % chartColor.length]
|
||||
}
|
||||
export function getCharBartColor (index) {
|
||||
return chartBarColor[index % chartBarColor.length]
|
||||
}
|
||||
const line = {
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
trigger: 'axis',
|
||||
textStyle: {
|
||||
width: '20px',
|
||||
overflow: 'truncate'
|
||||
},
|
||||
formatter: axiosFormatter,
|
||||
show: true,
|
||||
className: 'nz-chart-tooltip',
|
||||
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);max-width: 300px !important'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time'
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: function (value, index, a, b) {
|
||||
return unitConvert(value, unitTypes.number).join(' ')
|
||||
}
|
||||
},
|
||||
minInterval: 1
|
||||
},
|
||||
animation: false,
|
||||
grid: {
|
||||
left: 55,
|
||||
bottom: 30,
|
||||
top: 100,
|
||||
right: 25
|
||||
},
|
||||
color: chartColor,
|
||||
legend: {
|
||||
tooltip: {
|
||||
show: true,
|
||||
formatter: '{a}'
|
||||
},
|
||||
show: true,
|
||||
right: 23,
|
||||
top: 8,
|
||||
padding: 2,
|
||||
orient: 'horizontal',
|
||||
icon: 'circle',
|
||||
itemGap: 10,
|
||||
itemWidth: 10,
|
||||
textStyle: {
|
||||
padding: [0, 0, 0, 2],
|
||||
fontSize: 14
|
||||
},
|
||||
formatter: tooLongFormatter
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: 14
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '',
|
||||
type: 'line',
|
||||
smooth: false,
|
||||
symbol: 'none',
|
||||
data: []
|
||||
}
|
||||
]
|
||||
}
|
||||
const lineWithStatistics = {
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
trigger: 'axis',
|
||||
textStyle: {
|
||||
width: '20px',
|
||||
overflow: 'truncate'
|
||||
},
|
||||
formatter: axiosFormatter,
|
||||
className: 'nz-chart-tooltip',
|
||||
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);max-width: 300px !important'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time'
|
||||
},
|
||||
animation: false,
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: function (value, index) {
|
||||
return unitConvert(value, unitTypes.number).join(' ')
|
||||
}
|
||||
},
|
||||
minInterval: 1
|
||||
},
|
||||
color: chartColor,
|
||||
grid: {
|
||||
left: 55,
|
||||
bottom: 30,
|
||||
top: 20,
|
||||
right: 20
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: 14
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '',
|
||||
type: 'line',
|
||||
smooth: false,
|
||||
symbol: 'none',
|
||||
data: []
|
||||
}
|
||||
]
|
||||
}
|
||||
const lineStack = {
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
trigger: 'axis',
|
||||
textStyle: {
|
||||
width: '20px',
|
||||
overflow: 'truncate'
|
||||
},
|
||||
formatter: axiosFormatter,
|
||||
className: 'nz-chart-tooltip',
|
||||
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);max-width: 300px !important'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time'
|
||||
},
|
||||
color: chartColor,
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: function (value, index) {
|
||||
return unitConvert(value, unitTypes.number).join(' ')
|
||||
}
|
||||
},
|
||||
minInterval: 1
|
||||
},
|
||||
grid: {
|
||||
left: 55,
|
||||
bottom: 45,
|
||||
top: 10,
|
||||
right: 180
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
right: 30,
|
||||
top: 'middle',
|
||||
orient: 'vertical',
|
||||
icon: 'circle',
|
||||
itemGap: 20,
|
||||
itemWidth: 10,
|
||||
formatter: tooLongFormatter,
|
||||
textStyle: {
|
||||
padding: [0, 0, 0, 5],
|
||||
fontSize: 14
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: 14
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '',
|
||||
type: 'line',
|
||||
stack: 'value',
|
||||
areaStyle: {},
|
||||
symbol: 'none',
|
||||
data: []
|
||||
}
|
||||
]
|
||||
}
|
||||
const pieWithTable = {
|
||||
tooltip: {
|
||||
appendToBody: true
|
||||
},
|
||||
color: chartColor,
|
||||
animation: false,
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
type: 'plain',
|
||||
left: '60%',
|
||||
top: 'middle',
|
||||
icon: 'circle',
|
||||
itemWidth: 10, // 设置宽度
|
||||
itemHeight: 10, // 设置高度
|
||||
itemGap: 20,
|
||||
formatter: tooLongFormatter,
|
||||
tooltip: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
selectedMode: 'single',
|
||||
radius: ['42%', '65%'],
|
||||
center: ['30%', '50%'],
|
||||
data: [],
|
||||
label: {
|
||||
formatter: '{d}%'
|
||||
},
|
||||
tooltip: {
|
||||
formatter: function (param, index, callback) {
|
||||
return `${param.name}: ${unitConvert(param.value, param.data.unitType).join(' ')}`
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
const ipHostedDomain = {
|
||||
color: chartColor,
|
||||
animation: false,
|
||||
tooltip: {
|
||||
show: true
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
type: 'plain',
|
||||
right: '8%',
|
||||
top: 'middle',
|
||||
icon: 'circle',
|
||||
itemWidth: 10, // 设置宽度
|
||||
itemHeight: 10, // 设置高度
|
||||
itemGap: 20,
|
||||
tooltip: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
selectedMode: 'single',
|
||||
radius: ['42%', '65%'],
|
||||
center: ['36%', '50%'],
|
||||
data: [],
|
||||
label: {
|
||||
formatter: '{d}%'
|
||||
},
|
||||
tooltip: {
|
||||
formatter: function (param, index, callback) {
|
||||
return `${param.name}: ${unitConvert(param.value, param.data.unitType).join(' ')}`
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
const singleValueLine = {
|
||||
tooltip: {
|
||||
show: true,
|
||||
enterable: true,
|
||||
showContent: true,
|
||||
appendToBody: true,
|
||||
trigger: 'axis',
|
||||
textStyle: {
|
||||
width: '20px',
|
||||
overflow: 'truncate'
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
show: false
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false
|
||||
},
|
||||
animation: false,
|
||||
grid: {
|
||||
left: 0,
|
||||
bottom: 2,
|
||||
top: 5,
|
||||
right: 0
|
||||
},
|
||||
color: chartColor,
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
legendHoverLink: false,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: '#81C9FF',
|
||||
lineStyle: {
|
||||
width: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
data: [],
|
||||
showSymbol: false,
|
||||
areaStyle: { color: '#C9EAFF' }
|
||||
}
|
||||
]
|
||||
}
|
||||
import { axisFormatter } from '@/views/charts/charts/tools'
|
||||
import { chartColor } from '@/utils/constants'
|
||||
|
||||
export const entityListLineOption = {
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
@@ -336,7 +9,7 @@ export const entityListLineOption = {
|
||||
width: '20px',
|
||||
overflow: 'truncate'
|
||||
},
|
||||
formatter: axiosFormatter,
|
||||
formatter: axisFormatter,
|
||||
show: true,
|
||||
className: 'nz-chart-tooltip',
|
||||
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);max-width: 300px !important'
|
||||
@@ -376,461 +49,3 @@ export const entityListLineOption = {
|
||||
}
|
||||
]
|
||||
}
|
||||
const relationShip = {
|
||||
grid: {
|
||||
left: 0,
|
||||
bottom: 50,
|
||||
top: 80,
|
||||
right: 0
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'graph',
|
||||
layout: 'force',
|
||||
symbolSize: 40,
|
||||
roam: true,
|
||||
force: {
|
||||
repulsion: 350
|
||||
},
|
||||
draggable: true,
|
||||
label: { show: true },
|
||||
edgeSymbol: ['none', 'arrow'],
|
||||
edgeSymbolSize: 7,
|
||||
data: [],
|
||||
links: []
|
||||
}
|
||||
]
|
||||
}
|
||||
const sankey = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
triggerOn: 'mousemove'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'sankey',
|
||||
data: [],
|
||||
links: [],
|
||||
right: '5%',
|
||||
top: 50,
|
||||
bottom: 100,
|
||||
levels: [
|
||||
{
|
||||
depth: 0,
|
||||
itemStyle: {
|
||||
color: '#47D49C'
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
}, {
|
||||
depth: 1,
|
||||
itemStyle: {
|
||||
color: '#A69BF5'
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
}, {
|
||||
depth: 2,
|
||||
itemStyle: {
|
||||
color: '#73A0FA'
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#999'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
const ipOpenPortBar = {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisTick: { show: false },
|
||||
axisLine: { show: false }
|
||||
},
|
||||
grid: {
|
||||
top: 30,
|
||||
left: 60,
|
||||
right: 50,
|
||||
bottom: 50
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false
|
||||
},
|
||||
series: [{
|
||||
barWidth: 38,
|
||||
data: [],
|
||||
type: 'bar',
|
||||
label: { show: true, position: 'top' },
|
||||
barCategoryGap: '10%'
|
||||
}]
|
||||
}
|
||||
const categoryBar = {
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
trigger: 'axis',
|
||||
textStyle: {
|
||||
width: '20px',
|
||||
overflow: 'truncate'
|
||||
},
|
||||
formatter: categoryVerticalFormatter,
|
||||
show: true,
|
||||
className: 'nz-chart-tooltip',
|
||||
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);max-width: 300px !important'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisTick: { show: false },
|
||||
axisLine: { show: false }
|
||||
},
|
||||
grid: {
|
||||
top: 20,
|
||||
left: 10,
|
||||
right: 25,
|
||||
bottom: 20,
|
||||
containLabel: true
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisTick: { show: false },
|
||||
axisLine: { show: false }
|
||||
},
|
||||
color: chartColor,
|
||||
series: [{
|
||||
barWidth: 15,
|
||||
data: [],
|
||||
type: 'bar',
|
||||
label: { show: false },
|
||||
barCategoryGap: '10%',
|
||||
itemStyle: {
|
||||
color: function (params) {
|
||||
return getCharBartColor([params.dataIndex])
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
const timeBar = {
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
trigger: 'axis',
|
||||
textStyle: {
|
||||
width: '20px',
|
||||
overflow: 'truncate'
|
||||
},
|
||||
formatter: timeVerticalFormatter,
|
||||
show: true,
|
||||
className: 'nz-chart-tooltip',
|
||||
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);max-width: 300px !important'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
axisTick: { show: false },
|
||||
axisLine: { show: false },
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
// rotate: -40, //设置日期显示样式(倾斜度)
|
||||
formatter: function (value) { // 在这里写你需要的时间格式
|
||||
const t_date = new Date(value)
|
||||
return [t_date.getMonth() + 1, t_date.getDate()].join('/') + ' ' + [t_date.getHours(), t_date.getMinutes()].join(':')
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
top: 20,
|
||||
left: 25,
|
||||
right: 25,
|
||||
bottom: 20,
|
||||
containLabel: true
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisTick: { show: false },
|
||||
axisLine: { show: false },
|
||||
axisLabel: {
|
||||
formatter: function (value, index, a, b) {
|
||||
return unitConvert(value, unitTypes.number).join(' ')
|
||||
}
|
||||
},
|
||||
minInterval: 1
|
||||
},
|
||||
color: chartColor,
|
||||
series: [{
|
||||
barWidth: 15,
|
||||
data: [],
|
||||
type: 'bar',
|
||||
label: { show: false },
|
||||
barCategoryGap: '10%',
|
||||
itemStyle: {
|
||||
color: function (params) {
|
||||
return getCharBartColor([params.dataIndex])
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
const typeOptionMappings = [
|
||||
{ value: 11, option: line }, // 常规折线图
|
||||
{ value: 12, option: lineWithStatistics }, // 带统计表格的折线图
|
||||
{ value: 13, option: lineStack }, // 折线堆叠图
|
||||
{ value: 22, option: ipOpenPortBar }, // ip详情--开放端口的柱状图
|
||||
{ value: 23, option: timeBar }, // 矿机所属单位
|
||||
{ value: 24, option: categoryBar }, // 挖矿事件统计
|
||||
{ value: 31, option: pieWithTable }, // 常规折线图
|
||||
{ value: 33, option: ipHostedDomain }, // ip详情--托管域名
|
||||
{ value: 34, option: ipHostedDomain }, // app详情--相关域名
|
||||
{ value: 42, option: relationShip }, // 关系图
|
||||
{ value: 43, option: sankey }, // 桑基图
|
||||
{ value: 52, option: singleValueLine }
|
||||
]
|
||||
const typeCategory = {
|
||||
MAP: 'map',
|
||||
TABLE: 'table',
|
||||
ECHARTS: 'echarts',
|
||||
TITLE: 'title',
|
||||
SINGLE: 'singleValue',
|
||||
TABS: 'tabs'
|
||||
}
|
||||
export function getTypeCategory (type) {
|
||||
if (isMap(type)) {
|
||||
return typeCategory.MAP
|
||||
} else if (isEcharts(type)) {
|
||||
return typeCategory.ECHARTS
|
||||
} else if (isTable(type)) {
|
||||
return typeCategory.TABLE
|
||||
} else if (isSingleValue(type)) {
|
||||
return typeCategory.SINGLE
|
||||
} else if (isTitle(type)) {
|
||||
return typeCategory.TITLE
|
||||
} else if (isTabs(type)) {
|
||||
return typeCategory.TABS
|
||||
}
|
||||
}
|
||||
/* 柱状图:挖矿事件统计(time类型柱状图) */
|
||||
export function isEchartsTimeBar (type) {
|
||||
return type == 23
|
||||
}
|
||||
/* 柱状图:矿机所属单位(category类型柱状图) */
|
||||
export function isEchartsCategoryBar (type) {
|
||||
return type == 24
|
||||
}
|
||||
/* 饼图柱状图等 */
|
||||
export function isEcharts (type) {
|
||||
return type >= 11 && type <= 50
|
||||
}
|
||||
/* 折线,饼图 */
|
||||
export function isEchartsLineBar (type) {
|
||||
return type == 11 || type == 12 || type == 31 || type == 32 || type == 33 || type == 34
|
||||
}
|
||||
/* 地图 */
|
||||
export function isMap (type) {
|
||||
return type >= 1 && type <= 10
|
||||
}
|
||||
/* 连线地图 */
|
||||
export function isMapLine (type) {
|
||||
return type === 1
|
||||
}
|
||||
/* 色块地图 */
|
||||
export function isMapBlock (type) {
|
||||
return type === 2
|
||||
}
|
||||
/* 带统计的折线图 */
|
||||
export function isEchartsWithStatistics (type) {
|
||||
return type === 12
|
||||
}
|
||||
/* 关系图 */
|
||||
export function isRelationShip (type) {
|
||||
return type === 42
|
||||
}
|
||||
/* 桑基图 */
|
||||
export function isSankey (type) {
|
||||
return type === 43
|
||||
}
|
||||
/* 单值 */
|
||||
export function isSingleValue (type) {
|
||||
return type >= 51 && type <= 60
|
||||
}
|
||||
/* 带折线图的单值 */
|
||||
export function isSingleValueWithEcharts (type) {
|
||||
return type === 52
|
||||
}
|
||||
/* 带折线图的单值 */
|
||||
export function isSingleValueWithEchartsTemp (type) {
|
||||
return type === 55
|
||||
}
|
||||
/* 带Table的饼图 */
|
||||
export function isEchartsWithTable (type) {
|
||||
return type === 31
|
||||
}
|
||||
/* 普通饼图 */
|
||||
export function isEchartsPie (type) {
|
||||
return type === 32
|
||||
}
|
||||
/* table */
|
||||
export function isTable (type) {
|
||||
return type >= 61 && type <= 70
|
||||
}
|
||||
/* table */
|
||||
export function isActiveIpTable (type) {
|
||||
return type == 63
|
||||
}
|
||||
/* title */
|
||||
export function isTitle (type) {
|
||||
return type === 93
|
||||
}
|
||||
/* tabs */
|
||||
export function isTabs (type) {
|
||||
return type === 91
|
||||
}
|
||||
/* IP实体基本信息 */
|
||||
export function isIpBasicInfo (type) {
|
||||
return type === 4
|
||||
}
|
||||
/* IP实体开放端口 */
|
||||
export function isIpOpenPort (type) {
|
||||
return type === 22
|
||||
}
|
||||
/* IP实体托管域名 */
|
||||
export function isIpHostedDomain (type) {
|
||||
return type === 33
|
||||
}
|
||||
/* APP实体相关域名 */
|
||||
export function isAppRelatedDomain (type) {
|
||||
return type === 34
|
||||
}
|
||||
/* APP实体基本信息 */
|
||||
export function isAppBasicInfo (type) {
|
||||
return type === 82
|
||||
}
|
||||
/* DOMAIN实体Whois */
|
||||
export function isDomainWhois (type) {
|
||||
return type === 83
|
||||
}
|
||||
/* DOMAIN实体DNS记录 */
|
||||
export function isDomainDnsRecord (type) {
|
||||
return type === 84
|
||||
}
|
||||
/* 近期挖矿事件 */
|
||||
export function isCryptocurrencyEventList (type) {
|
||||
return type === 85
|
||||
}
|
||||
/* 组 */
|
||||
export function isGroup (type) {
|
||||
return type === 94
|
||||
}
|
||||
/* 实体详情块 */
|
||||
export function isBlock (type) {
|
||||
return type === 95
|
||||
}
|
||||
export function getOption (type) {
|
||||
const mapping = typeOptionMappings.find(m => m.value === type)
|
||||
return mapping && mapping.option ? _.cloneDeep(mapping.option) : null
|
||||
}
|
||||
export const layoutConstant = {
|
||||
HEADER: 'header',
|
||||
FOOTER: 'footer'
|
||||
}
|
||||
export function getLayout (type) {
|
||||
const layout = []
|
||||
if (!isSingleValue(type) && !isTitle(type)) {
|
||||
layout.push(layoutConstant.HEADER)
|
||||
}
|
||||
if (type === 12 || type === 31) {
|
||||
layout.push(layoutConstant.FOOTER)
|
||||
}
|
||||
return layout
|
||||
}
|
||||
|
||||
function tooLongFormatter (name) {
|
||||
return format.truncateText(name, 110, '12')
|
||||
}
|
||||
function axiosFormatter (params) {
|
||||
let str = '<div>'
|
||||
params.forEach((item, i) => {
|
||||
const tData = item.data[0]
|
||||
if (i === 0) {
|
||||
str += '<div style="margin-bottom: 5px">'
|
||||
str += window.$dayJs.tz(tData).format('YYYY-MM-DD HH:mm:ss')
|
||||
str += '</div>'
|
||||
}
|
||||
str += '<div class="cn-chart-tooltip-box">'
|
||||
str += item.marker
|
||||
str += `<span class="cn-chart-tooltip-content">
|
||||
${item.seriesName}
|
||||
</span>`
|
||||
str += `<span class="cn-chart-tooltip-value">
|
||||
${unitConvert(item.data[1], item.data[2]).join(' ')}
|
||||
</span>`
|
||||
str += '</div>'
|
||||
})
|
||||
str += '</div>'
|
||||
return str
|
||||
}
|
||||
|
||||
export function timeVerticalFormatter (params) {
|
||||
let str = '<div>'
|
||||
params.forEach((item, i) => {
|
||||
const tData = item.data[0]
|
||||
if (i === 0) {
|
||||
str += '<div style="margin-bottom: 5px">'
|
||||
str += window.$dayJs.tz(tData).format('YYYY-MM-DD HH:mm:ss')
|
||||
str += '</div>'
|
||||
}
|
||||
str += '<div class="cn-chart-tooltip-box">'
|
||||
str += item.marker
|
||||
str += `<span class="cn-chart-tooltip-content">
|
||||
${item.seriesName}
|
||||
</span>`
|
||||
str += `<span class="cn-chart-tooltip-value">
|
||||
${unitConvert(item.data[1], item.data[2]).join(' ')}
|
||||
</span>`
|
||||
str += '</div>'
|
||||
})
|
||||
str += '</div>'
|
||||
return str
|
||||
}
|
||||
|
||||
export function timeHorizontalFormatter (params) {
|
||||
let str = '<div>'
|
||||
params.forEach((item, i) => {
|
||||
const tData = item.data[1]
|
||||
if (i === 0) {
|
||||
str += '<div style="margin-bottom: 5px">'
|
||||
str += window.$dayJs.tz(tData).format('YYYY-MM-DD HH:mm:ss')
|
||||
str += '</div>'
|
||||
}
|
||||
str += '<div class="cn-chart-tooltip-box">'
|
||||
str += item.marker
|
||||
str += `<span class="cn-chart-tooltip-content">
|
||||
${item.seriesName}
|
||||
</span>`
|
||||
str += `<span class="cn-chart-tooltip-value">
|
||||
${unitConvert(item.data[0], item.data[2]).join(' ')}
|
||||
</span>`
|
||||
str += '</div>'
|
||||
})
|
||||
str += '</div>'
|
||||
return str
|
||||
}
|
||||
export function categoryHorizontalFormatter (params) {
|
||||
let str = '<div>'
|
||||
params.forEach((item, i) => {
|
||||
str += '<div class="cn-chart-tooltip-box">'
|
||||
str += item.data[1] + ': ' + item.data[0]
|
||||
str += '</div>'
|
||||
})
|
||||
str += '</div>'
|
||||
return str
|
||||
}
|
||||
export function categoryVerticalFormatter (params) {
|
||||
let str = '<div>'
|
||||
params.forEach((item, i) => {
|
||||
str += '<div class="cn-chart-tooltip-box">'
|
||||
str += item.data[0] + ': ' + item.data[1]
|
||||
str += '</div>'
|
||||
})
|
||||
str += '</div>'
|
||||
return str
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import { chartColor } from '@/views/charts/charts/chart-options'
|
||||
import { axisFormatter, tooLongFormatter } from '../tools'
|
||||
import { unitTypes, chartColor } from '@/utils/constants'
|
||||
import { axisFormatter, tooLongFormatter } from '@/views/charts/charts/tools'
|
||||
|
||||
export const line = {
|
||||
tooltip: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { chartColor } from '@/views/charts/charts/chart-options'
|
||||
import { tooLongFormatter } from '../tools'
|
||||
import { chartColor } from '@/utils/constants'
|
||||
|
||||
export const pieWithTable = {
|
||||
tooltip: {
|
||||
|
||||
@@ -6,11 +6,8 @@ import { ipOpenPortBar, timeBar, categoryBar } from './options/bar'
|
||||
import { pieWithTable, ipHostedDomain } from './options/pie'
|
||||
import { relationShip } from './options/graph'
|
||||
import { sankey } from './options/sankey'
|
||||
import { chartColor } from '@/utils/constants'
|
||||
|
||||
export const chartColor = ['#5370C6', '#90CC74', '#FAC858', '#EE6666',
|
||||
'#73BFDE', '#3BA172', '#FC8452', '#9960B4',
|
||||
'#E97CCC', '#FEA69E', '#0F8AB2', '#57CBAC',
|
||||
'#5888BC', '#63B6AC', '#EDC6B2', '#D5746B']
|
||||
export const chartBarColor = ['#0F8AB2', '#57CBAC']
|
||||
export function getChartColor (index) {
|
||||
return chartColor[index % chartColor.length]
|
||||
@@ -66,6 +63,10 @@ export function isMapLine (type) {
|
||||
export function isMapBlock (type) {
|
||||
return type === 2
|
||||
}
|
||||
/* 散点地图 */
|
||||
export function isMapPoint (type) {
|
||||
return type === 3
|
||||
}
|
||||
/* 普通折线图 */
|
||||
export function isEchartsLine (type) {
|
||||
return type === 11
|
||||
@@ -106,8 +107,8 @@ export function isEchartsWithTable (type) {
|
||||
export function isTable (type) {
|
||||
return type >= 61 && type <= 70
|
||||
}
|
||||
/* current table */
|
||||
export function isCurrentTable (type) {
|
||||
/* basic table */
|
||||
export function isBasicTable (type) {
|
||||
return type === 61
|
||||
}
|
||||
/* table */
|
||||
@@ -158,11 +159,11 @@ export function isAlarmInfo (type) {
|
||||
export function isCryptocurrencyEventList (type) {
|
||||
return type === 85
|
||||
}
|
||||
/* 单支持情况统计 */
|
||||
/* 单支持情况统计 */
|
||||
export function isSingleSupportStatistics (type) {
|
||||
return type === 86
|
||||
}
|
||||
/* 两个支持情况统计 */
|
||||
/* 两个支持情况统计 */
|
||||
export function isTwoSupportStatistics (type) {
|
||||
return type === 87
|
||||
}
|
||||
|
||||
@@ -14,9 +14,16 @@
|
||||
></detection-search>
|
||||
<!-- 内容区 -->
|
||||
<div class="explorer-container" style="height: calc(100% - 20px); flex-direction: column">
|
||||
<div class="detection__event-severity-bar" :id="`eventSeverityTrendBar${pageType}`">
|
||||
<detection-no-data v-if="isEventSeverityNoData"></detection-no-data>
|
||||
<div class="entity__loading" style="background: #eff2f5;opacity: .6;" v-show="loading">
|
||||
<i class="el-icon-loading"></i>
|
||||
</div>
|
||||
<template v-if="isEventSeverityNoData">
|
||||
<div class="no-data detection__event-severity-bar" >No data</div>
|
||||
</template>
|
||||
<template v-if="!isEventSeverityNoData">
|
||||
<div class="detection__event-severity-bar" :id="`eventSeverityTrendBar${pageType}`">
|
||||
</div>
|
||||
</template>
|
||||
<div style="display: flex; flex-grow: 1">
|
||||
<detection-filter
|
||||
:filter-data="filterData[pageType]"
|
||||
@@ -31,25 +38,38 @@
|
||||
<div class="chart-header">
|
||||
<div class="chart-header__title">{{$t('detection.severity')}}</div>
|
||||
</div>
|
||||
<div class="chart-content" :id="`eventSeverityPie${pageType}`">
|
||||
<detection-no-data v-if="isStatisticsSeverityNoData"></detection-no-data>
|
||||
</div>
|
||||
<template v-if="isStatisticsSeverityNoData">
|
||||
<div class="no-data chart-content" >No data</div>
|
||||
</template>
|
||||
<template v-if="!isStatisticsSeverityNoData">
|
||||
<div class="chart-content" :id="`eventSeverityPie${pageType}`">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
<div class="statistics__category">
|
||||
<div class="chart-header">
|
||||
<div class="chart-header__title">{{$t('detection.categoryProportion')}}</div>
|
||||
</div>
|
||||
<div class="chart-content" :id="`detectionCategoryPer${pageType}`">
|
||||
<detection-no-data v-if="isStatisticsCategoryNoData"></detection-no-data>
|
||||
</div>
|
||||
<template v-if="isStatisticsCategoryNoData">
|
||||
<div class="no-data chart-content" >No data</div>
|
||||
</template>
|
||||
<template v-if="!isStatisticsCategoryNoData">
|
||||
<div class="chart-content" :id="`detectionCategoryPer${pageType}`">
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="statistics__active-attack">
|
||||
<div class="chart-header">
|
||||
<div class="chart-header__title">{{pageType === detectionPageType.securityEvent ? $t('detection.activeAttacker') : $t('detections.activeEntity')}}</div>
|
||||
</div>
|
||||
<div class="chart-content" style="" :id="`detectionActiveAttacker${pageType}`">
|
||||
<detection-no-data v-if="isStatisticsActiveAttackNoData"></detection-no-data>
|
||||
</div>
|
||||
<template v-if="isStatisticsActiveAttackNoData">
|
||||
<div class="no-data chart-content" >No data</div>
|
||||
</template>
|
||||
<template v-if="!isStatisticsActiveAttackNoData">
|
||||
<div class="chart-content" :id="`detectionActiveAttacker${pageType}`">
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<detection-list
|
||||
@@ -87,7 +107,7 @@ import DetectionFilter from '@/views/detections/DetectionFilter'
|
||||
import DetectionList from '@/views/detections/DetectionList'
|
||||
import Pagination from '@/components/common/Pagination'
|
||||
import { defaultPageSize, detectionPageType } from '@/utils/constants'
|
||||
import { getNowTime, getSecond } from '@/utils/date-util'
|
||||
import { getNowTime, getSecond, rTime } from '@/utils/date-util'
|
||||
import { ref } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { multipleBarOption, pieForSeverity, activeAttackBar, getAttackColor, getSeverityColor, getSeriesIndex } from '@/views/detections/options/detectionOptions'
|
||||
@@ -183,8 +203,8 @@ export default {
|
||||
data: [] // 从接口动态获取,本项在获得数据后需要特殊处理左边框颜色
|
||||
},
|
||||
{
|
||||
title: this.$t('detections.securityType'),
|
||||
column: 'securityType',
|
||||
title: this.$t('detections.eventType'),
|
||||
column: 'eventType',
|
||||
collapse: false,
|
||||
value: [],
|
||||
data: [] // 从接口动态获取
|
||||
@@ -193,24 +213,122 @@ export default {
|
||||
},
|
||||
listData: [],
|
||||
listLoading: false,
|
||||
eventSeverityData: [],
|
||||
severityPerOption: null,
|
||||
severityPerData: [],
|
||||
categoryPerOption: null,
|
||||
categoryPerData: [],
|
||||
activeAttackOption: null,
|
||||
activeAttackData: [],
|
||||
isEventSeverityNoData: true,
|
||||
isStatisticsSeverityNoData: true,
|
||||
isStatisticsCategoryNoData: true,
|
||||
isStatisticsActiveAttackNoData: true
|
||||
eventSeverityData: [],
|
||||
statisticsSeverityData: [],
|
||||
statisticsCategoryData: [],
|
||||
statisticsActiveAttackData: [],
|
||||
isEventSeverityNoData: false,
|
||||
isStatisticsSeverityNoData: false,
|
||||
isStatisticsCategoryNoData: false,
|
||||
isStatisticsActiveAttackNoData: false,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始化顶部大柱状图
|
||||
initEventSeverityTrendData (params) {
|
||||
this.loading = true
|
||||
getData(api.detection[this.pageType].eventSeverityTrend, params).then(data => {
|
||||
/* data = [
|
||||
{
|
||||
"stat_time": "2022-01-01T10:07:03.008Z",
|
||||
"event_severity": "critical",
|
||||
"count": 5
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-02T10:07:03.008Z",
|
||||
"event_severity": "critical",
|
||||
"count": 15
|
||||
},{
|
||||
"stat_time": "2022-01-03T10:07:03.008Z",
|
||||
"event_severity": "critical",
|
||||
"count": 25
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-04T10:07:03.008Z",
|
||||
"event_severity": "critical",
|
||||
"count": 7
|
||||
},{
|
||||
"stat_time": "2022-01-01T10:07:03.008Z",
|
||||
"event_severity": "high",
|
||||
"count": 8
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-02T10:07:03.008Z",
|
||||
"event_severity": "high",
|
||||
"count": 2
|
||||
},{
|
||||
"stat_time": "2022-01-03T10:07:03.008Z",
|
||||
"event_severity": "high",
|
||||
"count": 25
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-04T10:07:03.008Z",
|
||||
"event_severity": "high",
|
||||
"count": 7
|
||||
},{
|
||||
"stat_time": "2022-01-01T10:07:03.008Z",
|
||||
"event_severity": "medium",
|
||||
"count": 9
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-02T10:07:03.008Z",
|
||||
"event_severity": "medium",
|
||||
"count": 15
|
||||
},{
|
||||
"stat_time": "2022-01-03T10:07:03.008Z",
|
||||
"event_severity": "medium",
|
||||
"count": 35
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-04T10:07:03.008Z",
|
||||
"event_severity": "medium",
|
||||
"count": 7
|
||||
},{
|
||||
"stat_time": "2022-01-01T10:07:03.008Z",
|
||||
"event_severity": "low",
|
||||
"count": 5
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-02T10:07:03.008Z",
|
||||
"event_severity": "low",
|
||||
"count": 1
|
||||
},{
|
||||
"stat_time": "2022-01-03T10:07:03.008Z",
|
||||
"event_severity": "low",
|
||||
"count": 25
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-04T10:07:03.008Z",
|
||||
"event_severity": "low",
|
||||
"count": 17
|
||||
},{
|
||||
"stat_time": "2022-01-01T10:07:03.008Z",
|
||||
"event_severity": "info",
|
||||
"count": 5
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-02T10:07:03.008Z",
|
||||
"event_severity": "info",
|
||||
"count": 15
|
||||
},{
|
||||
"stat_time": "2022-01-03T10:07:03.008Z",
|
||||
"event_severity": "info",
|
||||
"count": 25
|
||||
},
|
||||
{
|
||||
"stat_time": "2022-01-04T10:07:03.008Z",
|
||||
"event_severity": "info",
|
||||
"count": 27
|
||||
},
|
||||
] */
|
||||
/* data2 = [
|
||||
{
|
||||
legend: 'critical',
|
||||
values: [[1435781430781, '999'], [1435781431781, '222'], [1435781432781, '11'], [1435781433781, '3']]
|
||||
@@ -229,23 +347,40 @@ export default {
|
||||
values: [[1435781430781, '5'], [1435781431781, '7'], [1435781432781, '5'], [1435781433781, '8']]
|
||||
}
|
||||
] */
|
||||
this.eventSeverityData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
const chartDom = document.getElementById(`eventSeverityTrendBar${this.pageType}`)
|
||||
const detectionChart = echarts.init(chartDom)
|
||||
const eventSeverityTrendOption = this.$_.cloneDeep(multipleBarOption)
|
||||
const dataMap = new Map()
|
||||
data.forEach(item => {
|
||||
eventSeverityTrendOption.series[Number(getSeriesIndex(item.legend))].data = item.values.map(v => Number(v[1]))
|
||||
if (item.eventSeverity) {
|
||||
if (!dataMap.has(item.eventSeverity)) {
|
||||
const count = [[item.statTime, item.count]]
|
||||
dataMap.set(item.eventSeverity, count)
|
||||
} else {
|
||||
dataMap.get(item.eventSeverity).push([item.statTime, item.count])
|
||||
}
|
||||
}
|
||||
})
|
||||
eventSeverityTrendOption.xAxis.data = data[0].values.map(v => [window.$dayJs.tz(Number(v[0])).format('YYYY-MM-DD HH:mm:ss')])
|
||||
this.$nextTick(() => {
|
||||
detectionChart.setOption(eventSeverityTrendOption)
|
||||
const chartDom = document.getElementById(`eventSeverityTrendBar${this.pageType}`)
|
||||
const eventSeverityTrendOption = this.$_.cloneDeep(multipleBarOption)
|
||||
dataMap.forEach(function (value, key) {
|
||||
eventSeverityTrendOption.series[Number(getSeriesIndex(key))].data = value.map(v => Number(v[1]))
|
||||
})
|
||||
this.isEventSeverityNoData = false
|
||||
eventSeverityTrendOption.xAxis.data = dataMap.get('critical').map(v => rTime(v[0]))
|
||||
const detectionChart = echarts.init(chartDom)
|
||||
detectionChart.setOption(eventSeverityTrendOption)
|
||||
// this.isEventSeverityNoData = false
|
||||
} else {
|
||||
// this.isEventSeverityNoData = true
|
||||
}
|
||||
}).catch(error => {
|
||||
|
||||
}).finally(() => {
|
||||
this.$nextTick(() => {
|
||||
this.loading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 初始化左侧事件严重等级和小饼图
|
||||
initEventSeverityData (params) {
|
||||
getData(api.detection[this.pageType].eventSeverity, params).then(data => {
|
||||
@@ -267,6 +402,8 @@ export default {
|
||||
count: 300
|
||||
}
|
||||
] */
|
||||
this.statisticsSeverityData = data
|
||||
// this.isStatisticsSeverityNoData = true
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
this.filterData[this.pageType][0].data = data.map(r => ({ label: r.eventSeverity, value: r.eventSeverity, count: r.count }))
|
||||
const eventSeverityOption = this.$_.cloneDeep(pieForSeverity)
|
||||
@@ -276,7 +413,28 @@ export default {
|
||||
const chartDom = document.getElementById(`eventSeverityPie${this.pageType}`)
|
||||
const detectionChart = echarts.init(chartDom)
|
||||
detectionChart.setOption(eventSeverityOption)
|
||||
this.isStatisticsSeverityNoData = false
|
||||
// this.isStatisticsSeverityNoData = false
|
||||
}
|
||||
}).catch(error => {
|
||||
|
||||
})
|
||||
},
|
||||
initEventTypeData (params) {
|
||||
getData(api.detection[this.pageType].eventType, params).then(data => {
|
||||
this.statisticsCategoryData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
this.filterData[this.pageType][1].data = data.map(r => ({
|
||||
label: r.eventType,
|
||||
value: r.eventType,
|
||||
count: r.count
|
||||
}))
|
||||
const chartDom = document.getElementById(`detectionCategoryPer${this.pageType}`)
|
||||
const detectionChart = echarts.init(chartDom)
|
||||
const securityTypeOption = this.$_.cloneDeep(pieForSeverity)
|
||||
securityTypeOption.series[0].data = data.map(d => {
|
||||
return { value: d.count, name: d.eventType }
|
||||
})
|
||||
detectionChart.setOption(securityTypeOption)
|
||||
}
|
||||
}).catch(error => {
|
||||
|
||||
@@ -284,41 +442,20 @@ export default {
|
||||
},
|
||||
initSecurityTypeData (params) {
|
||||
getData(api.detection[this.pageType].securityType, params).then(data => {
|
||||
/* data = [
|
||||
{
|
||||
attackType: 'command and control',
|
||||
count: 1048
|
||||
}, {
|
||||
attackType: 'payload delivery',
|
||||
count: 735
|
||||
}, {
|
||||
attackType: 'cryptomining',
|
||||
count: 580
|
||||
}, {
|
||||
attackType: 'phishing',
|
||||
count: 484
|
||||
}, {
|
||||
attackType: 'dga',
|
||||
count: 300
|
||||
}, {
|
||||
attackType: 'ddos',
|
||||
count: 50
|
||||
}
|
||||
] */
|
||||
this.statisticsCategoryData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
this.filterData[this.pageType][1].data = data.map(r => ({
|
||||
label: r.attackType,
|
||||
value: r.attackType,
|
||||
label: r.securityType,
|
||||
value: r.securityType,
|
||||
count: r.count
|
||||
}))
|
||||
const chartDom = document.getElementById(`detectionCategoryPer${this.pageType}`)
|
||||
const detectionChart = echarts.init(chartDom)
|
||||
const securityTypeOption = this.$_.cloneDeep(pieForSeverity)
|
||||
securityTypeOption.series[0].data = data.map(d => {
|
||||
return { value: d.count, name: d.attackType, itemStyle: { color: getAttackColor(d.attackType) } }
|
||||
return { value: d.count, name: d.securityType, itemStyle: { color: getAttackColor(d.securityType) } }
|
||||
})
|
||||
detectionChart.setOption(securityTypeOption)
|
||||
this.isStatisticsCategoryNoData = false
|
||||
}
|
||||
}).catch(error => {
|
||||
|
||||
@@ -376,6 +513,8 @@ export default {
|
||||
count: 55355
|
||||
}
|
||||
] */
|
||||
|
||||
this.statisticsActiveAttackData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
this.filterData[this.pageType][4].data = data.map(r => ({
|
||||
label: r.offenderIp,
|
||||
@@ -395,7 +534,7 @@ export default {
|
||||
return [d.count, d.offenderIp]
|
||||
}).reverse()
|
||||
detectionChart.setOption(offenderIpOption)
|
||||
this.isStatisticsActiveAttackNoData = false
|
||||
// this.isStatisticsActiveAttackNoData = false
|
||||
}
|
||||
}).catch(error => {
|
||||
|
||||
@@ -550,15 +689,17 @@ export default {
|
||||
count: 50
|
||||
}
|
||||
] */
|
||||
const chartDom = document.getElementById(`detectionActiveAttacker${this.pageType}`)
|
||||
const detectionChart = echarts.init(chartDom)
|
||||
const option = this.$_.cloneDeep(activeAttackBar)
|
||||
option.series[0].data = data.map(d => {
|
||||
return [d.count, d.name]
|
||||
}).reverse()
|
||||
detectionChart.setOption(option)
|
||||
this.statisticsActiveAttackData = data
|
||||
if (!this.$_.isEmpty(data)) {
|
||||
const chartDom = document.getElementById(`detectionActiveAttacker${this.pageType}`)
|
||||
const detectionChart = echarts.init(chartDom)
|
||||
const option = this.$_.cloneDeep(activeAttackBar)
|
||||
option.series[0].data = data.map(d => {
|
||||
return [d.count, d.name]
|
||||
}).reverse()
|
||||
detectionChart.setOption(option)
|
||||
}
|
||||
}).catch(error => {
|
||||
|
||||
})
|
||||
},
|
||||
computeFilterPage (data) {
|
||||
@@ -571,7 +712,9 @@ export default {
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
q: this.q
|
||||
q: this.q,
|
||||
pageSize: this.pageObj.pageSize,
|
||||
pageNo: this.pageObj.pageNo
|
||||
}
|
||||
getData(api.detection[this.pageType].listBasic, params).then(data => {
|
||||
if (this.pageType === detectionPageType.securityEvent) {
|
||||
@@ -873,15 +1016,28 @@ export default {
|
||||
this.listData = data
|
||||
}).catch(error => {
|
||||
|
||||
})
|
||||
getData(api.detection[this.pageType].listCount, params).then(data => {
|
||||
this.pageObj.total = data
|
||||
}).catch(error => {
|
||||
|
||||
})
|
||||
},
|
||||
timeRefreshChange () {
|
||||
this.initNoData()
|
||||
if (!this.$refs.dateTimeRange.isCustom) {
|
||||
const value = this.timeFilter.dateRangeValue
|
||||
this.$refs.dateTimeRange.quickChange(value)
|
||||
}
|
||||
},
|
||||
initNoData () {
|
||||
this.isEventSeverityNoData = false
|
||||
this.isStatisticsSeverityNoData = false
|
||||
this.isStatisticsCategoryNoData = false
|
||||
this.isStatisticsActiveAttackNoData = false
|
||||
},
|
||||
reload (s, e, v) {
|
||||
this.initNoData()
|
||||
this.dateTimeRangeChange(s, e, v)
|
||||
},
|
||||
// methods
|
||||
@@ -889,6 +1045,7 @@ export default {
|
||||
this.timeFilter = { startTime: s, endTime: e, dateRangeValue: v }
|
||||
},
|
||||
search (metaList, formatSql) {
|
||||
this.initNoData()
|
||||
if (formatSql) {
|
||||
this.q = formatSql
|
||||
this.metaList = metaList
|
||||
@@ -900,7 +1057,16 @@ export default {
|
||||
this.queryList()
|
||||
this.queryListTotal()
|
||||
},
|
||||
resetFilterData () {
|
||||
this.filterData.securityEvent.forEach(d => {
|
||||
d.data = []
|
||||
})
|
||||
this.filterData.performanceEvent.forEach(d => {
|
||||
d.data = []
|
||||
})
|
||||
},
|
||||
queryFilter () {
|
||||
this.resetFilterData()
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
@@ -908,14 +1074,15 @@ export default {
|
||||
}
|
||||
this.initEventSeverityTrendData(params)
|
||||
this.initEventSeverityData(params)
|
||||
this.initSecurityTypeData(params)
|
||||
if (this.pageType === detectionPageType.securityEvent) {
|
||||
this.initOffenderIpData(params)
|
||||
this.initOffenderLocationData(params)
|
||||
this.initVictimIpData(params)
|
||||
this.initVictimLocationData(params)
|
||||
this.initSecurityTypeData(params)
|
||||
} else if (this.pageType === detectionPageType.performanceEvent) {
|
||||
this.initActiveEntity(params)
|
||||
this.initEventTypeData(params)
|
||||
}
|
||||
},
|
||||
queryListTotal () {
|
||||
@@ -961,6 +1128,68 @@ export default {
|
||||
this.queryList()
|
||||
},
|
||||
watch: {
|
||||
eventSeverityData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!n || n.length === 0) {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.isEventSeverityNoData = true
|
||||
// this.$set(this.isEventSeverityNoData ,true)
|
||||
this.loading = false
|
||||
}, 500)
|
||||
} else {
|
||||
clearTimeout(this.timeout)
|
||||
// this.$set(this.isEventSeverityNoData ,false)
|
||||
this.isEventSeverityNoData = false
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
},
|
||||
statisticsSeverityData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!n || n.length === 0) {
|
||||
this.timeout = setTimeout(() => {
|
||||
// this.$set(this.isStatisticsSeverityNoData ,true)
|
||||
this.isStatisticsSeverityNoData = true
|
||||
}, 500)
|
||||
} else {
|
||||
clearTimeout(this.timeout)
|
||||
// this.$set(this.isStatisticsSeverityNoData ,false)
|
||||
this.isStatisticsSeverityNoData = false
|
||||
}
|
||||
}
|
||||
},
|
||||
statisticsCategoryData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!n || n.length === 0) {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.isStatisticsCategoryNoData = true
|
||||
// this.$set(this.isStatisticsCategoryNoData ,true)
|
||||
}, 500)
|
||||
} else {
|
||||
clearTimeout(this.timeout)
|
||||
// this.$set(this.isStatisticsCategoryNoData ,false)
|
||||
this.isStatisticsCategoryNoData = false
|
||||
}
|
||||
}
|
||||
},
|
||||
statisticsActiveAttackData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!n || n.length === 0) {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.isStatisticsActiveAttackNoData = true
|
||||
// this.$set(this.isStatisticsActiveAttackNoData ,true)
|
||||
}, 500)
|
||||
} else {
|
||||
clearTimeout(this.timeout)
|
||||
// this.$set(this.isStatisticsActiveAttackNoData ,false)
|
||||
this.isStatisticsActiveAttackNoData = false
|
||||
}
|
||||
}
|
||||
},
|
||||
timeFilter (n) {
|
||||
this.search(this.metaList, this.q)
|
||||
},
|
||||
@@ -1016,7 +1245,6 @@ export default {
|
||||
setup () {
|
||||
const { params } = useRoute()
|
||||
const pageType = params.typeName
|
||||
|
||||
const dateRangeValue = 60
|
||||
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||
const timeFilter = ref({ startTime, endTime, dateRangeValue })
|
||||
|
||||
@@ -18,6 +18,9 @@ export function getSeriesIndex (type) {
|
||||
return mapping && mapping.index ? _.cloneDeep(mapping.index) : null
|
||||
}
|
||||
|
||||
export const activeAttackColor = ['#51a9ee', '#49bcf2', '#4ad7eb', '#4cd4c8',
|
||||
'#7acc7e', '#a7db69']
|
||||
|
||||
const activeAttackColorMappings = [
|
||||
{ value: 'command and control', color: '#51a9ee' },
|
||||
{ value: 'payload delivery', color: '#49bcf2' },
|
||||
@@ -149,7 +152,7 @@ export const pieForSeverity = {
|
||||
tooltip: {
|
||||
appendToBody: true
|
||||
},
|
||||
color: chartColor,
|
||||
color: activeAttackColor,
|
||||
animation: false,
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="overview__title">Fields</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{$t('entities.category')}}</div>
|
||||
<div class="row__content">{{basicInfo.appCategory}}</div>
|
||||
<div class="row__content">{{basicInfo.appCategory || '-'}}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{$t('entities.subcategory')}}</div>
|
||||
@@ -35,8 +35,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import { api, getData } from '@/utils/api'
|
||||
import { eventSeverityColor } from '@/utils/constants'
|
||||
export default {
|
||||
name: 'DetectionPerformanceEventAppOverview',
|
||||
@@ -74,35 +73,17 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
query () {
|
||||
this.basicInfo = {
|
||||
clientLocationCountry: 1212,
|
||||
clientLocationProvince: '112.2.2.3',
|
||||
clientLocationRegion: 'China',
|
||||
clientAsn: 'Hebei',
|
||||
serverLocationCountry: 'Xingtai',
|
||||
serverLocationProvince: 'hehe',
|
||||
serverLocationRegion: '2.2.2.2',
|
||||
serverAsn: 'China',
|
||||
domainCategoryName: 'Hebei',
|
||||
domainCategoryGroup: 'Xingtai',
|
||||
domainReputationScore: 'hehe',
|
||||
domainReputationLevel: 'high',
|
||||
appCategory: 'vpn',
|
||||
appSubcategory: 'foreign vpn',
|
||||
appRisk: 'critical'
|
||||
}
|
||||
/* this.queryBasic().then(responses => {
|
||||
}) */
|
||||
this.queryBasic().then(responses => {
|
||||
responses && (this.basicInfo = responses)
|
||||
})
|
||||
},
|
||||
queryBasic () {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
get(api.detection.performanceEvent.overviewBasic, { serverIp: this.detection.appName }).then(response => {
|
||||
if (response.code === 200) {
|
||||
resolve(response.data.list)
|
||||
} else {
|
||||
reject(response)
|
||||
}
|
||||
getData(api.detection.performanceEvent.overviewBasic, { domain: this.detection.appName,startTime: this.detection.startTime }).then(data => {
|
||||
resolve(data[0])
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="overview__title">Fields</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{$t('entities.category')}}</div>
|
||||
<div class="row__content">{{basicInfo.domainCategoryName}}</div>
|
||||
<div class="row__content">{{basicInfo.domainCategoryName || '-'}}</div>
|
||||
</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label">{{$t('entities.group')}}</div>
|
||||
@@ -39,8 +39,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import { api, getData } from '@/utils/api'
|
||||
import { eventSeverityColor } from '@/utils/constants'
|
||||
export default {
|
||||
name: 'DetectionPerformanceEventDomainOverview',
|
||||
@@ -78,35 +77,17 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
query () {
|
||||
this.basicInfo = {
|
||||
clientLocationCountry: 1212,
|
||||
clientLocationProvince: '112.2.2.3',
|
||||
clientLocationRegion: 'China',
|
||||
clientAsn: 'Hebei',
|
||||
serverLocationCountry: 'Xingtai',
|
||||
serverLocationProvince: 'hehe',
|
||||
serverLocationRegion: '2.2.2.2',
|
||||
serverAsn: 'China',
|
||||
domainCategoryName: 'Hebei',
|
||||
domainCategoryGroup: 'Xingtai',
|
||||
domainReputationScore: 'hehe',
|
||||
domainReputationLevel: 'high',
|
||||
appCategory: 'vpn',
|
||||
appSubcategory: 'foreign vpn',
|
||||
appRisk: 'critical'
|
||||
}
|
||||
/* this.queryBasic().then(responses => {
|
||||
}) */
|
||||
this.queryBasic().then(responses => {
|
||||
responses && (this.basicInfo = responses)
|
||||
})
|
||||
},
|
||||
queryBasic () {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
get(api.detection.performanceEvent.overviewBasic, { serverIp: this.detection.appName }).then(response => {
|
||||
if (response.code === 200) {
|
||||
resolve(response.data.list)
|
||||
} else {
|
||||
reject(response)
|
||||
}
|
||||
getData(api.detection.performanceEvent.overviewBasic, { appName: this.detection.appName,startTime: this.detection.startTime }).then(data => {
|
||||
resolve(data[0])
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
|
||||
@@ -65,31 +65,15 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
query () {
|
||||
this.basicInfo = {
|
||||
clientLocationCountry: 1212,
|
||||
clientLocationProvince: '112.2.2.3',
|
||||
clientLocationRegion: 'China',
|
||||
clientAsn: 'Hebei',
|
||||
serverLocationCountry: 'Xingtai',
|
||||
serverLocationProvince: 'hehe',
|
||||
serverLocationRegion: '2.2.2.2',
|
||||
serverAsn: 'China',
|
||||
domainCategoryName: 'Hebei',
|
||||
domainCategoryGroup: 'Xingtai',
|
||||
domainReputationScore: 'hehe',
|
||||
domainReputationLevel: 'high',
|
||||
appCategory: 'vpn',
|
||||
appSubcategory: 'foreign vpn',
|
||||
appRisk: 'critical'
|
||||
}
|
||||
/* this.queryBasic().then(responses => {
|
||||
}) */
|
||||
this.queryBasic().then(responses => {
|
||||
responses && (this.basicInfo = responses)
|
||||
})
|
||||
},
|
||||
queryBasic () {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
getData(api.detection.performanceEvent.overviewBasic, { serverIp: this.detection.serverIp }).then(data => {
|
||||
resolve(data)
|
||||
getData(api.detection.performanceEvent.overviewBasic, { serverIp: this.detection.serverIp,startTime: this.detection.startTime }).then(data => {
|
||||
resolve(data[0])
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="overview__left">
|
||||
<div class="overview__title">{{$t('overall.remark')}}</div>
|
||||
<div class="overview__row">
|
||||
<div class="row__content">{{basicInfo.malwareDescription || '-'}}</div>
|
||||
<div class="row__content">Description</div>
|
||||
</div>
|
||||
<div class="overview__title">Fields</div>
|
||||
<div class="overview__row">
|
||||
@@ -117,7 +117,7 @@
|
||||
<div class="overview__title">{{$t('detections.relatedDetections')}}</div>
|
||||
<div class="overview__row-timeline">
|
||||
<div class="row-timeline" v-for="event in events" :key="event">
|
||||
<div class="row-timeline__time-info" :style="event.startTime === basicInfo.startTime ? 'color: #333;font-weight: bold;' : ''">{{formatT0(event.startTime)}}</div>
|
||||
<div class="row-timeline__time-info" :style="event.startTime === basicInfo.startTime ? 'color: #333;font-weight: bold;' : ''">{{formatT0(event)}}</div>
|
||||
<div class="row-timeline__line">
|
||||
<div class="line-point-larger" v-if="event.startTime === basicInfo.startTime">
|
||||
<div class="line-point"></div>
|
||||
@@ -154,7 +154,8 @@
|
||||
import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import { getMillisecond } from '@/utils/date-util'
|
||||
import { eventSeverityColor } from '@/utils/constants'
|
||||
import { eventSeverityColor, unitTypes } from '@/utils/constants'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
export default {
|
||||
name: 'DetectionOverview',
|
||||
props: {
|
||||
@@ -170,126 +171,41 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
formatT0 () {
|
||||
return function (startTime) {
|
||||
return startTime === this.basicInfo.startTime ? 'T0' : 'T0-10m'
|
||||
return function (event) {
|
||||
const diffSeconds = event.diffSeconds
|
||||
if (diffSeconds === 0) {
|
||||
return 'T0'
|
||||
}
|
||||
const eventStartTime = event.startTime
|
||||
const entityStartTime = this.basicInfo ? this.basicInfo.startTime : ''
|
||||
|
||||
if (!this.$_.isEmpty(diffSeconds) && !this.$_.isEmpty(eventStartTime) && !this.$_.isEmpty(entityStartTime)) {
|
||||
const suffix = unitConvert(diffSeconds, unitTypes.time, 's', null, 0).join('')
|
||||
if (eventStartTime > entityStartTime) {
|
||||
return `T0+${suffix}`
|
||||
} else if (eventStartTime < entityStartTime) {
|
||||
return `T0-${suffix}`
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getMillisecond,
|
||||
query () {
|
||||
this.basicInfo = {
|
||||
eventId: 1212,
|
||||
offenderIp: '112.2.2.3',
|
||||
offenderLocationCountry: 'China',
|
||||
offenderLocationProvince: 'Hebei',
|
||||
offenderLocationRegion: 'Xingtai',
|
||||
offenderAsn: 'hehe',
|
||||
victimIp: '2.2.2.2',
|
||||
victimLocationCountry: 'China',
|
||||
victimLocationProvince: 'Hebei',
|
||||
victimLocationRegion: 'Xingtai',
|
||||
victimAsn: 'hehe',
|
||||
domain: '5aibj.com',
|
||||
domainCategoryName: 'bbs',
|
||||
domainCategoryGroup: 'hehe',
|
||||
domainReputationLevel: 'high',
|
||||
appName: 'express vpn',
|
||||
appCategory: 'vpn',
|
||||
appSubcategory: 'foreign vpn',
|
||||
appRisk: 'critical',
|
||||
cryptominingPool: 'btcP',
|
||||
cryptominingCoinType: 'btc',
|
||||
cryptominingSoftware: 'a',
|
||||
malwareName: 'gtw',
|
||||
malwareAlias: 'gt',
|
||||
malwareDescription: 'this is description,this is description,this is description,this is description,this is description,this is description,this is description,this is description,this is description,this is description,',
|
||||
malwarePlatforms: 'windows',
|
||||
malwareTechniques: 'Audio captures',
|
||||
malwareGroups: 'Silver terrier',
|
||||
startTime: 1645417930
|
||||
}
|
||||
this.events = [
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645307930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'critical',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '112.2.2.3',
|
||||
startTime: 1645317930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645327930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645337930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645347930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645357930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645367930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645397930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645407930
|
||||
},
|
||||
{
|
||||
eventSeverity: 'high',
|
||||
securityType: 'command and control',
|
||||
offenderIp: '2.2.2.2',
|
||||
victimIp: '2.2.2.3',
|
||||
startTime: 1645417930
|
||||
}
|
||||
]
|
||||
Promise.all([this.queryBasic(), this.queryEvent()]).then(responses => {
|
||||
console.info(responses)
|
||||
responses[0] && (this.basicInfo = responses[0])
|
||||
responses[1] && (this.events = responses[1])
|
||||
})
|
||||
},
|
||||
queryBasic () {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
get(api.detectionOverviewBasic, { eventId: this.detection.eventId }).then(response => {
|
||||
get(api.detection.securityEvent.overviewBasic, { eventId: this.detection.eventId,startTime: this.detection.startTime }).then(response => {
|
||||
if (response.code === 200) {
|
||||
resolve(response.data.list)
|
||||
resolve(response.data.result[0])
|
||||
} else {
|
||||
reject(response)
|
||||
}
|
||||
@@ -302,9 +218,9 @@ export default {
|
||||
queryEvent () {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
get(api.detectionOverviewEvent, { eventId: this.detection.eventId }).then(response => {
|
||||
get(api.detection.securityEvent.overviewEvent, { startTime: this.detection.startTime, offenderIp: this.detection.offenderIp, victimIp: this.detection.victimIp }).then(response => {
|
||||
if (response.code === 200) {
|
||||
resolve(response.data.list)
|
||||
resolve(response.data.result)
|
||||
} else {
|
||||
reject(response)
|
||||
}
|
||||
|
||||
@@ -257,8 +257,7 @@ export default {
|
||||
const queryParams = {
|
||||
startTime: parseInt(this.timeFilter.startTime / 1000),
|
||||
endTime: parseInt(this.timeFilter.endTime / 1000),
|
||||
ip: this.entityData.ipAddr,
|
||||
country: this.entityData.ipLocationCountry
|
||||
ip: this.entityData.ipAddr
|
||||
}
|
||||
return queryParams
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user