summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchenjinsong <[email protected]>2021-09-22 23:05:18 +0800
committerchenjinsong <[email protected]>2021-09-22 23:05:18 +0800
commit56d32ce8ca40f0b3e005312c3c67767aa8a86431 (patch)
treeee6b0bae50ae90aa83bf26db62ccdee5568e6d89
parentc55747fefca0e76e76715d88593eb8968b4c6639 (diff)
CN-148 feat: app详情开发
-rw-r--r--src/components/charts/chart-options.js16
-rw-r--r--src/components/charts/panel.scss283
-rw-r--r--src/views/charts/Chart.vue259
-rw-r--r--src/views/charts/Panel.vue4
4 files changed, 418 insertions, 144 deletions
diff --git a/src/components/charts/chart-options.js b/src/components/charts/chart-options.js
index de2f5f60..2cd48723 100644
--- a/src/components/charts/chart-options.js
+++ b/src/components/charts/chart-options.js
@@ -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
diff --git a/src/components/charts/panel.scss b/src/components/charts/panel.scss
index 54fae7bb..fca58565 100644
--- a/src/components/charts/panel.scss
+++ b/src/components/charts/panel.scss
@@ -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
+ }
+ }
+} \ No newline at end of file
diff --git a/src/views/charts/Chart.vue b/src/views/charts/Chart.vue
index 16e31a62..2b37b858 100644
--- a/src/views/charts/Chart.vue
+++ b/src/views/charts/Chart.vue
@@ -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>
diff --git a/src/views/charts/Panel.vue b/src/views/charts/Panel.vue
index 0c682d0c..f26c8261 100644
--- a/src/views/charts/Panel.vue
+++ b/src/views/charts/Panel.vue
@@ -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"/>