CN-146 feat: ip基本信息开发

This commit is contained in:
chenjinsong
2021-09-18 17:48:52 +08:00
parent 047fc4a1a7
commit 3255674788
4 changed files with 188 additions and 15 deletions

View File

@@ -15,7 +15,7 @@
<slot name="title"></slot> <slot name="title"></slot>
</div> </div>
</div> </div>
<div class="single-value__content" v-if="type === 52"> <div class="single-value__content single-value__content--with-chart" v-if="type === 52">
<div class="content__title"> <div class="content__title">
<slot name="title"></slot> <slot name="title"></slot>
</div> </div>

View File

@@ -305,12 +305,53 @@ const relationShip = {
} }
] ]
} }
const sankeyShip = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: [
{
type: 'sankey',
data: [],
links: [],
levels: [
{
depth: 0,
itemStyle: {
color: '#47D49C'
},
lineStyle: {
color: '#999'
}
}, {
depth: 1,
itemStyle: {
color: '#A69BF5'
},
lineStyle: {
color: '#999'
}
}, {
depth: 2,
itemStyle: {
color: '#73A0FA'
},
lineStyle: {
color: '#999'
}
}
]
}
]
}
const typeOptionMappings = [ const typeOptionMappings = [
{ value: 11, option: line }, // 常规折线图 { value: 11, option: line }, // 常规折线图
{ value: 12, option: lineWithStatistics }, // 带统计表格的折线图 { value: 12, option: lineWithStatistics }, // 带统计表格的折线图
{ value: 13, option: lineStack }, // 折线堆叠图 { value: 13, option: lineStack }, // 折线堆叠图
{ value: 31, option: pieWithTable }, // 常规折线图 { value: 31, option: pieWithTable }, // 常规折线图
{ value: 42, option: relationShip }, // 关系图 { value: 42, option: relationShip }, // 关系图
{ value: 43, option: sankeyShip }, // 桑基图
{ value: 52, option: singleValueLine } { value: 52, option: singleValueLine }
] ]
const typeCategory = { const typeCategory = {
@@ -360,6 +401,10 @@ export function isEchartsWithStatistics (type) {
export function isRelationShip (type) { export function isRelationShip (type) {
return type === 42 return type === 42
} }
/* 桑基图 */
export function isSankey (type) {
return type === 43
}
/* 单值 */ /* 单值 */
export function isSingleValue (type) { export function isSingleValue (type) {
return type >= 51 && type <= 60 return type >= 51 && type <= 60

View File

@@ -143,6 +143,22 @@
} }
.cn-chart__body { .cn-chart__body {
flex: auto; flex: auto;
display: flex;
.el-descriptions {
padding-top: 30px;
}
&>.el-descriptions {
flex: 0 0 350px;
padding: 30px 36px;
}
.chart-location {
display: flex;
flex: 1;
flex-direction: column;
}
.el-descriptions__content {
color: #3976CB;
}
} }
} }
&>.cn-chart__group { &>.cn-chart__group {
@@ -153,6 +169,7 @@
padding: 0 20px; padding: 0 20px;
.cn-chart { .cn-chart {
border: none; border: none;
box-shadow: none;
} }
} }
} }
@@ -202,6 +219,11 @@
font-size: 16px; font-size: 16px;
color: #666666; color: #666666;
} }
&.single-value__content--with-chart {
.content__title {
border-bottom: 1px solid $--content-right-background-color;
}
}
.single-value__unit { .single-value__unit {
font-weight: normal; font-weight: normal;
padding-left: 10px; padding-left: 10px;
@@ -626,6 +648,13 @@
font-size: 16px; font-size: 16px;
} }
} }
.cn-chart__header {
border-bottom: none;
.header__title {
color: #3976CB;
font-size: 14px;
}
}
} }
} }
} }
@@ -654,6 +683,11 @@
margin-left: 12px; margin-left: 12px;
cursor: pointer; cursor: pointer;
} }
.ip-detail-as {
color: #999;
font-size: 12px;
padding-left: 10px;
}
//.cn-chart-select{ //.cn-chart-select{
// display: flex; // display: flex;
// align-items: center; // align-items: center;

View File

