CN-434 feat: Detection--在实体详情页增加detection图表

This commit is contained in:
@changcode
2022-03-29 18:26:24 +08:00
parent 0353a3369e
commit b5f2dab4a0
8 changed files with 451 additions and 9 deletions

View File

@@ -164,3 +164,68 @@
}
}
}
.security.cn-detection--list,.service.cn-detection--list {
height: 100%;
flex-direction: column;
justify-content: space-between;
.cn-detection__case {
background: #FFFFFF;
border: 1px solid #E7EAED;
border-radius: 2px;
margin-bottom: 10px;
}
.cn-detection__case {
padding: 18px 0;
flex: unset;
}
.cn-detection__header {
margin-bottom: 8px;
}
.cn-detection__case-severity {
display: flex;
width: 38px;
height: 34px;
text-align: center;
margin: auto;
margin-right: 20px;
margin-left: 29px;
line-height: 34px;
i {
font-size: 40px;
}
}
.el-pagination__jump {
margin-left: 0 !important;
}
.cn-detection__footer {
background: #FFFFFF;
position: relative;
box-shadow: 0 0 4px 0 rgba(0,0,0,0.06);
.el-pagination__total {
position: absolute;
left: 0;
}
}
.domain.cn-detection-domain {
height: 20px;
line-height: 20px !important;
padding: 0 4px;
font-style: italic;
}
.critical {
color: #D84C4C !important;
}
.high {
color: #FF9A79 !important;
}
.info {
color: #D1BD50 !important;
}
.medium {
color: #FFB65A !important;
}
.low {
color: #FFD82D !important;
}
}

View File

