CN-1087 feat: 实体关系
@@ -103,7 +103,7 @@ $font-size: 12px;
|
|||||||
.graph-content-item {
|
.graph-content-item {
|
||||||
|
|
||||||
.graph-content-item-label, .graph-content-item-value {
|
.graph-content-item-label, .graph-content-item-value {
|
||||||
width: 100px;
|
width: 130px;
|
||||||
font-family: NotoSansSChineseRegular;
|
font-family: NotoSansSChineseRegular;
|
||||||
font-size: $font-size;
|
font-size: $font-size;
|
||||||
color: #717171;
|
color: #717171;
|
||||||
@@ -125,14 +125,8 @@ $font-size: 12px;
|
|||||||
.graph-content-relationship-item {
|
.graph-content-relationship-item {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba(135, 135, 135, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.graph-relationship-item-label, .graph-relationship-item-value {
|
.graph-relationship-item-label, .graph-relationship-item-value {
|
||||||
font-family: NotoSansSChineseRegular;
|
|
||||||
font-size: $font-size;
|
font-size: $font-size;
|
||||||
color: #353636;
|
color: #353636;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@@ -148,6 +142,10 @@ $font-size: 12px;
|
|||||||
|
|
||||||
.graph-relationship-item-value {
|
.graph-relationship-item-value {
|
||||||
color: #717171;
|
color: #717171;
|
||||||
|
|
||||||
|
i {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,9 +194,6 @@ $font-size: 12px;
|
|||||||
|
|
||||||
.graph-expand-relationship__icon {
|
.graph-expand-relationship__icon {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
&:hover {
|
|
||||||
color: #D80000 !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-basic-info__block-title {
|
.graph-basic-info__block-title {
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ $font-size: 12px;
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
font-family: PingFangSC-Semibold;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #353636;
|
color: #353636;
|
||||||
line-height: 22px;
|
line-height: 21px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +23,6 @@ $font-size: 12px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.graph-list-header-number {
|
.graph-list-header-number {
|
||||||
font-family: NotoSansSChineseRegular;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #717171;
|
color: #717171;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@@ -49,7 +47,6 @@ $font-size: 12px;
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-family: NotoSansHans-Medium;
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
padding: 14px 10px;
|
padding: 14px 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -59,6 +56,11 @@ $font-size: 12px;
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.graph-list-expand-btn--disabled {
|
||||||
|
opacity: .4;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,15 +75,9 @@ $font-size: 12px;
|
|||||||
|
|
||||||
.graph-list-item-ip {
|
.graph-list-item-ip {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
font-family: NotoSansSChineseRegular;
|
|
||||||
font-size: $font-size;
|
font-size: $font-size;
|
||||||
color: #353636;
|
color: #353636;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #D80000;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-list-item-block {
|
.graph-list-item-block {
|
||||||
@@ -97,7 +93,6 @@ $font-size: 12px;
|
|||||||
.graph-list-item-label, .graph-list-item-label__app {
|
.graph-list-item-label, .graph-list-item-label__app {
|
||||||
width: 62px;
|
width: 62px;
|
||||||
//margin-right: 15px;
|
//margin-right: 15px;
|
||||||
font-family: NotoSansSChineseRegular;
|
|
||||||
font-size: $font-size;
|
font-size: $font-size;
|
||||||
color: #717171;
|
color: #717171;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@@ -118,7 +113,6 @@ $font-size: 12px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.graph-list-item-value {
|
.graph-list-item-value {
|
||||||
font-family: NotoSansSChineseRegular;
|
|
||||||
font-size: $font-size;
|
font-size: $font-size;
|
||||||
color: #353636;
|
color: #353636;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
@@ -255,6 +255,8 @@ export const api = {
|
|||||||
informationAggregation: apiVersion + '/entity/detail/kb/intelligence/list',
|
informationAggregation: apiVersion + '/entity/detail/kb/intelligence/list',
|
||||||
// 实体关系
|
// 实体关系
|
||||||
entityGraph: {
|
entityGraph: {
|
||||||
|
basicInfo: apiVersion + '/entity/graph/relation/basic',
|
||||||
|
tags: apiVersion + '/entity/graph/relation/kb/intelligence/tag',
|
||||||
relatedEntityCount: apiVersion + '/entity/graph/relation/summaryCount',
|
relatedEntityCount: apiVersion + '/entity/graph/relation/summaryCount',
|
||||||
domainRelatedIp: apiVersion + '/entity/graph/relation/domain/relate/ips',
|
domainRelatedIp: apiVersion + '/entity/graph/relation/domain/relate/ips',
|
||||||
domainRelatedApp: apiVersion + '/entity/graph/relation/domain/relate/apps',
|
domainRelatedApp: apiVersion + '/entity/graph/relation/domain/relate/apps',
|
||||||
|
|||||||
@@ -37,25 +37,15 @@ export default {
|
|||||||
location () {
|
location () {
|
||||||
let location = ''
|
let location = ''
|
||||||
if (this.chartInfo) {
|
if (this.chartInfo) {
|
||||||
if (this.chartInfo.country) {
|
if (this.chartInfo.city) {
|
||||||
location = this.chartInfo.country
|
|
||||||
if (this.chartInfo.province) {
|
|
||||||
location += ', '
|
|
||||||
location += this.chartInfo.province
|
|
||||||
if (this.chartInfo.city) {
|
|
||||||
location += ', '
|
|
||||||
location += this.chartInfo.city
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (this.chartInfo.province) {
|
|
||||||
location = this.chartInfo.province
|
|
||||||
if (this.chartInfo.city) {
|
|
||||||
location += ', '
|
|
||||||
location += this.chartInfo.city
|
|
||||||
}
|
|
||||||
} else if (this.chartInfo.city) {
|
|
||||||
location = this.chartInfo.city
|
location = this.chartInfo.city
|
||||||
}
|
}
|
||||||
|
if (this.chartInfo.province) {
|
||||||
|
location = location ? `${this.chartInfo.province}, ${location}` : this.chartInfo.province
|
||||||
|
}
|
||||||
|
if (this.chartInfo.country) {
|
||||||
|
location = location ? `${this.chartInfo.country}, ${location}` : this.chartInfo.country
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return location
|
return location
|
||||||
},
|
},
|
||||||
|
|||||||
115
src/views/entityExplorer/entityGraphDetail/AppList.vue
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<loading :loading="entity.loading" size="small"></loading>
|
||||||
|
<div class="graph-list-header">
|
||||||
|
<div>
|
||||||
|
<div class="graph-list-header-title">
|
||||||
|
<i class="graph-list-header-icon cn-icon cn-icon-app-name"></i>
|
||||||
|
<span>{{ $t('entities.tab.relatedApp') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-header-number">
|
||||||
|
{{ $t('entity.graph.associatedQuantity') }}: <span>{{entity.count}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<i class="cn-icon cn-icon-close graph-close" @click="closeBlock"></i>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-expand-btn-block">
|
||||||
|
<div class="graph-list-expand-btn" :class="{ 'graph-list-expand-btn--disabled': expandBtnDisable }" style="display: inline-flex;" @click="expandList">
|
||||||
|
<i class="cn-icon cn-icon-expand-continue graph-expand-continue"></i>
|
||||||
|
{{ $t('entity.graph.continueToExpand') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="digital-certificate">
|
||||||
|
<div class="digital-certificate-header padding-b-12">
|
||||||
|
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
||||||
|
<div class="graph-list-content-header ">
|
||||||
|
{{ $t('entity.graph.expandedEntityQuantity') }}:
|
||||||
|
<span>{{ entity.listData ? entity.listData.length : 0 }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="graph-list-content">
|
||||||
|
<div v-for="(item, index) in entity.listData" :key="index" @mouseenter="onMouseenter(item)">
|
||||||
|
<div class="graph-list-item-ip" @click="expandDetail">{{ item.vertex }}</div>
|
||||||
|
<div class="graph-list-item-block">
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">APP ID:</div>
|
||||||
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'category.appId', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">{{$t('entities.category')}}:</div>
|
||||||
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'category.appCategory', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">{{$t('entities.subcategory')}}:</div>
|
||||||
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'category.appSubcategory', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">{{$t('entities.riskLevel')}}:</div>
|
||||||
|
<div class="graph-list-item-value">{{ appRisk($_.get(item.detail, 'category.appRisk', '-')) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">{{$t('config.dataSource.description')}}:</div>
|
||||||
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'category.appDescription', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-dividing-line" v-if="index !== entity.listData.length - 1"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { riskLevelMapping } from '@/utils/constants'
|
||||||
|
import Loading from '@/components/common/Loading'
|
||||||
|
export default {
|
||||||
|
name: 'AppList',
|
||||||
|
props: {
|
||||||
|
entity: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Loading
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
appRisk () {
|
||||||
|
return function (level) {
|
||||||
|
const m = riskLevelMapping.find(mapping => {
|
||||||
|
return mapping.value == level
|
||||||
|
})
|
||||||
|
return (m && m.name) || level
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expandBtnDisable () {
|
||||||
|
return !((this.entity.listData ? this.entity.listData.length : 0) < this.entity.count && this.entity.count > 10 && (this.entity.listData && this.entity.listData.length < 50))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
closeBlock () {
|
||||||
|
this.$emit('closeBlock')
|
||||||
|
},
|
||||||
|
expandDetail () {
|
||||||
|
if (this.entity.entityType === 'app') {
|
||||||
|
this.$emit('expandDetail', 'appDetail')
|
||||||
|
} else if (this.entity.entityType === 'domain') {
|
||||||
|
this.$emit('expandDetail', 'domainDetail')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onMouseenter (val) {
|
||||||
|
// 鼠标移动过graph列表名称时,graph图的分支图形会变大一点
|
||||||
|
this.$emit('mouseenter', val)
|
||||||
|
},
|
||||||
|
expandList () {
|
||||||
|
// 继续拓展ip列表,传递信息,调用接口
|
||||||
|
if (!this.expandBtnDisable) {
|
||||||
|
this.$emit('expandList', this.entity.sourceName, this.entity.nodeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div class="graph-list-header">
|
|
||||||
<div>
|
|
||||||
<div class="graph-list-header-title">
|
|
||||||
<i class="graph-list-header-icon" :class="entityIcon"></i>
|
|
||||||
<span>{{ $t(entityName) }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="graph-list-header-number" style="margin-bottom: 24px">
|
|
||||||
{{ $t('entity.graph.associatedQuantity') }}:<span>2</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<i class="cn-icon cn-icon-close graph-close" @click="closeBlock"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class="digital-certificate">
|
|
||||||
<div class="digital-certificate-header padding-b-12">
|
|
||||||
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
|
||||||
<div class="graph-list-content-header ">
|
|
||||||
{{ $t('entity.graph.expandedEntityQuantity') }}:
|
|
||||||
<span>{{ cardData.length }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="graph-list-content">
|
|
||||||
<div v-for="(item, index) in cardData" :key="index" @mouseenter="onMouseenter(item)">
|
|
||||||
<div class="graph-list-item-ip" @click="expandDetail">{{ item.name }}</div>
|
|
||||||
<div class="graph-list-item-block">
|
|
||||||
<div v-for="card in item.data" :key="card.name">
|
|
||||||
<div class="graph-list-item__app">
|
|
||||||
<div class="graph-list-item-label__app">{{ card.label }}:</div>
|
|
||||||
<div class="graph-list-item-value">{{ card.value }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="graph-list-dividing-line" v-if="index !== cardData.length - 1"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import i18n from '@/i18n'
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'AppOrDomainList',
|
|
||||||
props: {
|
|
||||||
entity: {
|
|
||||||
type: Object
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
this.initData()
|
|
||||||
},
|
|
||||||
setup (props) {
|
|
||||||
const cardData = ref([]) // 列表数据
|
|
||||||
const entityIcon = ref('') // 顶部icon
|
|
||||||
const entityName = ref('') // 顶部名称,非实体名
|
|
||||||
|
|
||||||
switch (props.entity.entityType) {
|
|
||||||
case 'app': {
|
|
||||||
entityIcon.value = 'cn-icon cn-icon-app-name'
|
|
||||||
entityName.value = 'entities.tab.relatedApp'
|
|
||||||
|
|
||||||
cardData.value = [
|
|
||||||
{
|
|
||||||
name: 'Wechat',
|
|
||||||
data: [
|
|
||||||
{ name: 'appId', label: i18n.global.t('entities.domainDetail.appid'), value: '2376' },
|
|
||||||
{ name: 'appCategory', label: i18n.global.t('entities.category'), value: 'Sensitive' },
|
|
||||||
{ name: 'appSubcategory', label: i18n.global.t('entities.subcategory'), value: 'Parked Domain' },
|
|
||||||
{ name: 'appRisk', label: i18n.global.t('entities.riskLevel'), value: 'Moderate Risk' },
|
|
||||||
{ name: 'appDescription', label: i18n.global.t('config.dataSource.description'), value: 'Wechat is a Chinese multinational networking and services company.' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Wechat',
|
|
||||||
data: [
|
|
||||||
{ name: 'appId', label: i18n.global.t('entities.domainDetail.appid'), value: '2376' },
|
|
||||||
{ name: 'appCategory', label: i18n.global.t('entities.category'), value: 'Sensitive' },
|
|
||||||
{ name: 'appSubcategory', label: i18n.global.t('entities.subcategory'), value: 'Parked Domain' },
|
|
||||||
{ name: 'appRisk', label: i18n.global.t('entities.riskLevel'), value: 'Moderate Risk' },
|
|
||||||
{ name: 'appDescription', label: i18n.global.t('config.dataSource.description'), value: 'Wechat is a Chinese multinational networking and services company.' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'domain': {
|
|
||||||
entityIcon.value = 'cn-icon cn-icon-subdomain'
|
|
||||||
entityName.value = 'entities.subdomain'
|
|
||||||
|
|
||||||
cardData.value = [
|
|
||||||
{
|
|
||||||
name: '-*.webproxy.at.1.baidu.com',
|
|
||||||
data: [
|
|
||||||
{ name: 'categoryName', label: i18n.global.t('entities.category'), value: 'Business and Economy' },
|
|
||||||
{ name: 'categoryGroup', label: i18n.global.t('entities.group'), value: 'Productivity' },
|
|
||||||
{ name: 'registration', label: i18n.global.t('entities.registration'), value: 'China' },
|
|
||||||
{ name: 'registrantOrg', label: i18n.global.t('entities.registry'), value: 'Beijing Baidu Netcom Science Technology Co, Ltd' },
|
|
||||||
{ name: 'icpLicense', label: i18n.global.t('entities.icpLicense'), value: '京ICP备24537号' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '-*.webproxy.at.1.baidu.com',
|
|
||||||
data: [
|
|
||||||
{ name: 'categoryName', label: i18n.global.t('entities.category'), value: 'Business and Economy' },
|
|
||||||
{ name: 'categoryGroup', label: i18n.global.t('entities.group'), value: 'Productivity' },
|
|
||||||
{ name: 'registration', label: i18n.global.t('entities.registration'), value: 'China' },
|
|
||||||
{ name: 'registrantOrg', label: i18n.global.t('entities.registry'), value: 'Beijing Baidu Netcom Science Technology Co, Ltd' },
|
|
||||||
{ name: 'icpLicense', label: i18n.global.t('entities.icpLicense'), value: '京ICP备24537号' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
entityIcon,
|
|
||||||
entityName,
|
|
||||||
cardData
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initData () {
|
|
||||||
// 此处请求接口
|
|
||||||
},
|
|
||||||
closeBlock () {
|
|
||||||
this.$emit('closeBlock')
|
|
||||||
},
|
|
||||||
expandDetail () {
|
|
||||||
if (this.entity.entityType === 'app') {
|
|
||||||
this.$emit('expandDetail', 'appDetail')
|
|
||||||
} else if (this.entity.entityType === 'domain') {
|
|
||||||
this.$emit('expandDetail', 'domainDetail')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onMouseenter (val) {
|
|
||||||
// 鼠标移动过graph列表名称时,graph图的分支图形会变大一点
|
|
||||||
this.$emit('mouseenter', val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
111
src/views/entityExplorer/entityGraphDetail/DomainList.vue
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<loading :loading="entity.loading" size="small"></loading>
|
||||||
|
<div class="graph-list-header">
|
||||||
|
<div>
|
||||||
|
<div class="graph-list-header-title">
|
||||||
|
<i class="graph-list-header-icon cn-icon cn-icon-subdomain"></i>
|
||||||
|
<span>{{ entity.isSubdomain ? $t('entities.subdomain') : $t('entity.graph.resolveDomain') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-header-number">
|
||||||
|
{{ $t('entity.graph.associatedQuantity') }}: <span>{{entity.count}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<i class="cn-icon cn-icon-close graph-close" @click="closeBlock"></i>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-expand-btn-block">
|
||||||
|
<div class="graph-list-expand-btn" :class="{ 'graph-list-expand-btn--disabled': expandBtnDisable }" style="display: inline-flex;" @click="expandList">
|
||||||
|
<i class="cn-icon cn-icon-expand-continue graph-expand-continue"></i>
|
||||||
|
{{ $t('entity.graph.continueToExpand') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="digital-certificate">
|
||||||
|
<div class="digital-certificate-header padding-b-12">
|
||||||
|
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
||||||
|
<div class="graph-list-content-header ">
|
||||||
|
{{ $t('entity.graph.expandedEntityQuantity') }}:
|
||||||
|
<span>{{ entity.listData ? entity.listData.length : 0 }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="graph-list-content">
|
||||||
|
<div v-for="(item, index) in entity.listData" :key="index" @mouseenter="onMouseenter(item)">
|
||||||
|
<div class="graph-list-item-ip" @click="expandDetail">{{ item.vertex }}</div>
|
||||||
|
<div class="graph-list-item-block">
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">{{$t('entities.category')}}:</div>
|
||||||
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'category.name', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">{{$t('entities.group')}}:</div>
|
||||||
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'category.group', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">{{$t('entities.registration')}}:</div>
|
||||||
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'whois.registrantCountry', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-item__app">
|
||||||
|
<div class="graph-list-item-label__app">{{$t('entities.registry')}}:</div>
|
||||||
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'whois.registrantOrg', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-list-dividing-line" v-if="index !== entity.listData.length - 1"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { riskLevelMapping } from '@/utils/constants'
|
||||||
|
import Loading from '@/components/common/Loading'
|
||||||
|
export default {
|
||||||
|
name: 'DomainList',
|
||||||
|
props: {
|
||||||
|
entity: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Loading
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
appRisk () {
|
||||||
|
return function (level) {
|
||||||
|
const m = riskLevelMapping.find(mapping => {
|
||||||
|
return mapping.value == level
|
||||||
|
})
|
||||||
|
return (m && m.name) || level
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expandBtnDisable () {
|
||||||
|
return !((this.entity.listData ? this.entity.listData.length : 0) < this.entity.count && this.entity.count > 10 && (this.entity.listData && this.entity.listData.length < 50))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
closeBlock () {
|
||||||
|
this.$emit('closeBlock')
|
||||||
|
},
|
||||||
|
expandDetail () {
|
||||||
|
if (this.entity.entityType === 'app') {
|
||||||
|
this.$emit('expandDetail', 'appDetail')
|
||||||
|
} else if (this.entity.entityType === 'domain') {
|
||||||
|
this.$emit('expandDetail', 'domainDetail')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onMouseenter (val) {
|
||||||
|
// 鼠标移动过graph列表名称时,graph图的分支图形会变大一点
|
||||||
|
this.$emit('mouseenter', val)
|
||||||
|
},
|
||||||
|
expandList () {
|
||||||
|
// 继续拓展ip列表,传递信息,调用接口
|
||||||
|
if (!this.expandBtnDisable) {
|
||||||
|
this.$emit('expandList', this.entity.sourceName, this.entity.nodeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -5,10 +5,10 @@
|
|||||||
<div class="graph-detail__icon"><i :class="iconClass"></i></div>
|
<div class="graph-detail__icon"><i :class="iconClass"></i></div>
|
||||||
|
|
||||||
<div class="graph-detail-header">
|
<div class="graph-detail-header">
|
||||||
<div class="entity-graph-type">{{ entityType[entity.entityType] }}</div>
|
<div class="entity-graph-type">{{ entityType[entity.type || entity.entityType] }}</div>
|
||||||
<div class="graph-basic-info">
|
<div class="graph-basic-info">
|
||||||
<div class="graph-basic-info-name__block">
|
<div class="graph-basic-info-name__block">
|
||||||
<div class="graph-basic-info-name" id="entityName">{{ entity.entityName }}</div>
|
<div class="graph-basic-info-name" id="entityName">{{ $_.get(entity, 'detailData.vertex', '') }}</div>
|
||||||
<div class="graph-basic-info-icon" @click="copyEntityName">
|
<div class="graph-basic-info-icon" @click="copyEntityName">
|
||||||
<i class="cn-icon cn-icon-copy"></i>
|
<i class="cn-icon cn-icon-copy"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,15 +30,94 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="graph-basic-info__block-content">
|
<div class="graph-basic-info__block-content">
|
||||||
<div class="graph-content-item" v-for="item in detailCards" :key="item.name">
|
<template v-if="entity.type === 'ip'">
|
||||||
<div class="graph-content-item-label">{{ item.label }}:</div>
|
<div class="graph-content-item" >
|
||||||
<div class="graph-content-item-value">{{ item.value || '-' }}</div>
|
<div class="graph-content-item-label">{{ $t('entities.asNumber') }}:</div>
|
||||||
</div>
|
<div class="graph-content-item-value">{{ $_.get(entity.detailData, 'detail.asn.asn', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.asOrg') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity.detailData, 'detail.asn.organization', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.graph.isp') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity.detailData, 'detail.location.isp', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('overall.location') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ location(entity.detailData) }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="entity.type === 'domain'">
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.category') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.category.name', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.group') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.category.group', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.creditLevel2') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.category.reputationLevel', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.graph.expirationDate') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ handleDate('detailData.detail.whois.expireDate') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.registrar') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.whois.registrarName', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.registry') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.whois.registrantOrg', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.registrationCountry') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.whois.registrantCountry', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.registrationDate') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ handleDate('detailData.detail.whois.createDate') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.registryEmail') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.whois.email', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="entity.type === 'app'">
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.category') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.category.appCategory', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.subcategory') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.category.appSubcategory', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('entities.riskLevel') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ appRisk($_.get(entity, 'detailData.detail.category.appRisk', '-')) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('overall.technology') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.category.appTechnology', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('overall.appFullName') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.category.appLongname', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="graph-content-item" >
|
||||||
|
<div class="graph-content-item-label">{{ $t('config.dataSource.description') }}:</div>
|
||||||
|
<div class="graph-content-item-value">{{ $_.get(entity, 'detailData.detail.category.appDescription', '-') }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--关系拓展-->
|
<!--关系拓展-->
|
||||||
<div class="digital-certificate graph-basic-info__block">
|
<div class="digital-certificate graph-basic-info__block">
|
||||||
|
<loading :loading="entity.loading" size="small"></loading>
|
||||||
<div class="digital-certificate-header padding-b-10">
|
<div class="digital-certificate-header padding-b-10">
|
||||||
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
||||||
<div class="graph-basic-info__block-title">
|
<div class="graph-basic-info__block-title">
|
||||||
@@ -47,28 +126,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="graph-basic-info__block-content" style="margin-top: -4px;">
|
<div class="graph-basic-info__block-content" style="margin-top: -4px;">
|
||||||
<div v-for="item in relationList" :key="item.name" @click="expandRelation(item.name)">
|
<div v-for="item in relationList" :key="item.name">
|
||||||
<el-popover
|
<div class="graph-content-item graph-content-relationship-item" v-if="item.value === item.total">
|
||||||
v-if="item.value.length === item.total"
|
<div class="graph-relationship-item-label">
|
||||||
placement="top"
|
<i class="margin-r-6" :class="item.icon"></i>
|
||||||
auto-close="2000"
|
<span>{{ item.label }}:</span>
|
||||||
trigger="click"
|
</div>
|
||||||
:content="$t('entity.graph.completed')"
|
<div class="graph-relationship-item-value">
|
||||||
popper-class="graph-popover"
|
<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>
|
||||||
<template #reference>
|
</div>
|
||||||
<div class="graph-content-item graph-content-relationship-item">
|
</div>
|
||||||
<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.length }}/{{ item.total }}</span>
|
|
||||||
<i class="cn-icon cn-icon-expand-relationship" :style="{color: iconColor(item.value.length, item.total)}"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-popover>
|
|
||||||
|
|
||||||
<div v-else class="graph-content-item graph-content-relationship-item">
|
<div v-else class="graph-content-item graph-content-relationship-item">
|
||||||
<div class="graph-relationship-item-label">
|
<div class="graph-relationship-item-label">
|
||||||
@@ -76,14 +144,8 @@
|
|||||||
<span>{{ item.label }}:</span>
|
<span>{{ item.label }}:</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="graph-relationship-item-value">
|
<div class="graph-relationship-item-value">
|
||||||
<span class="margin-r-6">{{ item.value.length }}/{{ item.total }}</span>
|
<span class="margin-r-6">{{ item.value }}/{{ item.total }}</span>
|
||||||
<el-tooltip
|
<i class="cn-icon cn-icon-expand-relationship graph-expand-relationship__icon" :style="{color: iconColor(item.value, item.total)}" @click="expandRelation(item.name)"></i>
|
||||||
effect="dark"
|
|
||||||
:content="$t('entity.graph.expandDownward')"
|
|
||||||
placement="top-end"
|
|
||||||
>
|
|
||||||
<i class="cn-icon cn-icon-expand-relationship graph-expand-relationship__icon" :style="{color: iconColor(item.value.length, item.total)}"></i>
|
|
||||||
</el-tooltip>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -95,13 +157,13 @@
|
|||||||
<div class="digital-certificate-header padding-b-10">
|
<div class="digital-certificate-header padding-b-10">
|
||||||
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
||||||
<div class="graph-basic-info__block-title">
|
<div class="graph-basic-info__block-title">
|
||||||
{{ $t('entity.graph.labels') }}
|
{{ $t('entity.graph.tags') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="entity-detail graph-basic-info__block-content">
|
<div class="entity-detail graph-basic-info__block-content">
|
||||||
<div class="graph-tag-list">
|
<div class="graph-tag-list">
|
||||||
<div v-for="ic in tagList" :key="ic.key">
|
<div v-for="ic in entity.tags" :key="ic.value">
|
||||||
<div class="entity-tag graph-tag-item" :class="`entity-tag--level-two-${ic.type}`">
|
<div class="entity-tag graph-tag-item" :class="`entity-tag--level-two-${ic.type}`">
|
||||||
<span>{{ic.value}}</span>
|
<span>{{ic.value}}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -112,15 +174,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import i18n from '@/i18n'
|
|
||||||
import { copySelectionText, selectElementText } from '@/utils/tools'
|
import { copySelectionText, selectElementText } from '@/utils/tools'
|
||||||
import { entityType, riskLevelMapping } from '@/utils/constants'
|
import { entityType, riskLevelMapping } from '@/utils/constants'
|
||||||
import axios from 'axios'
|
|
||||||
import { api } from '@/utils/api'
|
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import { dateFormatByAppearance } from '@/utils/date-util'
|
import { dateFormatByAppearance } from '@/utils/date-util'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import Loading from '@/components/common/Loading'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DomainDetail',
|
name: 'DomainDetail',
|
||||||
@@ -130,12 +190,23 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [chartMixin],
|
mixins: [chartMixin],
|
||||||
|
components: {
|
||||||
|
Loading
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
entityType
|
entityType
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
appRisk () {
|
||||||
|
return function (level) {
|
||||||
|
const m = riskLevelMapping.find(mapping => {
|
||||||
|
return mapping.value == level
|
||||||
|
})
|
||||||
|
return (m && m.name) || level
|
||||||
|
}
|
||||||
|
},
|
||||||
iconClass () {
|
iconClass () {
|
||||||
let className
|
let className
|
||||||
switch (this.entity.entityType) {
|
switch (this.entity.entityType) {
|
||||||
@@ -155,87 +226,187 @@ export default {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
return className
|
return className
|
||||||
|
},
|
||||||
|
handleDate () {
|
||||||
|
return function (key) {
|
||||||
|
const date = _.get(this.entity, key, '')
|
||||||
|
return date ? dateFormatByAppearance(date) : '-'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
watch: {
|
||||||
this.initData()
|
entity: {
|
||||||
|
deep: true,
|
||||||
|
handler (n) {
|
||||||
|
const type = n.type || n.entityType
|
||||||
|
switch (type) {
|
||||||
|
case 'ip': {
|
||||||
|
this.detailCards = [
|
||||||
|
{ name: 'asn', label: this.$t('entities.asNumber'), value: _.get(n.detailData, 'detail.asn.asn', '-') },
|
||||||
|
{
|
||||||
|
name: 'asOrg',
|
||||||
|
label: this.$t('entities.asOrg'),
|
||||||
|
value: _.get(n.detailData, 'detail.asn.organization', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'isp',
|
||||||
|
label: this.$t('entities.graph.isp'),
|
||||||
|
value: _.get(n.detailData, 'detail.location.isp', '-')
|
||||||
|
},
|
||||||
|
{ name: 'location', label: this.$t('overall.location'), value: this.location(n.detailData) }
|
||||||
|
]
|
||||||
|
this.relationList = [
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-subdomain',
|
||||||
|
name: 'domain',
|
||||||
|
label: this.$t('entity.graph.resolveDomain'),
|
||||||
|
value: _.get(n.relatedEntityCount, 'domain.current', '0') || 0,
|
||||||
|
total: _.get(n.relatedEntityCount, 'domain.total', '0') || 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-app-name',
|
||||||
|
name: 'app',
|
||||||
|
label: this.$t('entities.tab.relatedApp'),
|
||||||
|
value: _.get(n.relatedEntityCount, 'app.current', '0') || 0,
|
||||||
|
total: _.get(n.relatedEntityCount, 'app.total', '0') || 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'domain': {
|
||||||
|
const expireDate = _.get(n.detailData, 'detail.whois.expireDate', '')
|
||||||
|
const createDate = _.get(n.detailData, 'detail.whois.createDate', '')
|
||||||
|
this.detailCards = [
|
||||||
|
{
|
||||||
|
name: 'categoryName',
|
||||||
|
label: this.$t('entities.category'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.name', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'categoryGroup',
|
||||||
|
label: this.$t('entities.group'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.group', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'reputationLevel',
|
||||||
|
label: this.$t('entities.creditLevel2'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.reputationLevel', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'expireDate',
|
||||||
|
label: this.$t('entities.graph.expirationDate'),
|
||||||
|
value: expireDate ? dateFormatByAppearance(expireDate) : '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'registrarName',
|
||||||
|
label: this.$t('entities.registrar'),
|
||||||
|
value: _.get(n.detailData, 'detail.whois.registrarName', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'registrantOrg',
|
||||||
|
label: this.$t('entities.registry'),
|
||||||
|
value: _.get(n.detailData, 'detail.whois.registrantOrg', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'registrantCountry',
|
||||||
|
label: this.$t('entities.registrationCountry'),
|
||||||
|
value: _.get(n.detailData, 'detail.whois.registrantCountry', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'createDate',
|
||||||
|
label: this.$t('entities.registrationDate'),
|
||||||
|
value: createDate ? dateFormatByAppearance(createDate) : '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'email',
|
||||||
|
label: this.$t('entities.registryEmail'),
|
||||||
|
value: _.get(n.detailData, 'detail.whois.email', '-')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
this.relationList = [
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-resolve-ip',
|
||||||
|
name: 'ip',
|
||||||
|
label: this.$t('entities.graph.resolveIp'),
|
||||||
|
value: _.get(n.relatedEntityCount, 'ip.current', '0') || 0,
|
||||||
|
total: _.get(n.relatedEntityCount, 'ip.total', '0') || 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-subdomain',
|
||||||
|
name: 'subDomain',
|
||||||
|
label: this.$t('entities.subdomain'),
|
||||||
|
value: _.get(n.relatedEntityCount, 'subDomain.current', '0') || 0,
|
||||||
|
total: _.get(n.relatedEntityCount, 'subDomain.total', '0') || 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-app-name',
|
||||||
|
name: 'app',
|
||||||
|
label: this.$t('entities.tab.relatedApp'),
|
||||||
|
value: _.get(n.relatedEntityCount, 'app.current', 0) || 0,
|
||||||
|
total: _.get(n.relatedEntityCount, 'app.total', 0) || 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'app': {
|
||||||
|
this.detailCards = [
|
||||||
|
{
|
||||||
|
name: 'appCategory',
|
||||||
|
label: this.$t('entities.category'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.appCategory', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'appSubcategory',
|
||||||
|
label: this.$t('entities.subcategory'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.appSubcategory', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'appRisk',
|
||||||
|
label: this.$t('entities.riskLevel'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.appRisk', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'appTechnology',
|
||||||
|
label: this.$t('overall.technology'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.appTechnology', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'appLongname',
|
||||||
|
label: this.$t('overall.appFullName'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.appLongname', '-')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'appDescription',
|
||||||
|
label: this.$t('config.dataSource.description'),
|
||||||
|
value: _.get(n.detailData, 'detail.category.appDescription', '-')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
this.relationList = [
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-resolve-ip',
|
||||||
|
name: 'ip',
|
||||||
|
label: this.$t('entities.graph.resolveIp'),
|
||||||
|
value: _.get(n.relatedEntityCount, 'ip.current', '0') || 0,
|
||||||
|
total: _.get(n.relatedEntityCount, 'ip.total', '0') || 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-subdomain',
|
||||||
|
name: 'domain',
|
||||||
|
label: this.$t('entity.graph.resolveDomain'),
|
||||||
|
value: _.get(n.relatedEntityCount, 'domain.current', '0') || 0,
|
||||||
|
total: _.get(n.relatedEntityCount, 'domain.total', '0') || 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setup (props) {
|
setup (props) {
|
||||||
const detailCards = ref([])
|
const detailCards = ref([])
|
||||||
const relationList = ref([])
|
const relationList = ref([])
|
||||||
const tagList = ref([])
|
const tagList = ref([])
|
||||||
// 标签列表,后续请求接口时处理
|
|
||||||
tagList.value = [
|
|
||||||
{ key: 'isp', value: '信息技术', type: 'positive' },
|
|
||||||
{ key: 'malwareName', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName1', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName2', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName3', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName4', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName5', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName6', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName7', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName8', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName9', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName10', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName11', value: '互联网', type: 'normal' },
|
|
||||||
{ key: 'malwareName12', value: '互联网', type: 'normal' }
|
|
||||||
]
|
|
||||||
|
|
||||||
switch (props.entity.entityType) {
|
|
||||||
case 'ip': {
|
|
||||||
detailCards.value = _.concat(detailCards.value,
|
|
||||||
{ name: 'asn', label: i18n.global.t('entities.asNumber'), value: '' },
|
|
||||||
{ name: 'asOrg', label: i18n.global.t('entities.asOrg'), value: '' },
|
|
||||||
{ name: 'asSubnet', label: i18n.global.t('entities.asSubnet'), value: '' },
|
|
||||||
{ name: 'isp', label: i18n.global.t('entities.graph.isp'), value: '' },
|
|
||||||
{ name: 'location', label: i18n.global.t('entities.geographicLocation'), value: '' }
|
|
||||||
// { name: 'dnsPtr', label: 'DNS PTR', value: '' }
|
|
||||||
)
|
|
||||||
|
|
||||||
relationList.value = _.concat(relationList.value,
|
|
||||||
{ icon: 'cn-icon cn-icon-subdomain', name: 'resolveIp', label: i18n.global.t('entity.graph.resolveDomain'), value: [], total: 12 },
|
|
||||||
{ icon: 'cn-icon cn-icon-app-name', name: 'relatedApp', label: i18n.global.t('entities.tab.relatedApp'), value: [], total: 6 }
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'domain': {
|
|
||||||
detailCards.value = _.concat(detailCards.value,
|
|
||||||
{ name: 'categoryName', label: i18n.global.t('entities.category'), value: '' },
|
|
||||||
{ name: 'categoryGroup', label: i18n.global.t('entities.domainDetail.subcategory'), value: '' },
|
|
||||||
{ name: 'reputationLevel', label: i18n.global.t('entities.creditLevel2'), value: '' },
|
|
||||||
{ name: 'expireDate', label: i18n.global.t('entities.graph.expirationDate'), value: '' },
|
|
||||||
{ name: 'registrarName', label: i18n.global.t('entities.registrar'), value: '' },
|
|
||||||
{ name: 'registrantOrg', label: i18n.global.t('entities.registry'), value: '' },
|
|
||||||
{ name: 'registrantCountry', label: i18n.global.t('entities.registrationCountry'), value: '' },
|
|
||||||
{ name: 'createDate', label: i18n.global.t('entities.registrationDate'), value: '' },
|
|
||||||
{ name: 'email', label: i18n.global.t('entities.registryEmail'), value: '' }
|
|
||||||
)
|
|
||||||
|
|
||||||
relationList.value = _.concat(relationList.value,
|
|
||||||
{ icon: 'cn-icon cn-icon-resolve-ip', name: 'resolveIp', label: i18n.global.t('entities.graph.resolveIp'), value: [], total: 12 },
|
|
||||||
{ icon: 'cn-icon cn-icon-subdomain', name: 'subdomain', label: i18n.global.t('entities.subdomain'), value: [1, 2], total: 2 },
|
|
||||||
{ icon: 'cn-icon cn-icon-app-name', name: 'relatedApp', label: i18n.global.t('entities.tab.relatedApp'), value: [], total: 6 }
|
|
||||||
)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'app': {
|
|
||||||
detailCards.value = _.concat(detailCards.value,
|
|
||||||
{ name: 'appCategory', label: i18n.global.t('entities.category'), value: '' },
|
|
||||||
{ name: 'appSubcategory', label: i18n.global.t('entities.subcategory'), value: '' },
|
|
||||||
{ name: 'appRisk', label: i18n.global.t('entities.riskLevel'), value: '' },
|
|
||||||
{ name: 'appTechnology', label: i18n.global.t('overall.technology'), value: '' },
|
|
||||||
{ name: 'appName', label: i18n.global.t('overall.appName2'), value: '' },
|
|
||||||
{ name: 'appLongname', label: i18n.global.t('overall.appFullName'), value: '' },
|
|
||||||
{ name: 'appDescription', label: i18n.global.t('config.dataSource.description'), value: '' }
|
|
||||||
)
|
|
||||||
|
|
||||||
relationList.value = _.concat(relationList.value,
|
|
||||||
{ icon: 'cn-icon cn-icon-resolve-ip', name: 'resolveIp', label: i18n.global.t('entities.graph.resolveIp'), value: [], total: 12 },
|
|
||||||
{ icon: 'cn-icon cn-icon-subdomain', name: 'resolveDomain', label: i18n.global.t('entity.graph.resolveDomain'), value: [], total: 12 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
detailCards,
|
detailCards,
|
||||||
@@ -244,62 +415,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initData () {
|
|
||||||
axios.get(`${api.entity.basicInfo}/${this.entity.entityType}?resource=${this.entity.entityName}`).then(response => {
|
|
||||||
const res = response.data
|
|
||||||
if (res.code === 200) {
|
|
||||||
switch (this.entity.entityType) {
|
|
||||||
case 'ip': {
|
|
||||||
if (res.data.asn) {
|
|
||||||
this.detailCards.find(c => c.name === 'asn').value = res.data.asn.asn
|
|
||||||
this.detailCards.find(c => c.name === 'asOrg').value = res.data.asn.organization
|
|
||||||
// AS子网接口未返回
|
|
||||||
}
|
|
||||||
if (res.data.location) {
|
|
||||||
this.detailCards.find(c => c.name === 'isp').value = res.data.location.isp
|
|
||||||
this.detailCards.find(c => c.name === 'location').value = this.handleLocation(res.data.location)
|
|
||||||
// DNS PTR接口未返回
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'domain': {
|
|
||||||
if (res.data.category) {
|
|
||||||
this.detailCards.find(c => c.name === 'categoryName').value = res.data.category.categoryName
|
|
||||||
this.detailCards.find(c => c.name === 'categoryGroup').value = res.data.category.categoryGroup
|
|
||||||
this.detailCards.find(c => c.name === 'reputationLevel').value = res.data.category.reputationLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.data.whois) {
|
|
||||||
this.detailCards.find(c => c.name === 'expireDate').value = dateFormatByAppearance(res.data.whois.expireDate)
|
|
||||||
this.detailCards.find(c => c.name === 'registrarName').value = res.data.whois.registrarName
|
|
||||||
this.detailCards.find(c => c.name === 'registrantOrg').value = res.data.whois.registrantOrg
|
|
||||||
this.detailCards.find(c => c.name === 'registrantCountry').value = res.data.whois.registrantCountry
|
|
||||||
this.detailCards.find(c => c.name === 'createDate').value = dateFormatByAppearance(res.data.whois.createDate)
|
|
||||||
this.detailCards.find(c => c.name === 'email').value = res.data.whois.email
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'app': {
|
|
||||||
if (res.data.category) {
|
|
||||||
this.detailCards.find(c => c.name === 'appCategory').value = res.data.category.appCategory
|
|
||||||
this.detailCards.find(c => c.name === 'appSubcategory').value = res.data.category.appSubcategory
|
|
||||||
this.detailCards.find(c => c.name === 'appRisk').value = this.appRisk(res.data.category.appRisk)
|
|
||||||
this.detailCards.find(c => c.name === 'appTechnology').value = res.data.category.appTechnology
|
|
||||||
this.detailCards.find(c => c.name === 'appName').value = res.data.category.appName
|
|
||||||
this.detailCards.find(c => c.name === 'appLongname').value = res.data.category.appLongname
|
|
||||||
this.detailCards.find(c => c.name === 'appDescription').value = res.data.category.appDescription
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
this.httpError(e)
|
|
||||||
}).finally(() => {
|
|
||||||
this.toggleLoading(false)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
/** 复制实体名称 */
|
/** 复制实体名称 */
|
||||||
copyEntityName () {
|
copyEntityName () {
|
||||||
selectElementText(document.getElementById('entityName'))
|
selectElementText(document.getElementById('entityName'))
|
||||||
@@ -312,7 +427,11 @@ export default {
|
|||||||
/** 修改关系拓展图标颜色,全部拓展浅灰色,否则深灰色 */
|
/** 修改关系拓展图标颜色,全部拓展浅灰色,否则深灰色 */
|
||||||
iconColor (length, total) {
|
iconColor (length, total) {
|
||||||
if (length < total) {
|
if (length < total) {
|
||||||
return 'rgba(57, 57, 57, 1)'
|
if (length === 50) {
|
||||||
|
return 'rgba(57, 57, 57, 0.5)'
|
||||||
|
} else {
|
||||||
|
return 'rgba(57, 57, 57, 1)'
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return 'rgba(57, 57, 57, 0.5)'
|
return 'rgba(57, 57, 57, 0.5)'
|
||||||
}
|
}
|
||||||
@@ -335,31 +454,32 @@ export default {
|
|||||||
}
|
}
|
||||||
return location.join(' - ')
|
return location.join(' - ')
|
||||||
},
|
},
|
||||||
appRisk (level) {
|
|
||||||
const m = riskLevelMapping.find(mapping => {
|
|
||||||
return mapping.value === level
|
|
||||||
})
|
|
||||||
return (m && m.name) || level
|
|
||||||
},
|
|
||||||
/** 关系拓展 */
|
/** 关系拓展 */
|
||||||
expandRelation (name) {
|
expandRelation (name) {
|
||||||
// todo 模拟效果,后续修改
|
this.$emit('expandDetailList', name === 'subDomain' ? 'domain' : name, this.entity.name)
|
||||||
const obj = this.relationList.find(item => item.name === name)
|
|
||||||
if (obj) {
|
|
||||||
const num = obj.total - obj.value.length
|
|
||||||
if (num > 0) {
|
|
||||||
const len = num < 10 ? num : 10
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
obj.value.push(i)
|
|
||||||
}
|
|
||||||
this.$emit('expand')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
httpError (e) {
|
httpError (e) {
|
||||||
this.isNoData = false
|
this.isNoData = false
|
||||||
this.showError = true
|
this.showError = true
|
||||||
this.errorMsg = this.errorMsgHandler(e)
|
this.errorMsg = this.errorMsgHandler(e)
|
||||||
|
},
|
||||||
|
location (detailData) {
|
||||||
|
let location = ''
|
||||||
|
if (detailData) {
|
||||||
|
const data = detailData.detail
|
||||||
|
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 || '-'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<loading :loading="entity.loading" size="small"></loading>
|
||||||
<div class="graph-list-header">
|
<div class="graph-list-header">
|
||||||
<div>
|
<div>
|
||||||
<div class="graph-list-header-title">
|
<div class="graph-list-header-title">
|
||||||
@@ -7,7 +8,7 @@
|
|||||||
<span>{{ $t('entities.graph.resolveIp') }}</span>
|
<span>{{ $t('entities.graph.resolveIp') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="graph-list-header-number">
|
<div class="graph-list-header-number">
|
||||||
{{ $t('entity.graph.associatedQuantity') }}:<span>12</span>
|
{{ $t('entity.graph.associatedQuantity') }}: <span>{{entity.count}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="graph-list-expand-btn-block">
|
<div class="graph-list-expand-btn-block">
|
||||||
<div class="graph-list-expand-btn" style="display: inline-flex;" @click="expandList">
|
<div class="graph-list-expand-btn" :class="{ 'graph-list-expand-btn--disabled': expandBtnDisable }" style="display: inline-flex;" @click="expandList">
|
||||||
<i class="cn-icon cn-icon-expand-continue graph-expand-continue"></i>
|
<i class="cn-icon cn-icon-expand-continue graph-expand-continue"></i>
|
||||||
{{ $t('entity.graph.continueToExpand') }}
|
{{ $t('entity.graph.continueToExpand') }}
|
||||||
</div>
|
</div>
|
||||||
@@ -27,29 +28,29 @@
|
|||||||
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
<div class="digital-certificate-header__icon graph-header__icon"></div>
|
||||||
<div class="graph-list-content-header ">
|
<div class="graph-list-content-header ">
|
||||||
{{ $t('entity.graph.expandedEntityQuantity') }}:
|
{{ $t('entity.graph.expandedEntityQuantity') }}:
|
||||||
<span>{{ ipList.length }}</span>
|
<span>{{ entity.listData ? entity.listData.length : 0 }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="graph-list-content">
|
<div class="graph-list-content">
|
||||||
<div v-for="(item, index) in ipList" :key="index" @mouseenter="onMouseenter(item)">
|
<div v-for="(item, index) in entity.listData" :key="index" @mouseenter="onMouseenter(item)">
|
||||||
<div class="graph-list-item-ip"><span @click="expandDetail">{{ item.ip }}</span></div>
|
<div class="graph-list-item-ip"><span @click="expandDetail">{{ item.vertex }}</span></div>
|
||||||
<div class="graph-list-item-block">
|
<div class="graph-list-item-block">
|
||||||
<div class="graph-list-item padding-b-4">
|
<div class="graph-list-item padding-b-4">
|
||||||
<div class="graph-list-item-label">{{ $t('overall.location') }}:</div>
|
<div class="graph-list-item-label">{{ $t('overall.location') }}:</div>
|
||||||
<div class="graph-list-item-value graph-list-item-value1" style="display: flex;align-items: center;">
|
<div class="graph-list-item-value graph-list-item-value1" style="display: flex;align-items: center;">
|
||||||
<img :src="require(`../../../../public/images/flag/${item.flag}.svg`)" class="graph-list-country-flag"/>
|
<!-- <img :src="require(`../../../../public/images/flag/${item.flag}.svg`)" class="graph-list-country-flag"/>-->
|
||||||
<span>{{ item.city }}</span>
|
<span>{{ $_.get(item.detail, 'location.city', '-') }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="graph-list-item">
|
<div class="graph-list-item">
|
||||||
<div class="graph-list-item-label">ASN:</div>
|
<div class="graph-list-item-label">ASN:</div>
|
||||||
<div class="graph-list-item-value">{{ item.asn }}</div>
|
<div class="graph-list-item-value">{{ $_.get(item.detail, 'asn.asn', '-') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="graph-list-dividing-line" v-if="index !== ipList.length - 1"></div>
|
<div class="graph-list-dividing-line" v-if="index !== entity.listData.length - 1"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -58,22 +59,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Loading from '@/components/common/Loading'
|
||||||
export default {
|
export default {
|
||||||
name: 'IpList',
|
name: 'IpList',
|
||||||
data () {
|
props: {
|
||||||
return {
|
entity: {
|
||||||
ipList: [
|
type: Object
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
}
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
},
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
components: {
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
Loading
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
},
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
computed: {
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
expandBtnDisable () {
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
return !((this.entity.listData ? this.entity.listData.length : 0) < this.entity.count && this.entity.count > 10 && (this.entity.listData && this.entity.listData.length < 50))
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' },
|
|
||||||
{ ip: '192.168.22.11', flag: '011-china', city: 'China, Beijing', asn: 'Sensitive' }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -89,12 +88,8 @@ export default {
|
|||||||
},
|
},
|
||||||
expandList () {
|
expandList () {
|
||||||
// 继续拓展ip列表,传递信息,调用接口
|
// 继续拓展ip列表,传递信息,调用接口
|
||||||
// this.$emit('expandList')
|
this.$emit('expandList', this.entity.sourceName, this.entity.nodeId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|||||||