This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
cyber-narrator-cn-ui/src/views/entityExplorer/entityGraph/GraphEntityDetail.vue
2023-07-30 23:29:32 +08:00

419 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!--title-->
<div class="graph-detail-basic-info">
<div style="display: flex">
<div class="graph-detail__icon"><i :class="iconClass"></i></div>
<div class="graph-detail-header">
<div class="entity-graph-type">{{ $_.get(node, 'myData.entityType') ? entityType[$_.get(node, 'myData.entityType')] : '-' }}</div>
<div class="graph-basic-info">
<div class="graph-basic-info-name__block">
<div class="graph-basic-info-name" :title="$_.get(node, 'id', '')" id="entityName">{{ $_.get(node, 'id', '') }}</div>
<div class="graph-basic-info-icon" @click="copyEntityName">
<i class="cn-icon cn-icon-copy"></i>
</div>
</div>
</div>
</div>
</div>
<i class="cn-icon cn-icon-close graph-close" @click="closeBlock"></i>
</div>
<!--basic info-->
<div class="digital-certificate graph-basic-info__block">
<div class="digital-certificate-header padding-b-10">
<div class="digital-certificate-header__icon graph-header__icon"></div>
<div class="graph-basic-info__block-title">
{{ $t('overall.basicInfo') }}
</div>
</div>
<div class="graph-basic-info__block-content">
<div class="graph-content-item" v-for="detail in detailCards" :key="detail.name">
<div class="graph-content-item-label">{{ detail.label }}:</div>
<div class="graph-content-item-value">{{ detail.value || '-' }}</div>
</div>
</div>
</div>
<!--关系拓展-->
<div class="digital-certificate graph-basic-info__block">
<loading :loading="loading" size="small"></loading>
<div class="digital-certificate-header padding-b-10">
<div class="digital-certificate-header__icon graph-header__icon"></div>
<div class="graph-basic-info__block-title">
{{ $t('entity.graph.relationshipExpansion') }}
</div>
</div>
<div class="graph-basic-info__block-content" style="margin-top: -4px;">
<div v-for="item in relationList" :key="item.name">
<div class="graph-content-item graph-content-relationship-item" v-if="item.value === item.total">
<div class="graph-relationship-item-label">
<i class="margin-r-6" :class="item.icon"></i>
<span>{{ item.label }}</span>
</div>
<div class="graph-relationship-item-value">
<span class="margin-r-6">{{ item.value }}/{{ item.total }}</span>
<i class="cn-icon cn-icon-expand-relationship" :style="{color: iconColor(item.value, item.total)}"></i>
</div>
</div>
<div v-else class="graph-content-item graph-content-relationship-item">
<div class="graph-relationship-item-label">
<i class="graph-relationship-item-label-icon margin-r-6" :class="item.icon"></i>
<span>{{ item.label }}</span>
</div>
<div class="graph-relationship-item-value">
<span class="margin-r-6">{{ item.value }}/{{ item.total }}</span>
<i class="cn-icon cn-icon-expand-relationship graph-expand-relationship__icon" :style="{color: iconColor(item.value, item.total)}" @click="expandRelation(item.name)"></i>
</div>
</div>
</div>
</div>
</div>
<!--标签-->
<div v-if="$_.get(node, 'myData.tags', []).length > 0" class="digital-certificate graph-basic-info__block">
<div class="digital-certificate-header padding-b-10">
<div class="digital-certificate-header__icon graph-header__icon"></div>
<div class="graph-basic-info__block-title">
{{ $t('entity.graph.tags') }}
</div>
</div>
<div class="entity-detail graph-basic-info__block-content">
<div class="graph-tag-list">
<div v-for="ic in $_.get(node, 'myData.tags', [])" :key="ic.value">
<div class="entity-tag graph-tag-item" :class="`entity-tag--level-two-${ic.type}`">
<span>{{ic.value}}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { copySelectionText, selectElementText } from '@/utils/tools'
import { entityType, riskLevelMapping } from '@/utils/constants'
import chartMixin from '@/views/charts2/chart-mixin'
import { dateFormatByAppearance } from '@/utils/date-util'
import { ref } from 'vue'
import _ from 'lodash'
import Loading from '@/components/common/Loading'
export default {
name: 'GraphEntityDetail',
props: {
node: {
type: Object
},
loading: {
type: Boolean
}
},
mixins: [chartMixin],
components: {
Loading
},
data () {
return {
entityType
}
},
computed: {
appRisk () {
return function (level) {
const m = riskLevelMapping.find(mapping => {
return mapping.value == level
})
return (m && m.name) || level
}
},
iconClass () {
let className
switch (_.get(this.node, 'myData.entityType', '')) {
case ('ip'): {
className = 'cn-icon cn-icon-ip2'
break
}
case ('domain'): {
className = 'cn-icon cn-icon-domain2'
break
}
case ('app'): {
className = 'cn-icon cn-icon-app2'
break
}
default:
break
}
return className
},
handleDate () {
return function (key) {
const date = _.get(this.node, key, '')
return date ? dateFormatByAppearance(date) : '-'
}
}
},
watch: {
node: {
deep: true,
handler (n) {
this.handleDetailData(n)
}
}
},
mounted () {
this.handleDetailData(this.node)
},
setup (props) {
const detailCards = ref([])
const relationList = ref([])
const tagList = ref([])
return {
detailCards,
relationList,
tagList
}
},
methods: {
/** 复制实体名称 */
copyEntityName () {
selectElementText(document.getElementById('entityName'))
if (copySelectionText()) {
this.$message.success(this.$t('tip.copySuccess'))
} else {
this.$message.error('Unknown error')
}
},
/** 修改关系拓展图标颜色,全部拓展浅灰色,否则深灰色 */
iconColor (length, total) {
if (length < total) {
if (length === 50) {
return 'rgba(57, 57, 57, 0.5)'
} else {
return 'rgba(57, 57, 57, 1)'
}
} else {
return 'rgba(57, 57, 57, 0.5)'
}
},
// 关闭右侧详情栏
closeBlock () {
this.$emit('closeBlock')
},
/** 构造地址,国-省市-市 */
handleLocation (data) {
const location = []
if (data.country) {
location.push(data.country)
}
if (data.province) {
location.push(data.province)
}
if (data.city) {
location.push(data.city)
}
return location.join(' - ')
},
/** 关系拓展 */
expandRelation (name) {
this.$emit('expandDetailList', this.node.id, name)
},
httpError (e) {
this.isNoData = false
this.showError = true
this.errorMsg = this.errorMsgHandler(e)
},
location (detailData) {
let location = ''
if (detailData) {
const data = detailData.basicInfo.location
if (data) {
if (data.city) {
location = data.city
}
if (data.province) {
location = location ? `${data.province}, ${location}` : data.province
}
if (data.country) {
location = location ? `${data.country}, ${location}` : data.country
}
}
}
return location || '-'
},
handleDetailData (node) {
const n = node
const type = _.get(n, 'myData.entityType', '')
switch (type) {
case 'ip': {
this.detailCards = [
{ name: 'asn', label: this.$t('entities.asNumber'), value: _.get(n, 'myData.basicInfo.asn.asn', '-') },
{
name: 'asOrg',
label: this.$t('entities.asOrg'),
value: _.get(n.myData, 'basicInfo.asn.organization', '-')
},
{
name: 'isp',
label: this.$t('entities.graph.isp'),
value: _.get(n.myData, 'basicInfo.location.isp', '-')
},
{ name: 'location', label: this.$t('overall.location'), value: this.location(n.myData) }
]
this.relationList = [
{
icon: 'cn-icon cn-icon-subdomain',
name: 'domain',
label: this.$t('entity.graph.resolveDomain'),
value: _.get(n.myData, 'relatedEntity.domain.list', []).length,
total: _.get(n.myData, 'relatedEntity.domain.total', 0) || 0
},
{
icon: 'cn-icon cn-icon-app-name',
name: 'app',
label: this.$t('entities.tab.relatedApp'),
value: _.get(n.myData, 'relatedEntity.app.list', []).length,
total: _.get(n.myData, 'relatedEntity.app.total', '0') || 0
}
]
break
}
case 'domain': {
const expireDate = _.get(n.myData, 'basicInfo.whois.expireDate', '')
const createDate = _.get(n.myData, 'basicInfo.whois.createDate', '')
this.detailCards = [
{
name: 'categoryName',
label: this.$t('entities.category'),
value: _.get(n.myData, 'basicInfo.category.name', '-')
},
{
name: 'categoryGroup',
label: this.$t('entities.group'),
value: _.get(n.myData, 'basicInfo.category.group', '-')
},
{
name: 'reputationLevel',
label: this.$t('entities.creditLevel2'),
value: _.get(n.myData, 'basicInfo.category.reputationLevel', '-')
},
{
name: 'expireDate',
label: this.$t('entities.graph.expirationDate'),
value: expireDate ? dateFormatByAppearance(expireDate) : '-'
},
{
name: 'registrarName',
label: this.$t('entities.registrar'),
value: _.get(n.myData, 'basicInfo.whois.registrarName', '-')
},
{
name: 'registrantOrg',
label: this.$t('entities.registry'),
value: _.get(n.myData, 'basicInfo.whois.registrantOrg', '-')
},
{
name: 'registrantCountry',
label: this.$t('entities.registrationCountry'),
value: _.get(n.myData, 'basicInfo.whois.registrantCountry', '-')
},
{
name: 'createDate',
label: this.$t('entities.registrationDate'),
value: createDate ? dateFormatByAppearance(createDate) : '-'
},
{
name: 'email',
label: this.$t('entities.registryEmail'),
value: _.get(n.myData, 'basicInfo.whois.email', '-')
}
]
this.relationList = [
{
icon: 'cn-icon cn-icon-resolve-ip',
name: 'ip',
label: this.$t('entities.graph.resolveIp'),
value: _.get(n.myData, 'relatedEntity.ip.list', []).length,
total: _.get(n.myData, 'relatedEntity.ip.total', '0') || 0
},
{
icon: 'cn-icon cn-icon-subdomain',
name: 'domain',
label: this.$t('entities.subdomain'),
value: _.get(n.myData, 'relatedEntity.domain.list', []).length,
total: _.get(n.myData, 'relatedEntity.domain.total', '0') || 0
},
{
icon: 'cn-icon cn-icon-app-name',
name: 'app',
label: this.$t('entities.tab.relatedApp'),
value: _.get(n.myData, 'relatedEntity.app.list', []).length,
total: _.get(n.myData, 'relatedEntity.app.total', 0) || 0
}
]
break
}
case 'app': {
this.detailCards = [
{
name: 'appCategory',
label: this.$t('entities.category'),
value: _.get(n.myData, 'detail.category.appCategory', '-')
},
{
name: 'appSubcategory',
label: this.$t('entities.subcategory'),
value: _.get(n.myData, 'detail.category.appSubcategory', '-')
},
{
name: 'appRisk',
label: this.$t('entities.riskLevel'),
value: _.get(n.myData, 'detail.category.appRisk', '-')
},
{
name: 'appTechnology',
label: this.$t('overall.technology'),
value: _.get(n.myData, 'detail.category.appTechnology', '-')
},
{
name: 'appLongname',
label: this.$t('overall.appFullName'),
value: _.get(n.myData, 'detail.category.appLongname', '-')
},
{
name: 'appDescription',
label: this.$t('config.dataSource.description'),
value: _.get(n.myData, 'detail.category.appDescription', '-')
}
]
this.relationList = [
{
icon: 'cn-icon cn-icon-resolve-ip',
name: 'ip',
label: this.$t('entities.tab.relatedIp'),
value: _.get(n.myData, 'relatedEntity.ip.list', []).length,
total: _.get(n.myData, 'relatedEntity.ip.total', '0') || 0
},
{
icon: 'cn-icon cn-icon-subdomain',
name: 'domain',
label: this.$t('entities.graph.relatedDomain'),
value: _.get(n.myData, 'relatedEntity.domain.list', []).length,
total: _.get(n.myData, 'relatedEntity.domain.total', '0') || 0
}
]
}
}
}
}
}
</script>