CN-318 feat: detection服务质量界面

This commit is contained in:
chenjinsong
2022-02-25 13:33:54 +08:00
parent 2889c3cb19
commit 6158a6a4f4
19 changed files with 1197 additions and 683 deletions

View File

@@ -10,6 +10,7 @@
<detection-row
v-for="(data, index) in listData"
:detection="data"
:page-type="pageType"
:timeFilter="timeFilter"
:key="index"
:ref="`detectionRow${index}`"
@@ -33,7 +34,8 @@ export default {
from: String,
pageObj: Object,
loading: Boolean,
timeFilter: Object
timeFilter: Object,
pageType: String // 安全事件、服务质量
},
data () {
return {

View File

@@ -5,17 +5,19 @@
<span @click="switchCollapse" :class="{'reg-down': !isCollapse}"><i class="cn-icon cn-icon-arrow-right"></i></span>
</div>
<div class="cn-detection__case">
<div class="cn-detection__icon" :style="`background-color: ${eventSeverityColor[detection.eventSecurity]}`">
</div>
<div class="cn-detection__icon" :style="`background-color: ${eventSeverityColor[detection.eventSecurity]}`"></div>
<div class="cn-detection__row">
<div class="cn-detection__header">
<div class="cn-detection__header" v-if="pageType === detectionPageType.securityEvent">
<i class="cn-icon cn-icon-attacker" ></i>{{detection.offenderIp}}
<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="cn-detection__header" v-else-if="pageType === detectionPageType.performanceEvent">
<div class="cn-entity__icon"><i :class="iconClass"></i></div>
<div style="padding-left: 3px;">{{detection.serverIp || detection.domain || detection.appName || 'Unknown'}}</div>
</div>
<div class="cn-detection__body">
<div class="body__basic-info">
<div class="basic-info">
<div class="basic-info__item">
@@ -28,12 +30,12 @@
<span>{{$t('detection.list.securityType')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.securityType}}</span>
</div>
<div class="basic-info__item" v-if="detection.malwareName && detection.malwareName.length > 0 ">
<div class="basic-info__item" v-if="detection.malwareName">
<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" v-if="detection.cryptominingPool && detection.cryptominingPool.length > 0 ">
<div class="basic-info__item" v-if="detection.cryptominingPool">
<i class="cn-icon cn-icon-mining-pool"></i>
<span>{{$t('detection.list.cryptominingPool')}}&nbsp;:&nbsp;&nbsp;</span>
<span>{{detection.cryptominingPool}}</span>
@@ -43,6 +45,13 @@
<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;"
:style="pointColor(detection)"></span>
<span>{{unitConvert(detection.durationMs, 'time', null, null, 0).join(' ')}}</span>
</div>
</div>
</div>
</div>
@@ -50,10 +59,28 @@
<el-collapse-transition>
<div class="cn-detection__detail-overview" v-if="!isCollapse">
<el-divider></el-divider>
<detection-overview
<detection-security-event-overview
v-if="pageType === detectionPageType.securityEvent"
:detection="detection"
:time-filter="timeFilter"
></detection-overview>
></detection-security-event-overview>
<template v-else>
<detection-performance-event-ip-overview
v-if="detection.entityType === entityType.ip.toLowerCase()"
:detection="detection"
:time-filter="timeFilter"
></detection-performance-event-ip-overview>
<detection-performance-event-domain-overview
v-else-if="detection.entityType === entityType.domain.toLowerCase()"
:detection="detection"
:time-filter="timeFilter"
></detection-performance-event-domain-overview>
<detection-performance-event-app-overview
v-else-if="detection.entityType === entityType.app.toLowerCase()"
:detection="detection"
:time-filter="timeFilter"
></detection-performance-event-app-overview>
</template>
</div>
</el-collapse-transition>
</div>
@@ -61,26 +88,70 @@
</template>
<script>
import { eventSeverityColor } from '@/utils/constants'
import { eventSeverityColor, detectionPageType, entityType } from '@/utils/constants'
import { getMillisecond } from '@/utils/date-util'
import DetectionOverview from '@/views/detections/DetectionOverview'
import unitConvert from '@/utils/unit-convert'
import DetectionSecurityEventOverview from '@/views/detections/overview/DetectionSecurityEventOverview'
import DetectionPerformanceEventIpOverview from '@/views/detections/overview/DetectionPerformanceEventIpOverview'
import DetectionPerformanceEventAppOverview from '@/views/detections/overview/DetectionPerformanceEventAppOverview'
import DetectionPerformanceEventDomainOverview from '@/views/detections/overview/DetectionPerformanceEventDomainOverview'
export default {
name: 'DetectionRow',
components: {
DetectionOverview
DetectionSecurityEventOverview,
DetectionPerformanceEventIpOverview,
DetectionPerformanceEventAppOverview,
DetectionPerformanceEventDomainOverview
},
props: {
index: Number,
timeFilter: Object,
detection: Object
detection: Object,
pageType: String // 安全事件、服务质量
},
data () {
return {
entityType,
detectionPageType,
isCollapse: true, // 是否是折叠状态
eventSeverityColor
}
},
computed: {
iconClass () {
let className
switch (this.detection.entityType) {
case ('ip'): {
className = 'cn-icon cn-icon-ip'
break
}
case ('domain'): {
className = 'cn-icon cn-icon-domain'
break
}
case ('app'): {
className = 'cn-icon cn-icon-app'
break
}
default:
break
}
return className
},
pointColor () {
return function (detection) {
let color = '#8FA1BE'
if (detection.startTime && detection.endTime) {
if (getMillisecond(detection.endTime) - getMillisecond(detection.startTime) < 5 * 60 * 1000) {
color = '#D84C4C'
}
}
return { backgroundColor: color }
}
}
},
methods: {
unitConvert,
getMillisecond,
/* 切换折叠状态 */
switchCollapse () {

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,117 @@
<template>
<div class="detection-detail-overview">
<div class="overview__left">
<div class="overview__title">{{$t('overall.remark')}}</div>
<div class="overview__row">
<div class="row__content">{{basicInfo.malwareDescription || '-'}}</div>
</div>
<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>
<div class="overview__row">
<div class="row__label">{{$t('entities.subcategory')}}</div>
<div class="row__content">{{basicInfo.appSubcategory || '-'}}</div>
</div>
<div class="overview__row">
<div class="row__label">{{$t('entities.riskLevel')}}</div>
<div class="row__content">
<div class="row__tag" :style="`background-color:${eventSeverityColor[basicInfo.appRisk]}`">{{basicInfo.appRisk || '-'}}</div>
</div>
</div>
</div>
<div class="overview__right">
<div class="overview__title">{{$t('detections.goToEntity')}}</div>
<div class="overview__row">
<div class="row__content row__content--link">{{$t('detections.viewDetailOf', {ip: detection.appName})}}</div>
</div>
<div class="overview__title">{{$t('detections.goToHunt')}}</div>
<div class="overview__row">
<div class="row__content row__content--link">{{$t('detections.viewAllRelated')}}</div>
</div>
</div>
</div>
</template>
<script>
import { get } from '@/utils/http'
import { api } from '@/utils/api'
import { eventSeverityColor } from '@/utils/constants'
export default {
name: 'DetectionPerformanceEventAppOverview',
props: {
detection: Object
},
data () {
return {
eventSeverityColor,
basicInfo: {}
}
},
computed: {
computeLocation () {
return function (basicInfo) {
let result = ''
if (basicInfo.serverLocationCountry) {
result += basicInfo.serverLocationCountry
}
if (basicInfo.serverLocationProvince) {
if (result) {
result += ', '
}
result += basicInfo.serverLocationProvince
}
if (basicInfo.serverLocationRegion) {
if (result) {
result += ', '
}
result += basicInfo.serverLocationRegion
}
return result || '-'
}
}
},
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 => {
})*/
},
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)
}
})
} catch (e) {
reject(e)
}
})
}
},
mounted () {
this.query()
}
}
</script>

