CN-148 feat: app详情开发
This commit is contained in:
@@ -467,6 +467,22 @@ export function isIpOpenPort (type) {
|
||||
export function isIpHostedDomain (type) {
|
||||
return type === 33
|
||||
}
|
||||
/* APP实体托管域名 */
|
||||
export function isAppRelatedDomain (type) {
|
||||
return type === 34
|
||||
}
|
||||
/* APP实体基本信息 */
|
||||
export function isAppBasicInfo (type) {
|
||||
return type === 82
|
||||
}
|
||||
/* DOMAIN实体Whois */
|
||||
export function isDomainWhois (type) {
|
||||
return type === 83
|
||||
}
|
||||
/* DOMAIN实体DNS记录 */
|
||||
export function isDomainDnsRecord (type) {
|
||||
return type === 84
|
||||
}
|
||||
/* 组 */
|
||||
export function isGroup (type) {
|
||||
return type === 94
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&>.cn-chart__echarts, &>.cn-chart__table, &>.cn-chart__map, &>.cn-chart__group {
|
||||
&>.cn-chart__echarts, &>.cn-chart__table, &>.cn-chart__map, &>.cn-chart__group, &>.cn-chart__whois, &>.cn-chart__dns-record, &>.cn-chart__app-basic {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.cn-chart__header {
|
||||
@@ -165,7 +165,8 @@
|
||||
.cn-chart__header {
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
}
|
||||
.cn-chart__body {
|
||||
&>.cn-chart__body {
|
||||
display: grid !important;
|
||||
padding: 0 20px;
|
||||
.cn-chart {
|
||||
border: none;
|
||||
@@ -173,143 +174,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
&>.cn-chart__single-value.cn-chart__single-value--icon-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.single-value-icon__box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 40%;
|
||||
}
|
||||
|
||||
.single-value__icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28px;
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 60%;
|
||||
padding-right: 10px;
|
||||
|
||||
.content__data {
|
||||
padding-bottom: 7%;
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.content__title {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
&.single-value__content--with-chart {
|
||||
.content__title {
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
}
|
||||
}
|
||||
.single-value__unit {
|
||||
font-weight: normal;
|
||||
padding-left: 10px;
|
||||
color: #666;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&>.cn-chart__single-value.cn-chart__single-value--icon-right {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
|
||||
.single-value__icon {
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
margin-right: 7.5%;
|
||||
margin-bottom: 6%;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
font-size: 24px;
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
.content__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 50%;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
.content__data {
|
||||
display: flex;
|
||||
padding-top: 5%;
|
||||
height: 50%;
|
||||
flex: auto;
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
&>.cn-chart__single-value.cn-chart__single-value--chart {
|
||||
display: flex;
|
||||
padding: 13px 20px;
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
.content__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30%;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
.content__data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 25%;
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.content__chart {
|
||||
flex: auto
|
||||
}
|
||||
}
|
||||
}
|
||||
&>.cn-chart__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -581,6 +445,10 @@
|
||||
}
|
||||
}
|
||||
.title__name {
|
||||
text-overflow: ellipsis;
|
||||
max-width: 400px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
padding-left: 10px;
|
||||
color: #333;
|
||||
}
|
||||
@@ -697,3 +565,140 @@
|
||||
// border: 1px solid #0091ff;
|
||||
// border-radius: 2px;
|
||||
//}
|
||||
.cn-chart__single-value.cn-chart__single-value--icon-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.single-value-icon__box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 40%;
|
||||
}
|
||||
|
||||
.single-value__icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28px;
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 60%;
|
||||
padding-right: 10px;
|
||||
|
||||
.content__data {
|
||||
padding-bottom: 7%;
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.content__title {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
&.single-value__content--with-chart {
|
||||
.content__title {
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
}
|
||||
}
|
||||
.single-value__unit {
|
||||
font-weight: normal;
|
||||
padding-left: 10px;
|
||||
color: #666;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cn-chart__single-value.cn-chart__single-value--icon-right {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
|
||||
.single-value__icon {
|
||||
background-color: $--chart-single-value-icon-background-color;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
margin-right: 7.5%;
|
||||
margin-bottom: 6%;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
font-size: 24px;
|
||||
color: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
.content__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 50%;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
.content__data {
|
||||
display: flex;
|
||||
padding-top: 5%;
|
||||
height: 50%;
|
||||
flex: auto;
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cn-chart__single-value.cn-chart__single-value--chart {
|
||||
display: flex;
|
||||
padding: 13px 20px;
|
||||
|
||||
.single-value__content {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
.content__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30%;
|
||||
font-size: 16px;
|
||||
color: #666666;
|
||||
}
|
||||
.content__data {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 25%;
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
font-weight: bold;
|
||||
}
|
||||
.content__chart {
|
||||
flex: auto
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,7 @@
|
||||
</div>
|
||||
<div class="hosted-domain__chart">
|
||||
<div>
|
||||
<div class="hosted-domain__chart-title">{{$t('entities.byType')}}</div>
|
||||
<div class="hosted-domain__chart-title">{{$t('entities.byCategory')}}</div>
|
||||
<div class="chart-drawing" :id="`chart${chartInfo.id}-0`"></div>
|
||||
</div>
|
||||
<div>
|
||||
@@ -289,7 +289,185 @@
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<!-- IP详情-基本信息 -->
|
||||
<!-- Domain详情-whois -->
|
||||
<div
|
||||
v-else-if="isDomainWhois"
|
||||
class="cn-chart cn-chart__whois"
|
||||
:style="computePosition"
|
||||
>
|
||||
<div class="cn-chart__header">
|
||||
<chart-error
|
||||
:isError="isError"
|
||||
:errorInfo="errorInfo"
|
||||
>
|
||||
</chart-error>
|
||||
<div class="header__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cn-chart__body">
|
||||
<div class="domain-detail-list">
|
||||
<div class="domain-detail-list__row">
|
||||
<div class="domain-detail-list__label">{{$t('entities.sponsor')}}</div>
|
||||
<div class="domain-detail-list__content">{{detailData.sponsor || '-'}}</div>
|
||||
</div>
|
||||
<div class="domain-detail-list__row">
|
||||
<div class="domain-detail-list__label">{{$t('entities.org')}}</div>
|
||||
<div class="domain-detail-list__content">{{detailData.org || '-'}}</div>
|
||||
</div>
|
||||
<div class="domain-detail-list__row">
|
||||
<div class="domain-detail-list__label">Email</div>
|
||||
<div class="domain-detail-list__content">{{detailData.email || '-'}}</div>
|
||||
</div>
|
||||
<div class="domain-detail-list__row">
|
||||
<div class="domain-detail-list__label">{{$t('overall.country')}}</div>
|
||||
<div class="domain-detail-list__content">{{detailData.orgCountry || '-'}}</div>
|
||||
</div>
|
||||
<div class="domain-detail-list__row">
|
||||
<div class="domain-detail-list__label">{{$t('entities.creationDate')}}</div>
|
||||
<div class="domain-detail-list__content">{{detailData.creationDate || '-'}}</div>
|
||||
</div>
|
||||
<div class="domain-detail-list__row">
|
||||
<div class="domain-detail-list__label">{{$t('entities.expirationDate')}}</div>
|
||||
<div class="domain-detail-list__content">{{detailData.expirationDate || '-'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Domain详情-DNS记录 -->
|
||||
<div
|
||||
v-else-if="isDomainDnsRecord"
|
||||
class="cn-chart cn-chart__dns-record"
|
||||
:style="computePosition"
|
||||
>
|
||||
<div class="cn-chart__header">
|
||||
<chart-error
|
||||
:isError="isError"
|
||||
:errorInfo="errorInfo"
|
||||
>
|
||||
</chart-error>
|
||||
<div class="header__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cn-chart__body">
|
||||
<div class="entity-detail__dns-record">
|
||||
<div class="dns-record__table">
|
||||
<div style="height: 100%; overflow: hidden auto;">
|
||||
<div class="dns-record__table-row dns-record__table-row--header">
|
||||
<div class="dns-record__table-cell" style="min-width: 200px;">Type</div>
|
||||
<div class="dns-record__table-cell" style="width: 100%;">Value</div>
|
||||
</div>
|
||||
<div class="dns-record__table-row" v-for="(data, index) in detailData" :key="index">
|
||||
<div class="dns-record__table-cell">{{data.type || '-'}}</div>
|
||||
<div class="dns-record__table-cell">{{data.value || '-'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- APP详情-基本信息 -->
|
||||
<div
|
||||
v-else-if="isAppBasicInfo"
|
||||
class="cn-chart cn-chart__app-basic"
|
||||
:style="computePosition"
|
||||
>
|
||||
<div class="cn-chart__header">
|
||||
<chart-error
|
||||
:isError="isError"
|
||||
:errorInfo="errorInfo"
|
||||
>
|
||||
</chart-error>
|
||||
<div class="header__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cn-chart__body">
|
||||
<div style="display: flex; justify-content: space-between; width: 100%;">
|
||||
<el-descriptions :column="1" style="padding: 20px 30px;">
|
||||
<el-descriptions-item :label="$t('overall.appName')">{{detailData ? detailData.name : '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.appFullName') + ':'">{{detailData.fullName || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.technology')">{{detailData.technology || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('overall.remark')">{{detailData.remark || '-'}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="display: flex;">
|
||||
<single-value
|
||||
:type="51"
|
||||
icon="cn-icon cn-icon-category"
|
||||
:loading="false"
|
||||
style="width: 250px;"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{$t('entities.category')}}</span>
|
||||
</template>
|
||||
<template #data>
|
||||
<span>test</span>
|
||||
</template>
|
||||
</single-value>
|
||||
<single-value
|
||||
:type="51"
|
||||
icon="cn-icon cn-icon-sub-category"
|
||||
:loading="false"
|
||||
style="width: 250px;"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{$t('entities.subcategory')}}</span>
|
||||
</template>
|
||||
<template #data>
|
||||
<span>test2</span>
|
||||
</template>
|
||||
</single-value>
|
||||
<single-value
|
||||
:type="51"
|
||||
icon="cn-icon cn-icon-credit"
|
||||
:loading="false"
|
||||
style="width: 250px;"
|
||||
>
|
||||
<template #title>
|
||||
<span>{{$t('entities.reputationLevel')}}</span>
|
||||
</template>
|
||||
<template #data>
|
||||
<span>test3</span>
|
||||
</template>
|
||||
</single-value>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- APP详情-相关域名 -->
|
||||
<div
|
||||
v-else-if="isAppRelatedDomain"
|
||||
class="cn-chart cn-chart__dns-record"
|
||||
:style="computePosition"
|
||||
>
|
||||
<div class="cn-chart__header">
|
||||
<chart-error
|
||||
:isError="isError"
|
||||
:errorInfo="errorInfo"
|
||||
>
|
||||
</chart-error>
|
||||
<div class="header__title">
|
||||
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cn-chart__body">
|
||||
<div class="entity-detail__dns-record">
|
||||
<div class="dns-record__table">
|
||||
<div style="height: 100%; overflow: hidden auto;">
|
||||
<div class="dns-record__table-row dns-record__table-row--header">
|
||||
<div class="dns-record__table-cell" style="min-width: 200px;">Type</div>
|
||||
<div class="dns-record__table-cell" style="width: 100%;">Value</div>
|
||||
</div>
|
||||
<div class="dns-record__table-row" v-for="(data, index) in detailData" :key="index">
|
||||
<div class="dns-record__table-cell">{{data.type || '-'}}</div>
|
||||
<div class="dns-record__table-cell">{{data.value || '-'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -320,6 +498,10 @@ import {
|
||||
isIpBasicInfo,
|
||||
isIpOpenPort,
|
||||
isIpHostedDomain,
|
||||
isDomainWhois,
|
||||
isDomainDnsRecord,
|
||||
isAppBasicInfo,
|
||||
isAppRelatedDomain,
|
||||
getChartColor
|
||||
} from '@/components/charts/chart-options'
|
||||
import ChartError from '@/components/charts/ChartError'
|
||||
@@ -514,6 +696,20 @@ export default {
|
||||
this.isError = true
|
||||
this.errorInfo = e
|
||||
})
|
||||
} else if (this.isDomainWhois || this.isDomainDnsRecord) {
|
||||
const queryParams = { domain: this.entity.domain }
|
||||
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.detailData = response.data.result
|
||||
} else {
|
||||
this.isError = true
|
||||
this.noData = true
|
||||
this.errorInfo = response.msg || response.message || 'Unknown'
|
||||
}
|
||||
}).catch(e => {
|
||||
this.isError = true
|
||||
this.errorInfo = e
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
@@ -1331,6 +1527,10 @@ export default {
|
||||
isIpBasicInfo: isIpBasicInfo(props.chart.type),
|
||||
isIpHostedDomain: isIpHostedDomain(props.chart.type),
|
||||
isIpOpenPort: isIpOpenPort(props.chart.type),
|
||||
isDomainWhois: isDomainWhois(props.chart.type),
|
||||
isDomainDnsRecord: isDomainDnsRecord(props.chart.type),
|
||||
isAppBasicInfo: isAppBasicInfo(props.chart.type),
|
||||
isAppRelatedDomain: isAppRelatedDomain(props.chart.type),
|
||||
layout: getLayout(props.chart.type),
|
||||
myChart: shallowRef(null)
|
||||
}
|
||||
@@ -1364,7 +1564,7 @@ export default {
|
||||
}
|
||||
.open-port__table-cell {
|
||||
display: table-cell;
|
||||
vertical-align: 30px;
|
||||
vertical-align: middle;
|
||||
padding: 13px 30px;
|
||||
}
|
||||
}
|
||||
@@ -1435,4 +1635,57 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
.domain-detail-list {
|
||||
display: table;
|
||||
width: 100%;
|
||||
|
||||
.domain-detail-list__row {
|
||||
display: table-row;
|
||||
|
||||
.domain-detail-list__label {
|
||||
display: table-cell;
|
||||
padding: 15px 30px;
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
width: 170px;
|
||||
color: #6B717B;
|
||||
}
|
||||
.domain-detail-list__content {
|
||||
display: table-cell;
|
||||
padding: 15px 0 ;
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
color: #3976CB;
|
||||
}
|
||||
}
|
||||
}
|
||||
.entity-detail__dns-record {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.dns-record__table {
|
||||
display: table;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
.dns-record__table-row {
|
||||
display: table-row;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
.dns-record__table-row.dns-record__table-row--header {
|
||||
padding: 13px 30px 0;
|
||||
height: 40px;
|
||||
color: #6B717B;
|
||||
}
|
||||
.dns-record__table-cell {
|
||||
display: table-cell;
|
||||
border-bottom: 1px solid $--content-right-background-color;
|
||||
vertical-align: middle;
|
||||
padding: 13px 30px;
|
||||
}
|
||||
.dns-record__table-row:not(.dns-record__table-row--header) .dns-record__table-cell:last-of-type {
|
||||
color: #3976CB;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
<div class="entity-detail__header">
|
||||
<div class="detail-header__title">
|
||||
<span class="title__icon-circle">
|
||||
<i class="cn-icon cn-icon-ip"></i>
|
||||
<i class="cn-icon" :class="{'cn-icon-ip': entity.ip, 'cn-icon-domain': entity.domain, 'cn-icon-app': entity.appId}"></i>
|
||||
</span>
|
||||
<span class="title__name">{{entity.name}}</span></div>
|
||||
<div class="title__name" :title="entity.ip || entity.domain || entity.appId || '-'">{{entity.ip || entity.domain || entity.appId || '-'}}</div></div>
|
||||
<div class="detail-header__operation">
|
||||
<div class="panel__time">
|
||||
<DateTimeRange class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" ref="dateTimeRange" @change="reload"/>
|
||||
|
||||
Reference in New Issue
Block a user