@@ -247,6 +247,24 @@
v-else-if="isDomainRecursiveResolve"
></chart-domain-recursive-resolve>
<chart-detection-security
:chart-data="chartData"
:time-filter="timeFilter"
:chart-info="chartInfo"
:query-params="queryParams"
v-else-if="isDetectionSecurity"
@getDetectionData="getDetectionData"
></chart-detection-security>
<chart-detection-service
:chart-data="chartData"
:time-filter="timeFilter"
:chart-info="chartInfo"
:query-params="queryParams"
v-else-if="isDetectionService"
@getDetectionData="getDetectionData"
></chart-detection-service>
</template>
</div>
</template>
@@ -280,6 +298,8 @@ import ChartOneSituationStatistics from '@/views/charts/charts/ChartOneSituation
import ChartTwoSituationStatistics from '@/views/charts/charts/ChartTwoSituationStatistics'
import ChartAlarmInfo from '@/views/charts/charts/ChartAlarmInfo'
import ChartDomainRecursiveResolve from '@/views/charts/charts/ChartDomainRecursiveResolve'
import chartDetectionSecurity from '@/views/charts/charts/chartDetectionSecurity'
import chartDetectionService from '@/views/charts/charts/chartDetectionService'
import {
isEcharts,
isEchartsLine,
@@ -315,7 +335,9 @@ import {
isSingleSupportStatistics,
isTwoSupportStatistics,
isAlarmInfo,
isDomainRecursiveResolve
isDomainRecursiveResolve,
isDetectionSecurity,
isDetectionService
} from './charts/tools'
import _ from 'lodash'
@@ -349,7 +371,9 @@ export default {
ChartOneSituationStatistics,
ChartTwoSituationStatistics,
ChartAlarmInfo,
ChartDomainRecursiveResolve
ChartDomainRecursiveResolve,
chartDetectionSecurity,
chartDetectionService
},
data () {
return {
@@ -385,7 +409,9 @@ export default {
!this.isMap &&
!this.isSingleSupportStatistics &&
!this.isTwoSupportStatistics &&
!this.isAlarmInfo
!this.isAlarmInfo &&
!this.isDetectionSecurity &&
!this.isDetectionService
)
},
chartOption () {
@@ -410,6 +436,9 @@ export default {
getChartData (url, extraParams) {
this.$emit('getChartData', url, extraParams)
},
getDetectionData (url, extraParams, isRefresh, timeFilter) {
this.$emit('getChartData', url, extraParams, isRefresh, timeFilter)
},
initEchartsWithTable () {
this.$refs['chart' + this.chartInfo.id] &&
this.$refs['chart' + this.chartInfo.id].initEchartsWithTable(
@@ -424,8 +453,15 @@ export default {
tabHandleClickType: {
deep: true,
handler (n) {
console.log(n)
this.tabHandleClickType = n
}
},
chartData: {
deep: true,
immediate: true,
handler (n) {
}
}
},
setup (props) {
@@ -467,7 +503,9 @@ export default {
),
isTwoSupportStatistics: isTwoSupportStatistics(props.chartInfo.type),
isAlarmInfo: isAlarmInfo(props.chartInfo.type),
isDomainRecursiveResolve: isDomainRecursiveResolve(props.chartInfo.type)
isDomainRecursiveResolve: isDomainRecursiveResolve(props.chartInfo.type),
isDetectionSecurity: isDetectionSecurity(props.chartInfo.type),
isDetectionService: isDetectionService(props.chartInfo.type)
}
}
}

View File

@@ -7,7 +7,7 @@
>
<!-- title和工具栏支持浮动 -->
<chart-header
v-if="!isFullscreen && showHeader && !isSingleValue && !isTabs"
v-if="!isFullscreen && showHeader && !isSingleValue && !isTabs && !isDetectionSecurity && !isDetectionService"
:is-error="isError"
:error-info="errorInfo"
:chart-data="chartData"
@@ -79,7 +79,9 @@ import {
isAppBasicInfo,
isAppRelatedDomain,
isBlock,
isAlarmInfo
isAlarmInfo,
isDetectionSecurity,
isDetectionService
} from './charts/tools'
import { tableTitleMapping, legendMapping } from '@/views/charts/charts/chart-table-title'
import { replaceUrlPlaceholder } from '@/utils/tools'
@@ -165,7 +167,7 @@ export default {
},
methods: {
/* 参数 extraParams 额外请求参数isRefresh 是否是刷新 */
getChartData (url, extraParams = {}, isRefresh, chartTimeFilter) {
getChartData (url, extraParams = {}, isRefresh, chartTimeFilter, num) {
const vm = this
this.loading = true
this.standaloneTimeRange.use = !!isRefresh
@@ -187,12 +189,17 @@ export default {
pageSize: 9
}
}
if ((isDetectionService && JSON.stringify(extraParams) === '{}') || (isDetectionSecurity && JSON.stringify(extraParams) === '{}')) {
extraParams = {
pageNo: 1,
pageSize: 6
}
}
// 接口查询参数
this.queryParams = {
...this.handleQueryParams(),
...this.queryTimeRange,
...this.entity,
...extraParams
}
const requestUrl = url || (chartParams && chartParams.url)
@@ -430,7 +437,9 @@ export default {
isCryptocurrencyEventList: isCryptocurrencyEventList(props.chartInfo.type),
isAppBasicInfo: isAppBasicInfo(props.chartInfo.type),
isAppRelatedDomain: isAppRelatedDomain(props.chartInfo.type),
isAlarmInfo: isAlarmInfo(props.chartInfo.type)
isAlarmInfo: isAlarmInfo(props.chartInfo.type),
isDetectionService: isDetectionService(props.chartInfo.type),
isDetectionSecurity: isDetectionSecurity(props.chartInfo.type)
}
}
}

View File

@@ -0,0 +1,47 @@
<template>
<el-pagination
small
ref="pagination"
:current-page="pageObj.pageNo"
:page-size="pageObj.pageSize"
layout="total,prev,jumper,slot,next"
class="chart-table-pagination"
:total="pageObj.total"
@current-change="currentChange"
>
<span>/&nbsp;{{totalPage}}</span>
</el-pagination>
</template>
<script>
export default {
name: 'chartDetectionPagination',
props: {
pageObj: Object
},
data () {
return {
}
},
computed: {
totalPage () {
const remainder = this.pageObj.total % this.pageObj.pageSize
if (remainder) {
return parseInt(this.pageObj.total / this.pageObj.pageSize) + 1
} else {
return parseInt(this.pageObj.total / this.pageObj.pageSize)
}
}
},
methods: {
currentChange: function (val) {
this.$emit('pageJump', val)
this.pageObj.pageNo = val
}
},
mounted () {
this.$el.querySelector('.el-pagination__jump').childNodes[0].nodeValue = ''
}
}
</script>

View File

@@ -0,0 +1,85 @@
<template>
<div class="security cn-detection--list">
<div class="cn-detection-table">
<detections-table
v-for="(data, index) in chartData"
:detection="data"
:timeFilter="timeFilter"
:key="index"
:ref="`detectionRow${index}`"
:index="index"
></detections-table>
</div>
<div class="cn-detection__footer" v-show="pageObj.total > 0">
<chart-detection-pagination
ref="pagination"
:page-obj="pageObj"
@pageJump="pageJump"
:pageSizeForAlarm="pageSizeForAlarm"
></chart-detection-pagination>
</div>
</div>
</template>
<script>
import detectionsTable from '@/views/detections/detectionsTable'
import chartDetectionPagination from '@/views/charts/charts/chartDetectionPagination'
import { get } from '@/utils/http'
import { replaceUrlPlaceholder } from '@/utils/tools'
export default {
name: 'chartDetectionSecurity',
props: {
chartInfo: Object,
chartData: Array,
resultType: Object,
queryParams: Object,
timeFilter: Object
},
components: {
chartDetectionPagination,
detectionsTable
},
watch: {
},
data () {
return {
pageObj: {
pageNo: 1,
pageSize: 6,
total: 0,
resetPageNo: true
},
pageSizeForAlarm: 6
}
},
methods: {
securityCount () {
const requestUrl = this.chartInfo.params.countUrl
get(replaceUrlPlaceholder(requestUrl, this.queryParams)).then(response => {
this.pageObj.total = response.data.result
})
},
getDetectionData (val) {
this.pageObj.pageNo = val
const extraParams = {
pageNo: val,
pageSize: this.pageSizeForAlarm
}
this.$emit('getDetectionData', this.chartInfo.params.url, extraParams, false, {
startTime: this.queryParams.startTime,
endTime: this.queryParams.endTime
})
const requestUrl = this.chartInfo.params.countUrl
get(replaceUrlPlaceholder(requestUrl, this.queryParams)).then(response => {
this.pageObj.total = response.data.result
})
},
pageJump (val) {
this.getDetectionData(val)
}
},
mounted () {
this.securityCount()
}
}
</script>

View File

@@ -0,0 +1,83 @@
<template>
<div class="service cn-detection--list">
<div class="cn-detection-table">
<detections-table
v-for="(data, index) in chartData"
:detection="data"
:timeFilter="timeFilter"
:key="index"
:ref="`detectionRow${index}`"
:index="index"
></detections-table>
</div>
<div class="cn-chart__footer" v-show="pageObj.total > 0">
<chart-detection-pagination
ref="pagination"
:page-obj="pageObj"
@pageJump="pageJump"
:pageSizeForAlarm="pageSizeForAlarm"
></chart-detection-pagination>
</div>
</div>
</template>
<script>
import chartDetectionPagination from '@/views/charts/charts/chartDetectionPagination'
import detectionsTable from '@/views/detections/detectionsTable'
import { get } from '@/utils/http'
import { replaceUrlPlaceholder } from '@/utils/tools'
export default {
name: 'chartDetectionService',
props: {
chartInfo: Object,
chartData: Array,
resultType: Object,
queryParams: Object,
timeFilter: Object
},
components: {
chartDetectionPagination,
detectionsTable
},
data () {
return {
pageObj: {
pageNo: 1,
pageSize: 6,
total: 0,
resetPageNo: true
},
pageSizeForAlarm: 6
}
},
methods: {
securityCount () {
const requestUrl = this.chartInfo.params.countUrl
get(replaceUrlPlaceholder(requestUrl, this.queryParams)).then(response => {
this.pageObj.total = response.data.result
})
},
getDetectionData (val) {
this.pageObj.pageNo = val
const extraParams = {
pageNo: val,
pageSize: this.pageSizeForAlarm
}
this.$emit('getDetectionData', this.chartInfo.params.url, extraParams, false, {
startTime: this.queryParams.startTime,
endTime: this.queryParams.endTime
})
const requestUrl = this.chartInfo.params.countUrl
get(replaceUrlPlaceholder(requestUrl, this.queryParams)).then(response => {
this.pageObj.total = response.data.result
})
},
pageJump (val) {
this.getDetectionData(val)
}
},
mounted () {
this.securityCount()
}
}
</script>

View File

@@ -189,6 +189,13 @@ export function isBlock (type) {
return type === 805
}
export function isDetectionSecurity (type) {
return type === 709
}
export function isDetectionService (type) {
return type === 710
}
/* 根据type获取图表分类 */
const typeCategory = {
MAP: 'map',

View File

@@ -0,0 +1,108 @@
<template>
<div class="cn-detection__case">
<div class="cn-detection__case-severity"><i :class="iconClass" class="cn-icon cn-icon-alert-level"></i></div>
<div class="cn-detection__row">
<div class="cn-detection__header">
<span :class="iconClass"><i :class="iconClass" class="cn-icon cn-icon-attacker"></i>{{detection.offenderIp || '-'}}</span>
<div :class="iconClass" class="domain cn-detection-domain">{{detection.domain}}</div>
<span class="line">-------</span>
<span class="circle"></span>
<i class="cn-icon cn-icon-attacked" ></i>{{detection.victimIp || '-'}}
</div>
<div class="cn-detection__body">
<div class="body__basic-info">
<div class="basic-info">
<div class="basic-info__item" v-if="detection.eventSecurity">
<i class="cn-icon cn-icon-severity-level"></i>
<span>{{$t('detection.list.eventSecurity')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.eventSecurity || '-'}}</span>
</div>
<div class="basic-info__item" v-else-if="detection.eventSeverity">
<i class="cn-icon cn-icon-severity-level"></i>
<span>{{$t('detections.eventSeverity')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.eventSeverity || '-'}}</span>
</div>
<div class="basic-info__item">
<i class="cn-icon cn-icon-event-type"></i>
<span>{{$t('detection.list.securityType')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.securityType || '-'}}</span>
</div>
<div class="basic-info__item">
<i class="cn-icon cn-icon-event-type"></i>
<span>{{$t('detections.eventType')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.eventType || '-'}}</span>
</div>
<div class="basic-info__item">
<i class="cn-icon cn-icon-trojan"></i>
<span>{{$t('detection.list.malwareName')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.malwareName || '-'}}</span>
</div>
<div class="basic-info__item">
<i class="cn-icon cn-icon-mining-pool"></i>
<span>{{$t('detection.list.cryptominingPool')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.cryptominingPool || '-'}}</span>
</div>
<div class="basic-info__item">
<i class="cn-icon cn-icon-time2"></i>
<span>{{$t('detection.list.startTime')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{dayJs.tz(getMillisecond(detection.startTime)).format('YYYY-MM-DD HH:mm:ss') || '-'}}</span>
</div>
<div class="basic-info__item">
<i class="cn-icon cn-icon-time2"></i>
<span>{{$t('overall.duration')}}&nbsp;:&nbsp;&nbsp;</span>
<span style="display: inline-block;height: 6px;width: 6px;border-radius: 50%;margin-right: 8px;"></span>
<span>{{unitConvert(detection.durationMs, 'time', null, null, 0).join(' ') || '-'}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { getMillisecond } from '@/utils/date-util'
import unitConvert from '@/utils/unit-convert'
export default {
name: 'detectionsTable',
props: {
index: Number,
timeFilter: Object,
detection: Object,
pageType: String // 安全事件、服务质量
},
computed: {
iconClass () {
let className
switch (this.detection.eventSecurity || this.detection.eventSeverity) {
case ('critical'): {
className = 'critical'
break
}
case ('high'): {
className = 'high'
break
}
case ('info'): {
className = 'info'
break
}
case ('medium'): {
className = 'medium'
break
}
case ('low'): {
className = 'low'
break
}
default: break
}
return className
}
},
methods: {
unitConvert,
getMillisecond
}
}
</script>