View File

@@ -0,0 +1,121 @@
<template>
<div class="detection-detail-overview">
<div class="overview__left">
<div class="overview__title">{{$t('overall.remark')}}</div>
<div class="overview__row">
<div class="row__content">{{basicInfo.malwareDescription || '-'}}</div>
</div>
<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>
<div class="overview__row">
<div class="row__label">{{$t('entities.group')}}</div>
<div class="row__content">{{basicInfo.domainCategoryGroup || '-'}}</div>
</div>
<div class="overview__row">
<div class="row__label">{{$t('entities.credit')}}</div>
<div class="row__content">{{basicInfo.domainReputationScore || '-'}}</div>
</div>
<div class="overview__row">
<div class="row__label">{{$t('entities.reputationLevel')}}</div>
<div class="row__content">
<div class="row__tag" :style="`background-color:${eventSeverityColor[basicInfo.domainReputationLevel]}`">{{basicInfo.domainReputationLevel || '-'}}</div>
</div>
</div>
</div>
<div class="overview__right">
<div class="overview__title">{{$t('detections.goToEntity')}}</div>
<div class="overview__row">
<div class="row__content row__content--link">{{$t('detections.viewDetailOf', {ip: detection.domain})}}</div>
</div>
<div class="overview__title">{{$t('detections.goToHunt')}}</div>
<div class="overview__row">
<div class="row__content row__content--link">{{$t('detections.viewAllRelated')}}</div>
</div>
</div>
</div>
</template>
<script>
import { get } from '@/utils/http'
import { api } from '@/utils/api'
import { eventSeverityColor } from '@/utils/constants'
export default {
name: 'DetectionPerformanceEventDomainOverview',
props: {
detection: Object
},
data () {
return {
eventSeverityColor,
basicInfo: {}
}
},
computed: {
computeLocation () {
return function (basicInfo) {
let result = ''
if (basicInfo.serverLocationCountry) {
result += basicInfo.serverLocationCountry
}
if (basicInfo.serverLocationProvince) {
if (result) {
result += ', '
}
result += basicInfo.serverLocationProvince
}
if (basicInfo.serverLocationRegion) {
if (result) {
result += ', '
}
result += basicInfo.serverLocationRegion
}
return result || '-'
}
}
},
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 => {
})*/
},
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)
}
})
} catch (e) {
reject(e)
}
})
}
},
mounted () {
this.query()
}
}
</script>