@@ -47,7 +47,21 @@
<span class="header__operation-btn" @click="refresh"><i class="cn-icon cn-icon-refresh"></i></span> <span class="header__operation-btn" @click="refresh"><i class="cn-icon cn-icon-refresh"></i></span>
</template> </template>
<template #default> <template #default>
<template v-if="isIpBasicInfo">
<el-descriptions :column="1">
<el-descriptions-item label="ASN:">{{detailData.asn}}</el-descriptions-item>
<el-descriptions-item :label="$t('entities.asSubnet') + ':'">{{detailData.asSubnet}}</el-descriptions-item>
<el-descriptions-item label="ISP:">{{detailData.isp}}</el-descriptions-item>
<el-descriptions-item label="DNS PTR:">{{detailData.dnsPTR}}</el-descriptions-item>
</el-descriptions>
<div class="chart-location">
<el-descriptions :column="1">
<el-descriptions-item :label="$t('overall.location') + ':'">{{location}}</el-descriptions-item>
</el-descriptions>
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div> <div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</div>
</template>
<div v-else class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</template> </template>
</chart-map> </chart-map>
<!-- echarts类的图如饼图柱状图折线图等 --> <!-- echarts类的图如饼图柱状图折线图等 -->
@@ -117,7 +131,15 @@
> >
</chart-error> </chart-error>
</template> </template>
<template #title><span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span></template> <template #title>
<span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span>
<span
v-if="chartInfo.params && chartInfo.params.as"
class="ip-detail-as"
>
as&nbsp;<span style="text-transform: capitalize">{{chartInfo.params.as}}</span>
</span>
</template>
<template #data> <template #data>
<span>{{handleSingleValue[0] || handleSingleValue[0] === 0 ? handleSingleValue[0] : '-'}}</span> <span>{{handleSingleValue[0] || handleSingleValue[0] === 0 ? handleSingleValue[0] : '-'}}</span>
<span class="single-value__unit">{{handleSingleValue[1]}}</span> <span class="single-value__unit">{{handleSingleValue[1]}}</span>
@@ -201,14 +223,28 @@
:style="computePosition" :style="computePosition"
> >
<div class="cn-chart__header"> <div class="cn-chart__header">
<div class="header__title">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div> <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>
<span
v-if="chartInfo.params && chartInfo.params.as"
class="ip-detail-as"
>
as&nbsp;<span style="text-transform: capitalize">{{chartInfo.params.as}}</span>
</span>
</div>
</div> </div>
<div class="cn-chart__body"> <div class="cn-chart__body">
<template v-for="chart in chartInfo.children" :key="chart.id"> <template v-for="chart in chartInfo.children" :key="chart.id">
<chart :chart="chart" :time-filter="timeFilter" :ref="`chart-${chart.id}`" :entity="entity"></chart> <chart :chart="chart" :time-filter="timeFilter" :ref="`chart-${chart.id}`" :entity="entity" :parent-data="groupData"></chart>
</template> </template>
</div> </div>
</div> </div>
<!-- IP详情-基本信息 -->
</template> </template>
<script> <script>
@@ -235,6 +271,10 @@ import {
isRelationShip, isRelationShip,
isTabs, isTabs,
isGroup, isGroup,
isSankey,
isIpBasicInfo,
isIpOpenPort,
isIpHostedDomain,
getChartColor getChartColor
} from '@/components/charts/chart-options' } from '@/components/charts/chart-options'
import ChartError from '@/components/charts/ChartError' import ChartError from '@/components/charts/ChartError'
@@ -256,6 +296,7 @@ export default {
props: { props: {
chart: Object, // 图表对象包括id、name、type等数据 chart: Object, // 图表对象包括id、name、type等数据
timeFilter: Object, timeFilter: Object,
parentData: Object,
entity: { entity: {
type: Object, type: Object,
default: () => {} default: () => {}
@@ -287,6 +328,8 @@ export default {
icon: '' icon: ''
}, },
activeTab: '', activeTab: '',
groupData: '', // group类型的查询数据用于传递给子chart子chart通过params.dataKey取值
detailData: {}, // 详情类型图表的数据
statisticsData: [], statisticsData: [],
orderPieTable: chartPieTableTopOptions[0].value, orderPieTable: chartPieTableTopOptions[0].value,
selectPieChartName: '', selectPieChartName: '',
@@ -324,8 +367,8 @@ export default {
this.initEchartsWithStatistics(chartParams) this.initEchartsWithStatistics(chartParams)
} else if (this.isRelationShip) { } else if (this.isRelationShip) {
this.initRelationShip(chartParams) this.initRelationShip(chartParams)
} else if (this.isGroup) { } else if (this.isSankey) {
this.initSankey(chartParams)
} else { } else {
this.initECharts(chartParams) this.initECharts(chartParams)
} }
@@ -337,6 +380,15 @@ export default {
} else if (this.isSingleValue) { } else if (this.isSingleValue) {
if (chartParams) { if (chartParams) {
this.singleValue.icon = chartParams.icon this.singleValue.icon = chartParams.icon
const gotData = new Promise(resolve => {
if (chartParams.dataKey) {
if (this.parentData && this.parentData[chartParams.dataKey]) {
this.singleValue.value = this.parentData[chartParams.dataKey]
} else {
this.noData = true
}
resolve()
} else {
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), ...this.entity } const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), ...this.entity }
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => { get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) { if (response.code === 200) {
@@ -346,7 +398,13 @@ export default {
this.noData = true this.noData = true
this.errorInfo = response.msg || response.message || 'Unknown' this.errorInfo = response.msg || response.message || 'Unknown'
} }
resolve()
})
}
})
gotData.then(() => {
if (this.isSingleValueWithEcharts) { // 带曲线的单值图 if (this.isSingleValueWithEcharts) { // 带曲线的单值图
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), ...this.entity }
const dom = document.getElementById(`chart${this.chartInfo.id}`) const dom = document.getElementById(`chart${this.chartInfo.id}`)
!this.myChart && (this.myChart = echarts.init(dom)) !this.myChart && (this.myChart = echarts.init(dom))
this.chartOption = this.$_.cloneDeep(getOption(this.chart.type)) this.chartOption = this.$_.cloneDeep(getOption(this.chart.type))
@@ -389,6 +447,20 @@ export default {
if (!this.$_.isEmpty(this.chartInfo.children)) { if (!this.$_.isEmpty(this.chartInfo.children)) {
this.activeTab = `${this.chartInfo.children[0].id}` this.activeTab = `${this.chartInfo.children[0].id}`
} }
} else if (this.isGroup) {
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), ...this.entity }
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) {
this.groupData = 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) { } catch (e) {
console.error(e) console.error(e)
@@ -607,6 +679,9 @@ export default {
polygonTemplate.tooltipText = '{name}{title}' polygonTemplate.tooltipText = '{name}{title}'
polygonTemplate.nonScalingStroke = true polygonTemplate.nonScalingStroke = true
polygonTemplate.strokeWidth = 0.5 polygonTemplate.strokeWidth = 0.5
} else if (this.isIpBasicInfo) {
this.detailData = data
console.info(1)
} }
} else if (response.code !== 200) { } else if (response.code !== 200) {
this.isError = true this.isError = true
@@ -806,6 +881,9 @@ export default {
} }
return style return style
} }
},
initSankey (chartParams) {
}, },
initEchartsWithStatistics (chartParams) { initEchartsWithStatistics (chartParams) {
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), ...this.entity } const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), ...this.entity }
@@ -1010,6 +1088,19 @@ export default {
gridRow gridRow
} }
}, },
location () {
let location = ''
if (this.detailData.country) {
location = this.detailData.country
if (this.detailData.region) {
location += ', '
location += this.detailData.region
}
} else if (this.detailData.region) {
location = this.detailData.region
}
return location
},
handleSingleValue () { handleSingleValue () {
const value = this.singleValue.value const value = this.singleValue.value
const unitType = this.chartInfo.params.unitType const unitType = this.chartInfo.params.unitType
@@ -1057,7 +1148,6 @@ export default {
}, },
setup (props) { setup (props) {
const chartInfo = JSON.parse(JSON.stringify(props.chart)) const chartInfo = JSON.parse(JSON.stringify(props.chart))
console.info(chartInfo)
chartInfo.category = getTypeCategory(props.chart.type) chartInfo.category = getTypeCategory(props.chart.type)
return { return {
chartInfo, chartInfo,
@@ -1077,6 +1167,10 @@ export default {
isMapBlock: isMapBlock(props.chart.type), isMapBlock: isMapBlock(props.chart.type),
isTabs: isTabs(props.chart.type), isTabs: isTabs(props.chart.type),
isGroup: isGroup(props.chart.type), isGroup: isGroup(props.chart.type),
isSankey: isSankey(props.chart.type),
isIpBasicInfo: isIpBasicInfo(props.chart.type),
isIpHostedDomain: isIpHostedDomain(props.chart.type),
isIpOpenPort: isIpOpenPort(props.chart.type),
layout: getLayout(props.chart.type), layout: getLayout(props.chart.type),
myChart: shallowRef(null) myChart: shallowRef(null)
} }