CN-64 feat: 搜索框联动,其他一些细节调整
This commit is contained in:
@@ -8,15 +8,16 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-input
|
<el-input
|
||||||
prefix-icon="el-icon-user"
|
prefix-icon="el-icon-user"
|
||||||
class="inputstyle login__input"
|
class="login--input login__input"
|
||||||
v-model="username"
|
v-model="username"
|
||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-input
|
<el-input
|
||||||
class="inputstyle"
|
class="login--input"
|
||||||
prefix-icon="el-icon-lock"
|
prefix-icon="el-icon-lock"
|
||||||
type="password"
|
type="password"
|
||||||
|
@keyup.enter="login"
|
||||||
v-model="pin"
|
v-model="pin"
|
||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -24,8 +25,9 @@
|
|||||||
<el-button
|
<el-button
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
type="primary"
|
type="primary"
|
||||||
class="inputstyle login__button"
|
class="login--input login--butotn"
|
||||||
@click="login"
|
@click="login"
|
||||||
|
@keyup.enter="login"
|
||||||
style="font-size: 16px;"
|
style="font-size: 16px;"
|
||||||
>Login</el-button
|
>Login</el-button
|
||||||
>
|
>
|
||||||
@@ -104,7 +106,7 @@ export default {
|
|||||||
margin-left: 52px;
|
margin-left: 52px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
.inputstyle{
|
.login--input{
|
||||||
width: 300px;
|
width: 300px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
@@ -116,7 +118,7 @@ export default {
|
|||||||
height: 250px;
|
height: 250px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
.login__button {
|
.login--butotn {
|
||||||
background: #0091ff;
|
background: #0091ff;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|||||||
@@ -11,14 +11,14 @@
|
|||||||
<slot name="title"></slot>
|
<slot name="title"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="single-value__content" v-if="type === 52" style="width: 100%;height: 100%;display: flex;flex-direction: column;justify-content: center;padding: 0px 10px">
|
<div class="single-value__content" v-if="type === 52">
|
||||||
<div class="content__title" style="height: 20%;">
|
<div class="content__title">
|
||||||
<slot name="title"></slot>
|
<slot name="title"></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="content__data" style="height: 20%;">
|
<div class="content__data">
|
||||||
<slot name="data"></slot>
|
<slot name="data"></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="content__chart" style="height: 40%;">
|
<div class="content__chart">
|
||||||
<slot name="chart"></slot>
|
<slot name="chart"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -41,13 +41,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
&>.cn-chart.cn-chart__echarts--statistics {
|
|
||||||
border: none;
|
|
||||||
box-shadow: none;
|
|
||||||
.cn-chart__header {
|
|
||||||
border-bottom: 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;
|
||||||
@@ -178,6 +171,36 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&>.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 {
|
&>.cn-chart__title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -409,6 +432,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.cn-panel>.cn-chart__tabs>.el-tabs__content>.el-tab-pane>.cn-chart {
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
.cn-chart__header {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
.option-popper {
|
.option-popper {
|
||||||
.el-select-dropdown__item {
|
.el-select-dropdown__item {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
|||||||
@@ -5,23 +5,23 @@
|
|||||||
<div class="cn-entity__header">
|
<div class="cn-entity__header">
|
||||||
<div class="header__icon"><i :class="iconClass"></i></div>
|
<div class="header__icon"><i :class="iconClass"></i></div>
|
||||||
<div class="header__content" :title="d.ip||d.domainName||d.appName">
|
<div class="header__content" :title="d.ip||d.domainName||d.appName">
|
||||||
<template v-if="entityType === 'ip'">{{d.ip || 'Unknown'}}</template>
|
<template v-if="from === 'ip'">{{d.ip || 'Unknown'}}</template>
|
||||||
<template v-else-if="entityType === 'domain'">{{d.domainName || 'Unknown'}}</template>
|
<template v-else-if="from === 'domain'">{{d.domainName || 'Unknown'}}</template>
|
||||||
<template v-else-if="entityType === 'app'">{{d.appName || 'Unknown'}}</template>
|
<template v-else-if="from === 'app'">{{d.appName || 'Unknown'}}</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cn-entity__body" style="position: relative;">
|
<div class="cn-entity__body" style="position: relative;">
|
||||||
<div class="content__desc" v-if="entityType !== 'ip'" style="color: #999999; width: 200px; position: absolute; top: 33px;right: -9px ;font-size: 12px;">
|
<div class="content__desc" v-if="from !== 'ip'" style="color: #999999; width: 200px; position: absolute; top: 33px;right: -9px ;font-size: 12px;">
|
||||||
<template v-if="entityType === 'domain'" style="color: #999999; width: 200px;">
|
<template v-if="from === 'domain'">
|
||||||
<span class="desc__label">{{$t('entities.reputationLevel')}}:</span>
|
<span class="desc__label">{{$t('entities.reputationLevel')}}:</span>
|
||||||
<span>{{d.reputationLevel || '-'}}</span>
|
<span>{{d.reputationLevel || '-'}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="entityType === 'app'" style="color: #999999; width: 200px; margin:0px 35px;">
|
<template v-else-if="from === 'app'">
|
||||||
<span class="desc__label">{{$t('entities.risk')}}:</span>
|
<span class="desc__label">{{$t('entities.risk')}}:</span>
|
||||||
<span>{{d.appRisk || '-'}}</span>
|
<span>{{d.appRisk || '-'}}</span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="entityType === 'ip'">
|
<template v-if="from === 'ip'">
|
||||||
<div class="body__row">
|
<div class="body__row">
|
||||||
<span class="body__row-label"><i class="cn-icon cn-icon-category"></i> {{$t('overall.country')}}:</span>
|
<span class="body__row-label"><i class="cn-icon cn-icon-category"></i> {{$t('overall.country')}}:</span>
|
||||||
<div class="body__row-value" :title="d.country">{{d.country || '-'}}</div>
|
<div class="body__row-value" :title="d.country">{{d.country || '-'}}</div>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<div class="body__detail"
|
<div class="body__detail"
|
||||||
@click="entityDetail({clientIP: d.ip}, [{key: 'clientIP', label: $t('overall.clientIp')}, {key: 'serverIP', label: $t('overall.serverIp')}])">{{$t('overall.detail')}}></div>
|
@click="entityDetail({clientIP: d.ip}, [{key: 'clientIP', label: $t('overall.clientIp')}, {key: 'serverIP', label: $t('overall.serverIp')}])">{{$t('overall.detail')}}></div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="entityType === 'domain'">
|
<template v-else-if="from === 'domain'">
|
||||||
<div class="body__row">
|
<div class="body__row">
|
||||||
<span class="body__row-label"><i class="cn-icon cn-icon-category"></i> {{$t('entities.Group')}}:</span>
|
<span class="body__row-label"><i class="cn-icon cn-icon-category"></i> {{$t('entities.Group')}}:</span>
|
||||||
<div class="body__row-value" :title="d.categoryGroup">{{d.categoryGroup || '-'}}</div>
|
<div class="body__row-value" :title="d.categoryGroup">{{d.categoryGroup || '-'}}</div>
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="body__detail" @click="entityDetail({domain: d.domainName})">{{$t('overall.detail')}}></div>
|
<div class="body__detail" @click="entityDetail({domain: d.domainName})">{{$t('overall.detail')}}></div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="entityType === 'app'">
|
<template v-else-if="from === 'app'">
|
||||||
<div class="body__row">
|
<div class="body__row">
|
||||||
<span class="body__row-label"><i class="cn-icon cn-icon-risk"></i> APP ID:</span>
|
<span class="body__row-label"><i class="cn-icon cn-icon-risk"></i> APP ID:</span>
|
||||||
<div class="body__row-value" :title="d.appId">{{d.appId || '-'}}</div>
|
<div class="body__row-value" :title="d.appId">{{d.appId || '-'}}</div>
|
||||||
@@ -79,7 +79,6 @@
|
|||||||
:currentPage="pageObj.pageNo"
|
:currentPage="pageObj.pageNo"
|
||||||
:page-size="pageObj.pageSize"
|
:page-size="pageObj.pageSize"
|
||||||
:total="pageObj.total"
|
:total="pageObj.total"
|
||||||
:page-sizes="[30, 50, 100]"
|
|
||||||
layout="total, prev, pager, next"
|
layout="total, prev, pager, next"
|
||||||
></el-pagination>
|
></el-pagination>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,7 +90,7 @@ export default {
|
|||||||
name: 'EntityList',
|
name: 'EntityList',
|
||||||
props: {
|
props: {
|
||||||
listData: Array,
|
listData: Array,
|
||||||
entityType: String,
|
from: String,
|
||||||
pageObj: Object
|
pageObj: Object
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -103,7 +102,7 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
circleColor () {
|
circleColor () {
|
||||||
let color
|
let color
|
||||||
switch (this.entityType) {
|
switch (this.from) {
|
||||||
case ('ip'): {
|
case ('ip'): {
|
||||||
color = '#E8FBF9'
|
color = '#E8FBF9'
|
||||||
break
|
break
|
||||||
@@ -122,7 +121,7 @@ export default {
|
|||||||
},
|
},
|
||||||
iconClass () {
|
iconClass () {
|
||||||
let className
|
let className
|
||||||
switch (this.entityType) {
|
switch (this.from) {
|
||||||
case ('ip'): {
|
case ('ip'): {
|
||||||
className = 'cn-icon cn-icon-ip ip-green'
|
className = 'cn-icon cn-icon-ip ip-green'
|
||||||
break
|
break
|
||||||
@@ -160,11 +159,7 @@ export default {
|
|||||||
scrollbarToTop () {
|
scrollbarToTop () {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const wraps = document.querySelectorAll('.el-table__body-wrapper')
|
const wraps = document.querySelectorAll('.el-table__body-wrapper')
|
||||||
wraps.forEach(wrap => {
|
wraps.scrollTop = 0
|
||||||
if (wrap._ps_) {
|
|
||||||
wrap.scrollTop = 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
entityDetail (params, tabs = []) {
|
entityDetail (params, tabs = []) {
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.currentDataBottom = this.$_.cloneDeep(data)
|
this.currentDataBottom = this.$_.cloneDeep(data)
|
||||||
}
|
}
|
||||||
|
console.info(this.currentDataTop)
|
||||||
|
console.info(this.currentDataBottom)
|
||||||
this.$emit('select', data, node, index, column)
|
this.$emit('select', data, node, index, column)
|
||||||
},
|
},
|
||||||
showMore (filterData) {
|
showMore (filterData) {
|
||||||
@@ -94,8 +96,6 @@ export default {
|
|||||||
this.$emit('showMore', filterData.column)
|
this.$emit('showMore', filterData.column)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
loadFilter (node, resolve, f) {
|
|
||||||
},
|
|
||||||
dataEqual (obj1, obj2) {
|
dataEqual (obj1, obj2) {
|
||||||
if (!obj1 || !obj2) {
|
if (!obj1 || !obj2) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
margin-top: 23px;
|
margin-top: 23px;
|
||||||
|
|
||||||
.el-pager {
|
.el-pager {
|
||||||
li:last-of-type {
|
.btn-quicknext + li {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,26 @@
|
|||||||
<div class="cn-header">
|
<div class="cn-header">
|
||||||
<!-- <div class="left-menu--pin" :class="false ? 'left-menu--pin-normal' : 'left-menu--pin-reverse'" @click="shrink"><i :class="{'icon-reverse': false}" class="el-icon-s-fold"></i></div>-->
|
<!-- <div class="left-menu--pin" :class="false ? 'left-menu--pin-normal' : 'left-menu--pin-reverse'" @click="shrink"><i :class="{'icon-reverse': false}" class="el-icon-s-fold"></i></div>-->
|
||||||
<!--导航面包屑-->
|
<!--导航面包屑-->
|
||||||
<div style="flex-grow: 1;display: flex;padding: 0 70px;align-items: center">
|
<div class="header__left">
|
||||||
<el-breadcrumb separator="/">
|
<span @click="shrink" class="shrink-button" :class="{'shrink-button--collapse': isShrink}"><i class="cn-icon cn-icon-expand"></i></span>
|
||||||
<el-breadcrumb-item v-for="item in breadcrumb" :key="item">{{item}}</el-breadcrumb-item>
|
<el-breadcrumb separator="/" style="padding-left: 20px; padding-top: 6px;">
|
||||||
|
<el-breadcrumb-item :title="item" v-for="item in breadcrumb" :key="item" style="display: inline-block; max-width: 300px; height: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
|
||||||
|
{{item}}
|
||||||
|
</el-breadcrumb-item>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
|
<el-select
|
||||||
|
size="small"
|
||||||
|
v-model="from"
|
||||||
|
v-if="showEntityTypeSelector"
|
||||||
|
style="padding-left: 25px; width: 130px;"
|
||||||
|
>
|
||||||
|
<el-option v-for="(value, key) in entityType" :key="key" :label="value" :value="key"></el-option>
|
||||||
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<!--个人操作-->
|
<!--个人操作-->
|
||||||
<div class="personal">
|
<div class="personal">
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
<div class="header-menu--item">Language</div>
|
<div class="header-menu--item"><i class="cn-icon cn-icon-language"></i></div>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item>
|
<el-dropdown-item>
|
||||||
@@ -25,7 +36,7 @@
|
|||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
<div class='login-user header-menu--item'>{{username}} <i class="cn-icon cn-icon-arrow-down"></i></div>
|
<div class='login-user header-menu--item'>{{username}} <i class="cn-icon cn-icon-arrow-down"></i></div>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu #dropdown>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item>
|
<el-dropdown-item>
|
||||||
<div id="header-to-changepin" @click="showPinDialog">Change pin</div>
|
<div id="header-to-changepin" @click="showPinDialog">Change pin</div>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
@@ -42,6 +53,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
import { get } from '@/utils/http'
|
||||||
|
import { entityType, storageKey } from '@/utils/constants'
|
||||||
export default {
|
export default {
|
||||||
name: 'Header',
|
name: 'Header',
|
||||||
data () {
|
data () {
|
||||||
@@ -67,36 +80,68 @@ export default {
|
|||||||
name: this.$t('dnsServiceInsights')
|
name: this.$t('dnsServiceInsights')
|
||||||
}, {
|
}, {
|
||||||
path: '/entityExplorer',
|
path: '/entityExplorer',
|
||||||
parentName: this.$t('overall.dashboard'),
|
parentName: this.$t('overall.entities'),
|
||||||
name: this.$t('overall.entityExplorer')
|
name: this.$t('overall.entityExplorer'),
|
||||||
|
childName: ''
|
||||||
}, {
|
}, {
|
||||||
path: '/user',
|
path: '/user',
|
||||||
parentName: this.$t('overall.dashboard'),
|
parentName: this.$t('overall.setting'),
|
||||||
name: this.$t('user')
|
name: this.$t('overall.user')
|
||||||
}, {
|
}, {
|
||||||
path: '/role',
|
path: '/role',
|
||||||
parentName: this.$t('overall.dashboard'),
|
parentName: this.$t('overall.setting'),
|
||||||
name: this.$t('role')
|
name: this.$t('overall.role')
|
||||||
}, {
|
}, {
|
||||||
path: '/operationLog',
|
path: '/operationLog',
|
||||||
parentName: this.$t('overall.dashboard'),
|
parentName: this.$t('overall.setting'),
|
||||||
name: this.$t('overall.operationLog')
|
name: this.$t('overall.operationLog')
|
||||||
}, {
|
}, {
|
||||||
path: '/i18n',
|
path: '/i18n',
|
||||||
parentName: this.$t('overall.dashboard'),
|
parentName: this.$t('overall.setting'),
|
||||||
name: this.$t('l18n')
|
name: 'I18N'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
from: '' // entity类型
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
breadcrumb () {
|
breadcrumb () {
|
||||||
const breadcrumb = this.breadcrumbMap.find(b => this.path === b.path)
|
const breadcrumb = this.breadcrumbMap.find(b => this.path === b.path)
|
||||||
return breadcrumb ? [breadcrumb.parentName, breadcrumb.name] : []
|
const breadcrumbArray = breadcrumb ? [breadcrumb.parentName, breadcrumb.name] : []
|
||||||
|
if (breadcrumbArray.length > 0 && breadcrumb.childName) {
|
||||||
|
breadcrumbArray.push(breadcrumb.childName)
|
||||||
|
}
|
||||||
|
return breadcrumbArray
|
||||||
},
|
},
|
||||||
path () {
|
path () {
|
||||||
const { path } = useRoute()
|
const { path } = useRoute()
|
||||||
return path
|
return path
|
||||||
|
},
|
||||||
|
showEntityTypeSelector () {
|
||||||
|
return this.$store.getters.getShowEntityTypeSelector
|
||||||
|
},
|
||||||
|
isShrink () {
|
||||||
|
return this.$store.getters.getIsShrink
|
||||||
|
},
|
||||||
|
entityName () {
|
||||||
|
return this.$store.getters.entityName
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
from (n) {
|
||||||
|
this.$store.commit('entityTypeChange', n)
|
||||||
|
},
|
||||||
|
entityName (n) {
|
||||||
|
const breadcrumb = this.breadcrumbMap.find(b => b.path === '/entityExplorer')
|
||||||
|
breadcrumb.childName = n
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.from = Object.keys(this.entityType)[0]
|
||||||
|
},
|
||||||
|
setup () {
|
||||||
|
return {
|
||||||
|
entityType // 所有entity类型,用于header下拉框选择
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -111,6 +156,8 @@ export default {
|
|||||||
this.showChangePin = true
|
this.showChangePin = true
|
||||||
},
|
},
|
||||||
logout () {
|
logout () {
|
||||||
|
sessionStorage.removeItem(storageKey.token)
|
||||||
|
get('/logout')
|
||||||
},
|
},
|
||||||
refreshLang () {
|
refreshLang () {
|
||||||
this.language = localStorage.getItem('cn-language')
|
this.language = localStorage.getItem('cn-language')
|
||||||
@@ -120,6 +167,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
shrink () {
|
shrink () {
|
||||||
|
this.$store.commit('isShrink', !this.isShrink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,6 +178,22 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
|
||||||
|
.header__left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.shrink-button {
|
||||||
|
margin-left: 20px;
|
||||||
|
color: #A4ADB5;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all linear .4s;
|
||||||
|
|
||||||
|
&.shrink-button--collapse {
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.header-menu {
|
.header-menu {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
:index="`${index}`">
|
:index="`${index}`">
|
||||||
<template #title>
|
<template #title>
|
||||||
<i :class="menu.icon"></i>
|
<i :class="menu.icon"></i>
|
||||||
<span :title="menu.name">{{menu.i18n ? $t(menu.i18n) : menu.name}}</span>
|
<span :title="$t(menu.i18n)">{{menu.i18n ? $t(menu.i18n) : menu.name}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-for="(secondMenu, secondIndex) in menu.children">
|
<template v-for="(secondMenu, secondIndex) in menu.children">
|
||||||
<el-submenu
|
<el-submenu
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-for="(thirdMenu, thirdIndex) in secondMenu.children" :key="`${index}-${secondIndex}-${thirdIndex}`">
|
<template v-for="(thirdMenu, thirdIndex) in secondMenu.children" :key="`${index}-${secondIndex}-${thirdIndex}`">
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
:title="thirdMenu.name"
|
:title="$t(thirdMenu.i18n)"
|
||||||
v-if="thirdMenu.state === 1"
|
v-if="thirdMenu.state === 1"
|
||||||
:index="thirdMenu.route">
|
:index="thirdMenu.route">
|
||||||
{{thirdMenu.i18n ? $t(thirdMenu.i18n) : thirdMenu.name}}
|
{{thirdMenu.i18n ? $t(thirdMenu.i18n) : thirdMenu.name}}
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
:title="secondMenu.name"
|
:title="$t(secondMenu.i18n)"
|
||||||
v-else-if="secondMenu.state === 1"
|
v-else-if="secondMenu.state === 1"
|
||||||
:key="secondIndex * 100"
|
:key="secondIndex * 100"
|
||||||
:index="secondMenu.route">
|
:index="secondMenu.route">
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
:title="menu.name"
|
:title="menu.i18n"
|
||||||
v-else-if="menu.state === 1"
|
v-else-if="menu.state === 1"
|
||||||
:key="index + 'a'"
|
:key="index + 'a'"
|
||||||
:index="menu.route">
|
:index="menu.route">
|
||||||
@@ -132,6 +132,30 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
// el-submenu active字色
|
||||||
|
.el-submenu.is-active .el-submenu__title,
|
||||||
|
.el-submenu.is-active .el-submenu__title>i,
|
||||||
|
.el-menu-item.is-active {
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
// el-submenu active且open背景色
|
||||||
|
.el-submenu__title:not(.is-active):hover, .el-menu-item:not(.is-active):hover, .el-menu-item:not(.is-active):focus {
|
||||||
|
background-color: mix($--color-white, $--menu-background-color, 7%) !important;
|
||||||
|
}
|
||||||
|
.is-active.is-opened {
|
||||||
|
.el-submenu__title, .el-menu-item:not(.is-active) {
|
||||||
|
background-color: $--menu-hover-background-color !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-menu-item {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
background-color: $--color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.left-menu {
|
.left-menu {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -154,31 +178,6 @@ export default {
|
|||||||
border-right: none;
|
border-right: none;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
// el-submenu active字色
|
|
||||||
.el-submenu.is-active .el-submenu__title,
|
|
||||||
.el-submenu.is-active .el-submenu__title>i,
|
|
||||||
.el-menu-item.is-active {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// el-submenu active且open背景色
|
|
||||||
.el-submenu__title:not(.is-active):hover, .el-menu-item:not(.is-active):hover, .el-menu-item:not(.is-active):focus {
|
|
||||||
background-color: mix($--color-white, $--menu-background-color, 7%) !important;
|
|
||||||
}
|
|
||||||
.is-active.is-opened {
|
|
||||||
.el-submenu__title, .el-menu-item:not(.is-active) {
|
|
||||||
background-color: $--menu-hover-background-color !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.el-menu-item {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
|
|
||||||
&.is-active {
|
|
||||||
background-color: $--color-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-menu-item, .el-submenu__title {
|
.el-menu-item, .el-submenu__title {
|
||||||
height: 46px;
|
height: 46px;
|
||||||
line-height: 46px;
|
line-height: 46px;
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ import axios from 'axios'
|
|||||||
import { storageKey } from '@/utils/constants'
|
import { storageKey } from '@/utils/constants'
|
||||||
import { loadI18n } from '@/i18n'
|
import { loadI18n } from '@/i18n'
|
||||||
|
|
||||||
const loginWhiteList = ['/login'] // 免登陆白名单
|
const loginWhiteList = ['/login', '/'] // 免登陆白名单
|
||||||
const permissionWhiteList = [...loginWhiteList] // 权限白名单
|
const permissionWhiteList = [...loginWhiteList] // 权限白名单
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
// await test(to, from)
|
||||||
// 加载iso-3166-2资源
|
// 加载iso-3166-2资源
|
||||||
loadGeoData()
|
loadGeoData()
|
||||||
// 加载baseUrl
|
// 加载baseUrl
|
||||||
|
|||||||
@@ -8,12 +8,25 @@ const store = createStore({
|
|||||||
state () {
|
state () {
|
||||||
return {
|
return {
|
||||||
isShrink: localStorage.getItem('cn-left-menu-shrink') === 'true',
|
isShrink: localStorage.getItem('cn-left-menu-shrink') === 'true',
|
||||||
i18n: false
|
i18n: false,
|
||||||
|
|
||||||
|
showEntityTypeSelector: false, // 在entity explore页面时,控制header显示实体类型选择框
|
||||||
|
from: '', // entity type
|
||||||
|
entityName: '' // entity名称,用于header顶部面包屑展示
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getIsShrink (state) {
|
getIsShrink (state) {
|
||||||
return state.isShrink
|
return state.isShrink
|
||||||
|
},
|
||||||
|
getShowEntityTypeSelector (state) {
|
||||||
|
return state.showEntityTypeSelector
|
||||||
|
},
|
||||||
|
from (state) {
|
||||||
|
return state.from
|
||||||
|
},
|
||||||
|
entityName (state) {
|
||||||
|
return state.entityName
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
@@ -23,6 +36,17 @@ const store = createStore({
|
|||||||
},
|
},
|
||||||
loadI18n (state) {
|
loadI18n (state) {
|
||||||
state.i18n = true
|
state.i18n = true
|
||||||
|
},
|
||||||
|
entityTypeChange (state, from) {
|
||||||
|
if (from) {
|
||||||
|
state.from = from
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showEntityTypeSelector (state, show) {
|
||||||
|
state.showEntityTypeSelector = show
|
||||||
|
},
|
||||||
|
setEntityName (state, entityName) {
|
||||||
|
state.entityName = entityName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export const api = {
|
|||||||
entityCount: '/interface/entity/total',
|
entityCount: '/interface/entity/total',
|
||||||
entityFilter: '/interface/entity/filter'
|
entityFilter: '/interface/entity/filter'
|
||||||
}
|
}
|
||||||
|
|
||||||
/* panel */
|
/* panel */
|
||||||
export async function getPanelList (params) {
|
export async function getPanelList (params) {
|
||||||
return await getData(api.panel, params, true)
|
return await getData(api.panel, params, true)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { storageKey } from '@/utils/constants'
|
||||||
|
|
||||||
axios.interceptors.request.use(config => {
|
axios.interceptors.request.use(config => {
|
||||||
const token = sessionStorage.getItem('cn-token')
|
const token = sessionStorage.getItem('cn-token')
|
||||||
@@ -41,6 +42,7 @@ axios.interceptors.response.use(
|
|||||||
response => {
|
response => {
|
||||||
if (licenceErrorCode.indexOf(response.data.code) !== -1) {
|
if (licenceErrorCode.indexOf(response.data.code) !== -1) {
|
||||||
window.location.href = '/'
|
window.location.href = '/'
|
||||||
|
sessionStorage.removeItem(storageKey.token)
|
||||||
} else if (response.status === 200) {
|
} else if (response.status === 200) {
|
||||||
if (accountErrorCode.indexOf(response.data.code) !== -1) {
|
if (accountErrorCode.indexOf(response.data.code) !== -1) {
|
||||||
window.location.href = '/'
|
window.location.href = '/'
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export default function unitConvert (value, unitType, sourceUnit, targetUnit, do
|
|||||||
return ['-', '']
|
return ['-', '']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Number(value) && Number(value) !== 0) {
|
if (!value && value !== 0) {
|
||||||
return ['-', '']
|
return ['-', '']
|
||||||
} else {
|
} else {
|
||||||
switch (unitType) {
|
switch (unitType) {
|
||||||
|
|||||||
@@ -92,14 +92,7 @@
|
|||||||
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
|
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #chart>
|
<template #chart>
|
||||||
<div class="chart-drawing" :id="`chart${chartInfo.id}`" style="
|
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||||
width:100%;
|
|
||||||
height: 100%;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
border-width: 0px;"></div>
|
|
||||||
</template>
|
</template>
|
||||||
</single-value>
|
</single-value>
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
@@ -236,7 +229,8 @@ export default {
|
|||||||
selectPieChartName: '',
|
selectPieChartName: '',
|
||||||
allSelectPieChartName: [],
|
allSelectPieChartName: [],
|
||||||
chartOption: null,
|
chartOption: null,
|
||||||
loading: true
|
loading: true,
|
||||||
|
throttle: null // 节流器
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -284,15 +278,14 @@ export default {
|
|||||||
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000) }
|
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000) }
|
||||||
get(replaceUrlPlaceholder(chartParams.urlLine, queryParams)).then(response => {
|
get(replaceUrlPlaceholder(chartParams.urlLine, queryParams)).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
response.data.result = [
|
/*response.data.result = [
|
||||||
{
|
{
|
||||||
legend: "session_rate",
|
legend: "session_rate",
|
||||||
values:[
|
values:[
|
||||||
["1625122200","2"],["1625122500","2"],["1625122800","1"],["1625123100","1"],["1625123400","2"],["1625123700","2"],["1625124000","2"],["1625124300","3"],["1625124600","3"],["1625124900","3"]
|
["1625122200","2"],["1625122500","2"],["1625122800","1"],["1625123100","1"],["1625123400","2"],["1625123700","2"],["1625124000","2"],["1625124300","3"],["1625124600","3"],["1625124900","3"]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]*/
|
||||||
|
|
||||||
this.chartOption.series = response.data.result.map((r, i) => {
|
this.chartOption.series = response.data.result.map((r, i) => {
|
||||||
return {
|
return {
|
||||||
...seriesTemplate,
|
...seriesTemplate,
|
||||||
@@ -665,6 +658,9 @@ export default {
|
|||||||
}
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
echartsResize () {
|
||||||
|
this.myChart.resize()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -696,6 +692,8 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.initChart()
|
this.initChart()
|
||||||
|
this.throttle = this.$_.throttle(this.echartsResize, 500)
|
||||||
|
window.addEventListener('resize', this.throttle)
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
chart: {
|
chart: {
|
||||||
@@ -741,6 +739,9 @@ export default {
|
|||||||
layout: getLayout(props.chart.type),
|
layout: getLayout(props.chart.type),
|
||||||
myChart: shallowRef(null)
|
myChart: shallowRef(null)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
unmounted () {
|
||||||
|
window.removeEventListener('resize', this.throttle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
<div v-if="typeName" class="entity-detail-tool">
|
<div v-if="typeName" class="entity-detail-tool">
|
||||||
<div>
|
<div>
|
||||||
<span @click="goBack" style="cursor: pointer;"><i class="cn-icon cn-icon-arrow-left-circle"></i></span>
|
<span @click="goBack" style="cursor: pointer;"><i class="cn-icon cn-icon-arrow-left-circle"></i></span>
|
||||||
|
<span style="padding-left: 15px; color: #333;">{{tabTitle}}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-radio-group v-model="tab" size="mini" @change="changeTab">
|
<el-radio-group v-model="tab" size="mini" @change="changeTab">
|
||||||
<el-radio-button v-for="tab in tabs" :key="tab.key" :label="tab.label"></el-radio-button>
|
<el-radio-button v-for="tab in tabs" :key="tab.key" :label="tab.label"></el-radio-button>
|
||||||
@@ -64,6 +65,27 @@ export default {
|
|||||||
chartList: []
|
chartList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
tabTitle () {
|
||||||
|
let title
|
||||||
|
switch (this.typeName) {
|
||||||
|
case 'ipEntityDetail': {
|
||||||
|
title = this.$t('entities.ipDetail')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'domainEntityDetail': {
|
||||||
|
title = this.$t('entities.domainDetail')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'appEntityDetail': {
|
||||||
|
title = this.$t('entities.appDetail')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
return title
|
||||||
|
}
|
||||||
|
},
|
||||||
async mounted () {
|
async mounted () {
|
||||||
await this.init()
|
await this.init()
|
||||||
},
|
},
|
||||||
@@ -146,6 +168,9 @@ export default {
|
|||||||
this.$refs[`chart-${chart.id}`] && this.$refs[`chart-${chart.id}`].reloadChart()
|
this.$refs[`chart-${chart.id}`] && this.$refs[`chart-${chart.id}`].reloadChart()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
beforeUnmount () {
|
||||||
|
this.$store.commit('setEntityName', '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="outer-box" v-if="!showDetail">
|
<div class="outer-box" v-show="!showDetail">
|
||||||
<el-select
|
|
||||||
size="small"
|
|
||||||
v-model="from"
|
|
||||||
style="position: fixed; top: 9px; width: 130px; left:260px;"
|
|
||||||
>
|
|
||||||
<el-option v-for="(value, key) in entityType" :key="key" :label="value" :value="key"></el-option>
|
|
||||||
</el-select>
|
|
||||||
<div class="cn-entities">
|
<div class="cn-entities">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchContentTemp"
|
v-model="searchContentTemp"
|
||||||
@@ -24,27 +17,24 @@
|
|||||||
:bottom-filter-data="bottomFilterData"
|
:bottom-filter-data="bottomFilterData"
|
||||||
@select="select"
|
@select="select"
|
||||||
@showMore="showMore"
|
@showMore="showMore"
|
||||||
@loadFilter="loadFilter"
|
|
||||||
style="grid-area: 2 / 1 / 3 / 2;"
|
style="grid-area: 2 / 1 / 3 / 2;"
|
||||||
></left-filter>
|
></left-filter>
|
||||||
<!-- 内容区域 -->
|
<!-- 内容区域 -->
|
||||||
<entity-list
|
<entity-list
|
||||||
:list-data="listData"
|
:list-data="listData"
|
||||||
:entity-type="from"
|
:from="from"
|
||||||
:page-obj="pageObjRight"
|
:page-obj="pageObjRight"
|
||||||
@showDetail="entityDetail"
|
@showDetail="entityDetail"
|
||||||
@pageSize="pageSizeRight"
|
|
||||||
@pageNo="pageNoRight"
|
@pageNo="pageNoRight"
|
||||||
style="grid-area: 2 / 2 / 3 / 3;"
|
style="grid-area: 2 / 2 / 3 / 3;"
|
||||||
></entity-list>
|
></entity-list>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<cn-panel v-else :entity="currentEntity" :type-name="typeName" :tabs="panelTabs" @goBack="showDetail = false"></cn-panel>
|
<cn-panel v-if="showDetail" :entity="currentEntity" :type-name="typeName" :tabs="panelTabs" @goBack="showDetail = false"></cn-panel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { entityType, entityFilterType } from '@/utils/constants'
|
import { entityType, entityFilterType } from '@/utils/constants'
|
||||||
import { ref } from 'vue'
|
|
||||||
import LeftFilter from '@/components/entities/LeftFilter'
|
import LeftFilter from '@/components/entities/LeftFilter'
|
||||||
import EntityList from '@/components/entities/EntityList'
|
import EntityList from '@/components/entities/EntityList'
|
||||||
import { getEntityFilter, getEntityList, getEntityCount } from '@/utils/api'
|
import { getEntityFilter, getEntityList, getEntityCount } from '@/utils/api'
|
||||||
@@ -112,7 +102,7 @@ export default {
|
|||||||
}
|
}
|
||||||
default: break
|
default: break
|
||||||
}
|
}
|
||||||
const { topFilterData, bottomFilterData } = await this.queryFilterData({ column, q: this.searchContent, from: this.from })
|
const { topFilterData, bottomFilterData } = await this.queryFilterData({ column, q: this.doubleQuotationToSingle(this.searchContent), from: this.from })
|
||||||
if (index === 1) {
|
if (index === 1) {
|
||||||
this.bottomFilterData = {
|
this.bottomFilterData = {
|
||||||
...this.bottomFilterData,
|
...this.bottomFilterData,
|
||||||
@@ -128,7 +118,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async search () {
|
async search () {
|
||||||
const params = { from: this.from, q: this.searchContent }
|
const params = { from: this.from, q: this.doubleQuotationToSingle(this.searchContent) }
|
||||||
this.listData = await getEntityList({ ...this.pageObjRight, ...params })
|
this.listData = await getEntityList({ ...this.pageObjRight, ...params })
|
||||||
this.pageObjRight.total = await getEntityCount(params)
|
this.pageObjRight.total = await getEntityCount(params)
|
||||||
const { topFilterData, bottomFilterData } = await this.queryFilterData(params)
|
const { topFilterData, bottomFilterData } = await this.queryFilterData(params)
|
||||||
@@ -156,7 +146,6 @@ export default {
|
|||||||
let topFilterParams = { ...params, ...this.pageObjLeftTop }
|
let topFilterParams = { ...params, ...this.pageObjLeftTop }
|
||||||
let bottomFilterParams = { ...params, ...this.pageObjLeftBottom }
|
let bottomFilterParams = { ...params, ...this.pageObjLeftBottom }
|
||||||
const keys = Object.keys(this.filterObj)
|
const keys = Object.keys(this.filterObj)
|
||||||
let topLevel = 1 // 左上过滤条件默认是tree的第一层
|
|
||||||
if (!this.$_.isEmpty(keys)) {
|
if (!this.$_.isEmpty(keys)) {
|
||||||
let hasTopColumn = false
|
let hasTopColumn = false
|
||||||
let hasBottomColumn = false
|
let hasBottomColumn = false
|
||||||
@@ -169,14 +158,6 @@ export default {
|
|||||||
topFilterParams = { ...topFilterParams, column: key }
|
topFilterParams = { ...topFilterParams, column: key }
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case entityFilterType.ip.region:
|
|
||||||
case entityFilterType.domain.categoryName:
|
|
||||||
case entityFilterType.app.appSubcategory: {
|
|
||||||
topLevel = 2
|
|
||||||
hasTopColumn = true
|
|
||||||
topFilterParams = { ...topFilterParams, column: key }
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case entityFilterType.ip.asn:
|
case entityFilterType.ip.asn:
|
||||||
case entityFilterType.domain.reputationLevel:
|
case entityFilterType.domain.reputationLevel:
|
||||||
case entityFilterType.app.appRisk: {
|
case entityFilterType.app.appRisk: {
|
||||||
@@ -203,17 +184,17 @@ export default {
|
|||||||
let bottomFilterData = { data: bottomFilterListData, hasnotMore: bottomFilterListData.length < 10, column: bottomFilterParams.column }
|
let bottomFilterData = { data: bottomFilterListData, hasnotMore: bottomFilterListData.length < 10, column: bottomFilterParams.column }
|
||||||
switch (this.from) {
|
switch (this.from) {
|
||||||
case 'ip': {
|
case 'ip': {
|
||||||
topFilterData = { ...topFilterData, icon: 'cn-icon cn-icon-country', title: this.$t('entities.countryOrRegion'), leaf: topLevel === 2 }
|
topFilterData = { ...topFilterData, icon: 'cn-icon cn-icon-country', title: this.$t('entities.countryOrRegion') }
|
||||||
bottomFilterData = { ...bottomFilterData, icon: 'cn-icon cn-icon-cloud', title: this.$t('entities.asn') }
|
bottomFilterData = { ...bottomFilterData, icon: 'cn-icon cn-icon-cloud', title: this.$t('entities.asn') }
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'domain': {
|
case 'domain': {
|
||||||
topFilterData = { ...topFilterData, icon: 'cn-icon cn-icon-category', title: this.$t('entities.groupAndName'), leaf: topLevel === 2 }
|
topFilterData = { ...topFilterData, icon: 'cn-icon cn-icon-category', title: this.$t('entities.groupAndName') }
|
||||||
bottomFilterData = { ...bottomFilterData, icon: 'cn-icon cn-icon-risk', title: this.$t('entities.creditLevel') }
|
bottomFilterData = { ...bottomFilterData, icon: 'cn-icon cn-icon-risk', title: this.$t('entities.creditLevel') }
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'app': {
|
case 'app': {
|
||||||
topFilterData = { ...topFilterData, icon: 'cn-icon cn-icon-category', title: this.$t('entities.categoryAndSub'), leaf: topLevel === 2 }
|
topFilterData = { ...topFilterData, icon: 'cn-icon cn-icon-category', title: this.$t('entities.categoryAndSub') }
|
||||||
bottomFilterData = { ...bottomFilterData, icon: 'cn-icon cn-icon-risk', title: this.$t('entities.riskLevel') }
|
bottomFilterData = { ...bottomFilterData, icon: 'cn-icon cn-icon-risk', title: this.$t('entities.riskLevel') }
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -222,7 +203,7 @@ export default {
|
|||||||
return { topFilterData, bottomFilterData }
|
return { topFilterData, bottomFilterData }
|
||||||
},
|
},
|
||||||
getDefaultTopColumn (from) {
|
getDefaultTopColumn (from) {
|
||||||
let column = ''
|
let column
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case 'ip': {
|
case 'ip': {
|
||||||
column = entityFilterType.ip.country
|
column = entityFilterType.ip.country
|
||||||
@@ -260,57 +241,85 @@ export default {
|
|||||||
return column
|
return column
|
||||||
},
|
},
|
||||||
async select (data, node, index, column) {
|
async select (data, node, index, column) {
|
||||||
this.filterObj[column] = data.name
|
if (index === 0) { // 上部过滤
|
||||||
|
if (node.level === 1) {
|
||||||
|
const columns = { ...this.filterObj, [column]: data.name }
|
||||||
|
// 清除二级条件
|
||||||
|
delete columns[entityFilterType.ip.region]
|
||||||
|
delete columns[entityFilterType.domain.categoryName]
|
||||||
|
delete columns[entityFilterType.app.appSubcategory]
|
||||||
|
this.filterObj = columns
|
||||||
|
} else if (node.level === 2) {
|
||||||
|
const columns = { ...this.filterObj, [column]: data.parentName }
|
||||||
|
// 清除一级条件
|
||||||
|
let childColumn
|
||||||
|
switch (column) {
|
||||||
|
case entityFilterType.ip.country: {
|
||||||
|
childColumn = entityFilterType.ip.region
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case entityFilterType.domain.categoryGroup: {
|
||||||
|
childColumn = entityFilterType.domain.categoryName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case entityFilterType.app.appCategory: {
|
||||||
|
childColumn = entityFilterType.app.appSubcategory
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: break
|
||||||
|
}
|
||||||
|
columns[childColumn] = data.name
|
||||||
|
this.filterObj = columns
|
||||||
|
}
|
||||||
|
} else if (index === 1) { // 下部过滤
|
||||||
|
this.filterObj[column] = data.name
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async loadLevel2FilterData (node, parentColumn) {
|
async loadLevel2FilterData (node, parentColumn) {
|
||||||
let column
|
if (parentColumn) {
|
||||||
switch (parentColumn) {
|
const where = {}
|
||||||
case entityFilterType.ip.country: {
|
where[parentColumn] = node.data.name
|
||||||
column = entityFilterType.ip.region
|
let column
|
||||||
break
|
switch (parentColumn) {
|
||||||
|
case entityFilterType.ip.country: {
|
||||||
|
column = entityFilterType.ip.region
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case entityFilterType.domain.categoryGroup: {
|
||||||
|
column = entityFilterType.domain.categoryName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case entityFilterType.app.appCategory: {
|
||||||
|
column = entityFilterType.app.appSubcategory
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: break
|
||||||
}
|
}
|
||||||
case entityFilterType.domain.categoryGroup: {
|
const params = {
|
||||||
column = entityFilterType.domain.categoryName
|
q: this.doubleQuotationToSingle(this.searchContent),
|
||||||
break
|
from: this.from,
|
||||||
|
pageNo: 1,
|
||||||
|
where,
|
||||||
|
column
|
||||||
}
|
}
|
||||||
case entityFilterType.app.appCategory: {
|
const result = await getEntityFilter(params)
|
||||||
column = entityFilterType.app.appSubcategory
|
return result.map(r => ({ ...r, leaf: true, parentName: node.data.name }))
|
||||||
break
|
} else {
|
||||||
}
|
return []
|
||||||
default: break
|
|
||||||
}
|
}
|
||||||
const params = {
|
|
||||||
q: this.searchContent,
|
|
||||||
from: this.from,
|
|
||||||
pageSize: -1,
|
|
||||||
pageNo: 1,
|
|
||||||
column
|
|
||||||
}
|
|
||||||
return await getEntityFilter(params)
|
|
||||||
},
|
|
||||||
pageSizeRight (val) {
|
|
||||||
this.pageObjRight.pageSize = val
|
|
||||||
},
|
},
|
||||||
pageNoRight (val) {
|
pageNoRight (val) {
|
||||||
|
console.info(val)
|
||||||
this.pageObjRight.pageNo = val
|
this.pageObjRight.pageNo = val
|
||||||
|
this.search()
|
||||||
},
|
},
|
||||||
loadFilter (node, resolve, filterType, key, parentKey) {
|
// 双引号转为单引号
|
||||||
if (node.level === 0) {
|
doubleQuotationToSingle (content) {
|
||||||
resolve(node.data)
|
return content.replace(/\"/g, "'")
|
||||||
} else {
|
|
||||||
const param = { column: key, from: filterType, q: this.searchContent }
|
|
||||||
const req = getEntityFilter(param)
|
|
||||||
if (req) {
|
|
||||||
req.then(res => {
|
|
||||||
res = res.map(r => {
|
|
||||||
return { ...r, leaf: true }
|
|
||||||
})
|
|
||||||
resolve(res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
entityDetail (entity, tabs) {
|
entityDetail (entity, tabs) {
|
||||||
|
const entityName = entity.domain || entity.clientIP || entity.serverIP || entity.appId
|
||||||
|
this.$store.commit('setEntityName', entityName)
|
||||||
this.typeName = `${this.from.toLowerCase()}EntityDetail`
|
this.typeName = `${this.from.toLowerCase()}EntityDetail`
|
||||||
this.currentEntity = entity
|
this.currentEntity = entity
|
||||||
this.panelTabs = tabs
|
this.panelTabs = tabs
|
||||||
@@ -375,7 +384,10 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const searchParams = this.$_.cloneDeep(this.searchParams)
|
const searchParams = this.$_.cloneDeep(this.searchParams)
|
||||||
Object.keys(paramsObj).forEach(key => {
|
const newSearchParams = []
|
||||||
|
const keys = Object.keys(paramsObj)
|
||||||
|
keys.forEach(key => {
|
||||||
|
newSearchParams.push({ name: key, value: paramsObj[key] })
|
||||||
let containKey = false
|
let containKey = false
|
||||||
searchParams.forEach(item => {
|
searchParams.forEach(item => {
|
||||||
if (item.name === key) {
|
if (item.name === key) {
|
||||||
@@ -391,7 +403,9 @@ export default {
|
|||||||
searchParams.push({ name: key, value: paramsObj[key] })
|
searchParams.push({ name: key, value: paramsObj[key] })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if (change) {
|
if (newSearchParams.length !== searchParams.length) {
|
||||||
|
this.searchParams = newSearchParams
|
||||||
|
} else if (change) {
|
||||||
this.searchParams = searchParams
|
this.searchParams = searchParams
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -436,17 +450,28 @@ export default {
|
|||||||
this.search()
|
this.search()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
showDetail (n) {
|
||||||
|
this.$store.commit('showEntityTypeSelector', !n)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
from () {
|
||||||
|
return this.$store.getters.from
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async mounted () {
|
async mounted () {
|
||||||
|
this.$store.commit('showEntityTypeSelector', true)
|
||||||
this.searchParams = []
|
this.searchParams = []
|
||||||
},
|
},
|
||||||
setup () {
|
setup () {
|
||||||
const from = ref(Object.keys(entityType)[0])
|
|
||||||
return {
|
return {
|
||||||
entityType, // 所有entity类型,用于header下拉框选择
|
entityType // 所有entity类型,用于header下拉框选择
|
||||||
from // 当前entity类型,ip/domain/app
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
beforeUnmount () {
|
||||||
|
this.$store.commit('showEntityTypeSelector', false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user