perf: entities部分内容、优化带统计图表样式
This commit is contained in:
@@ -13,16 +13,32 @@ $--menu-hover-background-color: #000C18; // menu背景色
|
|||||||
$--menu-item-font-color: #BEBEBE; // menu字色
|
$--menu-item-font-color: #BEBEBE; // menu字色
|
||||||
$--menu-item-hover-fill: $--color-primary; // menu鼠标悬浮、激活时背景色
|
$--menu-item-hover-fill: $--color-primary; // menu鼠标悬浮、激活时背景色
|
||||||
|
|
||||||
|
$--collapse-header-height: 42px;
|
||||||
|
$--collapse-border-color: #EFF2F5;
|
||||||
|
|
||||||
/** 自定义变量 **/
|
/** 自定义变量 **/
|
||||||
:root {
|
:root {
|
||||||
|
/* 自适应变量 */
|
||||||
|
@media only screen and (min-width : 10px) {
|
||||||
|
--chart-height-unit: 25px; // chart的单元高度
|
||||||
|
--entity-width: calc(50% - 5px); // entity列表每个entity框的宽度
|
||||||
|
--entity-height: 190px; // entity列表每个entity框的高度
|
||||||
|
}
|
||||||
@media only screen and (min-width : 1224px) {
|
@media only screen and (min-width : 1224px) {
|
||||||
--chart-height-unit: 30px;
|
--chart-height-unit: 30px;
|
||||||
}
|
}
|
||||||
|
@media only screen and (min-width : 1560px) {
|
||||||
|
--entity-width: calc(33.3% - 7px);
|
||||||
|
}
|
||||||
@media only screen and (min-width : 1824px) {
|
@media only screen and (min-width : 1824px) {
|
||||||
--chart-height-unit: 40px;
|
--chart-height-unit: 40px;
|
||||||
|
--entity-width: calc(33.3% - 7px);
|
||||||
|
--entity-height: 210px;
|
||||||
}
|
}
|
||||||
@media only screen and (min-width : 2424px) {
|
@media only screen and (min-width : 2424px) {
|
||||||
--chart-height-unit: 55px;
|
--chart-height-unit: 55px;
|
||||||
|
--entity-width: calc(25% - 8px);
|
||||||
|
--entity-height: 240px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +48,7 @@ $--border-radius-primary: 2px;
|
|||||||
$--right-box-border-color: #E7EAED;
|
$--right-box-border-color: #E7EAED;
|
||||||
|
|
||||||
/* 按钮 */
|
/* 按钮 */
|
||||||
$--button-border-radius: $--border-color-primary; // 按钮圆角
|
$--button-border-radius: $--border-radius-primary; // 按钮圆角
|
||||||
|
|
||||||
$--button-primary-color: #FFF; // 普通按钮字色
|
$--button-primary-color: #FFF; // 普通按钮字色
|
||||||
$--button-primary-background-color: $--color-primary; // 普通按钮背景色
|
$--button-primary-background-color: $--color-primary; // 普通按钮背景色
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="cn-chart cn-chart__echarts">
|
<div class="cn-chart cn-chart__echarts" :class="{'cn-chart__echarts--statistics': isEchartsWithStatistics}">
|
||||||
<div class="cn-chart__header" v-if="layout.indexOf(layoutConstant.HEADER) > -1">
|
<div class="cn-chart__header" v-if="layout.indexOf(layoutConstant.HEADER) > -1">
|
||||||
<div class="header__title">
|
<div class="header__title">
|
||||||
<slot name="title"></slot>
|
<slot name="title"></slot>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { layoutConstant, isEchartsWithTable } from '@/components/charts/chart-options'
|
import { layoutConstant, isEchartsWithTable, isEchartsWithStatistics } from '@/components/charts/chart-options'
|
||||||
export default {
|
export default {
|
||||||
name: 'EchartsFrame',
|
name: 'EchartsFrame',
|
||||||
props: {
|
props: {
|
||||||
@@ -28,7 +28,8 @@ export default {
|
|||||||
setup (props) {
|
setup (props) {
|
||||||
return {
|
return {
|
||||||
layoutConstant,
|
layoutConstant,
|
||||||
isPieWithTable: isEchartsWithTable(props.chartInfo.type)
|
isPieWithTable: isEchartsWithTable(props.chartInfo.type),
|
||||||
|
isEchartsWithStatistics: isEchartsWithStatistics(props.chartInfo.type)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
<div class="legend__table">
|
<div class="legend__table">
|
||||||
<table>
|
<table>
|
||||||
<tr v-for="(d, i) in data" :key="i" class="legend__row">
|
<tr v-for="(d, i) in data" :key="i" class="legend__row">
|
||||||
<td><div :style="{backgroundColor: getChartColor(i)}" class="legend__row-top" :title="getChartColor(i)"></div></td>
|
<td style="width: 40px;"><div :style="{backgroundColor: getChartColor(i)}" class="legend__row-top" :title="getChartColor(i)"></div></td>
|
||||||
<td><div class="text__show" :title="d.legend">{{d.legend}}</div></td>
|
<td><div class="text__show" :title="d.legend">{{d.legend}}</div></td>
|
||||||
<td><div :title="d.aggregation.avg" class="legend__row-left">{{d.aggregation.avg}}</div></td>
|
<td style="width: 70px;"><div :title="d.aggregation.avg">{{d.aggregation.avg}}</div></td>
|
||||||
<td><div :title="d.aggregation.max" class="legend__row-right">{{d.aggregation.max}}</div></td>
|
<td style="width: 70px;"><div :title="d.aggregation.max">{{d.aggregation.max}}</div></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -38,12 +38,13 @@ export default {
|
|||||||
setup () {
|
setup () {
|
||||||
return {
|
return {
|
||||||
getChartColor,
|
getChartColor,
|
||||||
chartColor }
|
chartColor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.chart__legend{
|
.chart__legend{
|
||||||
width: 455px;
|
width: 455px;
|
||||||
height: 111px;
|
height: 111px;
|
||||||
@@ -52,8 +53,8 @@ export default {
|
|||||||
color:#5f6368;
|
color:#5f6368;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
.text__show{
|
.text__show {
|
||||||
width: 50px;
|
max-width: 240px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow:ellipsis;
|
text-overflow:ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -66,21 +67,17 @@ export default {
|
|||||||
}
|
}
|
||||||
.location{
|
.location{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 138px;
|
right: 110px;
|
||||||
top: -9px;
|
top: -9px;
|
||||||
font-family: Roboto-Regular;
|
font-size: 13px;
|
||||||
font-size: 14px;
|
|
||||||
color: #0091FF;
|
color: #0091FF;
|
||||||
font-weight: 400;
|
|
||||||
}
|
}
|
||||||
.locations{
|
.locations{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 29px;
|
right: 25px;
|
||||||
top: -8px;
|
top: -8px;
|
||||||
font-family: Roboto-Regular;
|
font-size: 13px;
|
||||||
font-size: 14px;
|
|
||||||
color: #0091FF;
|
color: #0091FF;
|
||||||
font-weight: 400;
|
|
||||||
}
|
}
|
||||||
.legend__row-top{
|
.legend__row-top{
|
||||||
width: 17px;
|
width: 17px;
|
||||||
@@ -90,7 +87,11 @@ export default {
|
|||||||
}
|
}
|
||||||
.legend__table {
|
.legend__table {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
height: calc(100% - 30px)
|
height: calc(100% - 30px);
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.legend__row{
|
.legend__row{
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@@ -98,13 +99,7 @@ export default {
|
|||||||
}
|
}
|
||||||
.legend__row:hover {
|
.legend__row:hover {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
border: 0px;
|
border: 0;
|
||||||
color: #383838;
|
color: #383838;
|
||||||
}
|
}
|
||||||
.legend__row-right{
|
|
||||||
margin-left: 60px;
|
|
||||||
}
|
|
||||||
.legend__row-left{
|
|
||||||
margin-left: 178px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -25,6 +25,10 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
&>.cn-chart.cn-chart__echarts--statistics {
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
&>.cn-chart__echarts, &>.cn-chart__table, &>.cn-chart__map {
|
&>.cn-chart__echarts, &>.cn-chart__table, &>.cn-chart__map {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
83
src/components/entities/EntityList.vue
Normal file
83
src/components/entities/EntityList.vue
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<div class="entity-list">
|
||||||
|
<div class="entity-list__content">
|
||||||
|
<div class="cn-entity" v-for="d in listData" :key="d.id">
|
||||||
|
<div class="cn-entity__header">
|
||||||
|
<div class="header__icon" :style="{backgroundColor: circleColor}"><i :class="iconClass"></i></div>
|
||||||
|
<div class="header__content">
|
||||||
|
<div class="content__title">
|
||||||
|
<template v-if="entityType === 'ip'">{{d.ip || 'Unknown'}}</template>
|
||||||
|
<template v-else-if="entityType === 'domain'">{{d.domainName || 'Unknown'}}</template>
|
||||||
|
<template v-else-if="entityType === 'app'">{{d.appName || 'Unknown'}}</template>
|
||||||
|
</div>
|
||||||
|
<div class="content__desc" v-if="entityType !== 'ip'">
|
||||||
|
<template v-if="entityType === 'domain'">
|
||||||
|
<span class="desc__label">{{$t('entities.reputationLevel')}}:</span>
|
||||||
|
<span>{{d.reputationLevel || '-'}}</span>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="entityType === 'app'">
|
||||||
|
<span class="desc__label">{{$t('entities.risk')}}:</span>
|
||||||
|
<span>{{d.appRisk || '-'}}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="cn-entity__body"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="entity-list__pagination"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'EntityList',
|
||||||
|
props: {
|
||||||
|
listData: Array,
|
||||||
|
entityType: String
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
circleColor () {
|
||||||
|
let color
|
||||||
|
switch (this.entityType) {
|
||||||
|
case ('ip'): {
|
||||||
|
color = '#E8FBF9'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('domain'): {
|
||||||
|
color = '#EEF6FE'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('app'): {
|
||||||
|
color = '#FEF7E7'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
},
|
||||||
|
iconClass () {
|
||||||
|
let className
|
||||||
|
switch (this.entityType) {
|
||||||
|
case ('ip'): {
|
||||||
|
className = 'cn-icon cn-icon-ip ip-green'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('domain'): {
|
||||||
|
className = 'cn-icon cn-icon-domain domain-blue'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('app'): {
|
||||||
|
className = 'cn-icon cn-icon-app app-orange'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
return className
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
@@ -2,19 +2,28 @@
|
|||||||
<div class="entity-left-filter">
|
<div class="entity-left-filter">
|
||||||
<div class="filter__header">{{$t('entities.filter')}}</div>
|
<div class="filter__header">{{$t('entities.filter')}}</div>
|
||||||
<div class="filter__body">
|
<div class="filter__body">
|
||||||
<el-collapse v-model="active">
|
<el-collapse v-model="active" class="filter__collapse">
|
||||||
<el-collapse-item
|
<el-collapse-item
|
||||||
v-for="(f, i) in filterData"
|
v-for="(f, i) in filterData"
|
||||||
:key="i"
|
:key="i"
|
||||||
:title="f.title"
|
:title="f.title"
|
||||||
:name="`${i}`"
|
:name="`${i}`"
|
||||||
class="filter__collapse"
|
|
||||||
>
|
>
|
||||||
<el-tree
|
<el-tree
|
||||||
:data="f.data"
|
:data="f.data"
|
||||||
|
:load="(node, resolve) => f.load(node, resolve, f.filterType, f.childrenKey ? f.childrenKey : f.key)"
|
||||||
|
:node-key="f.key"
|
||||||
|
:props="{ isLeaf: 'leaf' }"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
:lazy="i === 0"
|
||||||
|
:show-checkbox="i === 1"
|
||||||
|
@node-click="nodeClick"
|
||||||
>
|
>
|
||||||
<template #default="{ node, data }">
|
<template #default="{ node, data }">
|
||||||
<span>{{data[f.key]}}-{{data.count}}</span>
|
<div class="filter-item">
|
||||||
|
<span>{{node.level === 1 ? data[f.key] : ''}}{{node.level === 2 ? data[f.childrenKey] : ''}}</span>
|
||||||
|
<span>{{data.count}}</span>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
@@ -34,8 +43,10 @@ export default {
|
|||||||
active: ['1']
|
active: ['1']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
methods: {
|
||||||
console.info(this.filterData)
|
nodeClick (data, node) {
|
||||||
|
this.$emit('select', data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -47,6 +58,7 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: 1px solid $--right-box-border-color;
|
border: 1px solid $--right-box-border-color;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
.filter__header {
|
.filter__header {
|
||||||
background-color: #FAFAFA;
|
background-color: #FAFAFA;
|
||||||
@@ -59,12 +71,28 @@ export default {
|
|||||||
.filter__body {
|
.filter__body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
.filter__collapse {
|
.filter__collapse {
|
||||||
max-height: 50%;
|
|
||||||
|
|
||||||
.el-collapse-item__header {
|
.el-collapse-item__header {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
|
padding-top: 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
border-bottom: 1px solid $--right-box-border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-collapse-item__wrap {
|
||||||
|
padding-top: 6px !important;
|
||||||
|
|
||||||
|
.filter-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-right: 6px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,4 +7,83 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
|
||||||
|
.entity-list {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.entity-list__content {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, var(--entity-width));
|
||||||
|
grid-auto-flow: row;
|
||||||
|
grid-auto-rows: var(--entity-height);
|
||||||
|
grid-gap: 10px;
|
||||||
|
height: calc(100% - 67px);
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.cn-entity {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 44% 56%;
|
||||||
|
border: 1px solid $--right-box-border-color;
|
||||||
|
|
||||||
|
.cn-entity__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
.header__icon {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
justify-items: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 52px;
|
||||||
|
height: 52px;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.header__content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding-left: 10px;
|
||||||
|
|
||||||
|
.content__title {
|
||||||
|
font-size: 22px;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.content__desc {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666666;
|
||||||
|
padding-top: 3px;
|
||||||
|
|
||||||
|
.desc__label {
|
||||||
|
color: #aaa;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cn-entity__body {
|
||||||
|
background-color: lightgoldenrodyellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.entity-list__pagination {
|
||||||
|
height: 67px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ip-green {
|
||||||
|
color: #23BF9A;
|
||||||
|
}
|
||||||
|
.domain-blue {
|
||||||
|
color: #0290FF;
|
||||||
|
}
|
||||||
|
.app-orange {
|
||||||
|
color: #FFA200;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ export const api = {
|
|||||||
chart: '/visual/chart',
|
chart: '/visual/chart',
|
||||||
entityIpFilter: '/interface/entity/ip/filter',
|
entityIpFilter: '/interface/entity/ip/filter',
|
||||||
entityDomainFilter: '/interface/entity/domain/filter',
|
entityDomainFilter: '/interface/entity/domain/filter',
|
||||||
entityAppFilter: '/interface/entity/app/filter'
|
entityAppFilter: '/interface/entity/app/filter',
|
||||||
|
entityIpList: '/interface/entity/ip/list',
|
||||||
|
entityDomainList: '/interface/entity/domain/list',
|
||||||
|
entityAppList: '/interface/entity/app/list'
|
||||||
}
|
}
|
||||||
/* panel */
|
/* panel */
|
||||||
export async function getPanelList (params) {
|
export async function getPanelList (params) {
|
||||||
@@ -44,6 +47,18 @@ export async function getEntityDomainFilterList (params) {
|
|||||||
export async function getEntityAppFilterList (params) {
|
export async function getEntityAppFilterList (params) {
|
||||||
return await getData(api.entityAppFilter, params, true)
|
return await getData(api.entityAppFilter, params, true)
|
||||||
}
|
}
|
||||||
|
/* ip类型entity列表 */
|
||||||
|
export async function getEntityIpList (params) {
|
||||||
|
return await getData(api.entityIpList, params, true)
|
||||||
|
}
|
||||||
|
/* domain类型entity列表 */
|
||||||
|
export async function getEntityDomainList (params) {
|
||||||
|
return await getData(api.entityDomainList, params, true)
|
||||||
|
}
|
||||||
|
/* app类型entity列表 */
|
||||||
|
export async function getEntityAppList (params) {
|
||||||
|
return await getData(api.entityAppList, params, true)
|
||||||
|
}
|
||||||
/* 字典 */
|
/* 字典 */
|
||||||
export async function getDictList (params) {
|
export async function getDictList (params) {
|
||||||
return await getData(api.dict, params, true)
|
return await getData(api.dict, params, true)
|
||||||
|
|||||||
@@ -21,9 +21,13 @@
|
|||||||
<!-- 筛选区域 -->
|
<!-- 筛选区域 -->
|
||||||
<left-filter
|
<left-filter
|
||||||
:filter-data="filterData"
|
:filter-data="filterData"
|
||||||
|
@select="select"
|
||||||
></left-filter>
|
></left-filter>
|
||||||
<!-- 内容区域 -->
|
<!-- 内容区域 -->
|
||||||
<div style="background-color: lightcyan"></div>
|
<entity-list
|
||||||
|
:list-data="listData"
|
||||||
|
:entity-type="filterType"
|
||||||
|
></entity-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -32,17 +36,32 @@
|
|||||||
import { entityType } from '@/utils/constants'
|
import { entityType } from '@/utils/constants'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import LeftFilter from '@/components/entities/LeftFilter'
|
import LeftFilter from '@/components/entities/LeftFilter'
|
||||||
import { getEntityIpFilterList, getEntityDomainFilterList, getEntityAppFilterList } from '@/utils/api'
|
import EntityList from '@/components/entities/EntityList'
|
||||||
|
import { getEntityIpFilterList, getEntityDomainFilterList, getEntityAppFilterList, getEntityIpList, getEntityDomainList, getEntityAppList } from '@/utils/api'
|
||||||
export default {
|
export default {
|
||||||
name: 'EntityExplorer',
|
name: 'EntityExplorer',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
searchContent: '',
|
searchContent: '',
|
||||||
filterData: []
|
filterData: [],
|
||||||
|
pageObjLeftTop: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10
|
||||||
|
},
|
||||||
|
pageObjLeftBottom: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10
|
||||||
|
},
|
||||||
|
pageObjRight: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 50
|
||||||
|
},
|
||||||
|
listData: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
LeftFilter
|
LeftFilter,
|
||||||
|
EntityList
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadData (filterType, conditionGroup) {
|
async loadData (filterType, conditionGroup) {
|
||||||
@@ -63,32 +82,60 @@ export default {
|
|||||||
default: break
|
default: break
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
},
|
||||||
|
select (data) {
|
||||||
|
|
||||||
|
},
|
||||||
|
getEntityData (param) {
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
filterType (n) {
|
filterType (n) {
|
||||||
|
this.pageObjLeftTop = {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
this.pageObjLeftBottom = {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
this.pageObjRight = {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 50
|
||||||
|
}
|
||||||
|
this.listData = []
|
||||||
const requests = []
|
const requests = []
|
||||||
const data = []
|
const data = []
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 'ip': {
|
case 'ip': {
|
||||||
requests.push(this.loadData(n, 'country'))
|
requests.push(this.loadData(n, 'country'))
|
||||||
requests.push(this.loadData(n, 'asn'))
|
requests.push(this.loadData(n, 'asn'))
|
||||||
data.push({ title: this.$t('entities.countryOrRegion'), key: 'country' })
|
data.push({ title: this.$t('entities.countryOrRegion'), key: 'country', childrenKey: 'region', load })
|
||||||
data.push({ title: this.$t('entities.systemNumber'), key: 'asn' })
|
data.push({ title: this.$t('entities.systemNumber'), key: 'asn', load })
|
||||||
|
getEntityIpList({ ...this.pageObjRight }).then(res => {
|
||||||
|
this.listData = res
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'domain': {
|
case 'domain': {
|
||||||
requests.push(this.loadData(n, 'group'))
|
requests.push(this.loadData(n, 'group'))
|
||||||
requests.push(this.loadData(n, 'level'))
|
requests.push(this.loadData(n, 'level'))
|
||||||
data.push({ title: this.$t('entities.group'), key: 'group' })
|
data.push({ title: this.$t('entities.group'), key: 'group', childrenKey: 'name', load })
|
||||||
data.push({ title: this.$t('entities.level'), key: 'level' })
|
data.push({ title: this.$t('entities.level'), key: 'level', load })
|
||||||
|
getEntityDomainList({ ...this.pageObjRight }).then(res => {
|
||||||
|
this.listData = res
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'app': {
|
case 'app': {
|
||||||
requests.push(this.loadData(n, 'category'))
|
requests.push(this.loadData(n, 'category'))
|
||||||
requests.push(this.loadData(n, 'risk'))
|
requests.push(this.loadData(n, 'risk'))
|
||||||
data.push({ title: this.$t('entities.category'), key: 'category' })
|
data.push({ title: this.$t('entities.category'), key: 'category', childrenKey: 'subcategory', load })
|
||||||
data.push({ title: this.$t('entities.risk'), key: 'risk' })
|
data.push({ title: this.$t('entities.risk'), key: 'risk', load })
|
||||||
|
getEntityAppList({ ...this.pageObjRight }).then(res => {
|
||||||
|
this.listData = res
|
||||||
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
default: break
|
default: break
|
||||||
@@ -104,15 +151,21 @@ export default {
|
|||||||
async mounted () {
|
async mounted () {
|
||||||
const country = await this.loadData(this.filterType, 'country')
|
const country = await this.loadData(this.filterType, 'country')
|
||||||
const asn = await this.loadData(this.filterType, 'asn')
|
const asn = await this.loadData(this.filterType, 'asn')
|
||||||
|
this.listData = await getEntityIpList({ ...this.pageObjRight })
|
||||||
this.filterData.push({
|
this.filterData.push({
|
||||||
title: this.$t('entities.countryOrRegion'),
|
title: this.$t('entities.countryOrRegion'),
|
||||||
key: 'country',
|
key: 'country',
|
||||||
data: country
|
childrenKey: 'region',
|
||||||
|
data: country,
|
||||||
|
filterType: this.filterType,
|
||||||
|
load
|
||||||
})
|
})
|
||||||
this.filterData.push({
|
this.filterData.push({
|
||||||
title: this.$t('entities.systemNumber'),
|
title: this.$t('entities.systemNumber'),
|
||||||
key: 'asn',
|
key: 'asn',
|
||||||
data: asn
|
data: asn,
|
||||||
|
filterType: this.filterType,
|
||||||
|
load
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
setup () {
|
setup () {
|
||||||
@@ -123,6 +176,36 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const load = (node, resolve, filterType, key) => {
|
||||||
|
if (node.level === 0) {
|
||||||
|
resolve(node.data)
|
||||||
|
} else {
|
||||||
|
let req = null
|
||||||
|
switch (filterType) {
|
||||||
|
case 'ip': {
|
||||||
|
req = getEntityIpFilterList({ type: key })
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'domain': {
|
||||||
|
req = getEntityDomainFilterList({ type: key })
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'app': {
|
||||||
|
req = getEntityAppFilterList({ type: key })
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
if (req !== null) {
|
||||||
|
req.then(res => {
|
||||||
|
res = res.map(r => {
|
||||||
|
return { ...r, leaf: true }
|
||||||
|
})
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
Reference in New Issue
Block a user