View File

@@ -0,0 +1,106 @@
<template>
<div class="detection-detail-overview">
<div class="overview__left">
<div class="overview__title">{{$t('overall.remark')}}</div>
<div class="overview__row">
<div class="row__content">{{basicInfo.malwareDescription || '-'}}</div>
</div>
<div class="overview__title">Fields</div>
<div class="overview__row">
<div class="row__label">{{$t('overall.location')}}</div>
<div class="row__content">{{computeLocation(basicInfo)}}</div>
</div>
<div class="overview__row">
<div class="row__label">ASN</div>
<div class="row__content">{{basicInfo.serverAsn || '-'}}</div>
</div>
</div>
<div class="overview__right">
<div class="overview__title">{{$t('detections.goToEntity')}}</div>
<div class="overview__row">
<div class="row__content row__content--link">{{$t('detections.viewDetailOf', {ip: detection.serverIp})}}</div>
</div>
<div class="overview__title">{{$t('detections.goToHunt')}}</div>
<div class="overview__row">
<div class="row__content row__content--link">{{$t('detections.viewAllRelated')}}</div>
</div>
</div>
</div>
</template>
<script>
import { api, getData } from '@/utils/api'
export default {
name: 'DetectionPerformanceEventIpOverview',
props: {
detection: Object
},
data () {
return {
basicInfo: {}
}
},
computed: {
computeLocation () {
return function (basicInfo) {
let result = ''
if (basicInfo.serverLocationCountry) {
result += basicInfo.serverLocationCountry
}
if (basicInfo.serverLocationProvince) {
if (result) {
result += ', '
}
result += basicInfo.serverLocationProvince
}
if (basicInfo.serverLocationRegion) {
if (result) {
result += ', '
}
result += basicInfo.serverLocationRegion
}
return result || '-'
}
}
},
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 => {
})*/
},
queryBasic () {
return new Promise((resolve, reject) => {
try {
getData(api.detection.performanceEvent.overviewBasic, { serverIp: this.detection.serverIp }).then(data => {
resolve(data)
}).catch(error => {
reject(error)
})
} catch (e) {
reject(e)
}
})
}
},
mounted () {
this.query()
}
}
</script>