CN-1150: 实体列表接口对接
This commit is contained in:
@@ -10,10 +10,9 @@
|
|||||||
right: 10px;
|
right: 10px;
|
||||||
|
|
||||||
.search__suffix {
|
.search__suffix {
|
||||||
margin-left: 8px; // 新版实体列表改版,后续记得解开
|
// margin-left: 8px;
|
||||||
|
|
||||||
.cn-icon-search-advance, .cn-icon-search-normal {
|
.cn-icon-search-advance, .cn-icon-search-normal, .cn-icon-filter {
|
||||||
//.cn-icon-search-advance, .cn-icon-search-normal, .cn-icon-filter {
|
|
||||||
color: #A6AAAE;
|
color: #A6AAAE;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,3 +222,10 @@
|
|||||||
padding: 0 4px;
|
padding: 0 4px;
|
||||||
//color: white;
|
//color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.performance-event-remark {
|
||||||
|
font-family: NotoSansSChineseRegular;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #353636;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,104 +1,100 @@
|
|||||||
.entity-filter-case {
|
.entity-filter-case {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 280px;
|
width: 320px;
|
||||||
margin-right: 10px;
|
margin-right: 20px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
border: 1px solid rgba(226, 229, 236, 1) !important;
|
||||||
|
border-radius: 4px !important;
|
||||||
|
|
||||||
.filter-case__header {
|
.filter-case__header {
|
||||||
background-color: #E1E6ED;
|
padding-left: 8px;
|
||||||
margin-bottom: 10px;
|
height: 36px;
|
||||||
padding-left: 8px;
|
line-height: 36px;
|
||||||
height: 36px;
|
color: #666;
|
||||||
line-height: 36px;
|
|
||||||
color: #666;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.entity-filter {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border: 1px solid #E7EAED;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
background-color: white;
|
|
||||||
|
|
||||||
.filter__header {
|
|
||||||
height: 46px;
|
|
||||||
margin: 0 15px;
|
|
||||||
line-height: 46px;
|
|
||||||
border-bottom: 1px solid #EFF2F5;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #333;
|
background: #F7F7F7;
|
||||||
|
box-shadow: 0 1px 0 0 rgba(226,229,236,1);
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
}
|
}
|
||||||
.filter__body {
|
|
||||||
padding: 11px 0 21px 0;
|
.filter__header {
|
||||||
.filter__row {
|
height: 46px;
|
||||||
padding: 0 15px;
|
line-height: 46px;
|
||||||
|
margin: 0 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #353636;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter__body {
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
margin: 0 20px;
|
||||||
|
|
||||||
|
.filter-hr {
|
||||||
|
width: calc(100% + 20px);
|
||||||
|
margin-left: -10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
height: 1px;
|
||||||
|
background: #EFF2F5;
|
||||||
|
//background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter__body-item {
|
||||||
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.filter__body-item-left {
|
||||||
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
font-size: 14px;
|
||||||
transition: all linear .2s;
|
color: #353636;
|
||||||
.filter__row-popover {
|
font-weight: 400;
|
||||||
display: flex;
|
|
||||||
line-height: 26px;
|
.filter-country-flag {
|
||||||
|
width: 18px;
|
||||||
|
height: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover, &.filter__row--active {
|
.filter__body-item-left-index {
|
||||||
background-color: #F3F7FA;
|
width: 16px;
|
||||||
}
|
height: 16px;
|
||||||
.row__label {
|
|
||||||
font-size: 14px;
|
|
||||||
flex: 8;
|
|
||||||
display: flex;
|
|
||||||
i {
|
|
||||||
color: #8FA1BE;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
padding-left: 6px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.row__value {
|
|
||||||
color: #666;
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex: 1;
|
background: #EFF2F5;
|
||||||
.chart__loading img {
|
border-radius: 2px;
|
||||||
left: unset;
|
margin-right: 6px;
|
||||||
right: 0;
|
font-family: NotoSansHans-Black;
|
||||||
}
|
font-size: 9px;
|
||||||
}
|
color: #96A2B0;
|
||||||
}
|
font-weight: 900;
|
||||||
}
|
display: flex;
|
||||||
}
|
align-items: center;
|
||||||
}
|
justify-content: center;
|
||||||
.filter__row-popover {
|
|
||||||
.pop-title {
|
|
||||||
i {
|
|
||||||
margin-right: 6px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.entity-pop-custom {
|
|
||||||
.filter-top-box {
|
|
||||||
.chart__loading {
|
|
||||||
height: calc(100% - 65px);
|
|
||||||
top: 64px;
|
|
||||||
}
|
|
||||||
.top-table-percent{
|
|
||||||
display:grid;
|
|
||||||
grid-template-columns: 50% auto;
|
|
||||||
grid-template-rows: 100%;
|
|
||||||
grid-row-gap: 0px;
|
|
||||||
grid-column-gap: 0px;
|
|
||||||
.top-table-progress{
|
|
||||||
align-content: center;
|
|
||||||
padding-top: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.customer-no-border-table {
|
|
||||||
.el-table__body-wrapper {
|
|
||||||
height: calc(100% - 36px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filter__body-item-left-label {
|
||||||
|
max-width: 180px;
|
||||||
|
font-family: NotoSansSChineseRegular;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #353636;
|
||||||
|
font-weight: 400;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter__body-item-right {
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-family: NotoSansSChineseRegular;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #717171;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
transition: all .2s;
|
transition: all .2s;
|
||||||
//border: 1px solid #E2E5EC; 新版实体列表改版,后续记得解开
|
border: 1px solid #E2E5EC;
|
||||||
|
|
||||||
&:hover .cn-entity__header .header__content {
|
&:hover .cn-entity__header .header__content {
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,10 @@
|
|||||||
&:last-of-type {
|
&:last-of-type {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-popper {
|
||||||
|
min-width: 90px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.row__content-accept {
|
.row__content-accept {
|
||||||
margin-left: 39px;
|
margin-left: 39px;
|
||||||
@@ -187,6 +191,12 @@
|
|||||||
color: #666666;
|
color: #666666;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overview__row-related {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.overview__content.domain__content {
|
.overview__content.domain__content {
|
||||||
@@ -306,3 +316,8 @@
|
|||||||
.margin-l-140 {
|
.margin-l-140 {
|
||||||
margin-left: 140px;
|
margin-left: 140px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.line-center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.entity-list {
|
.entity-list {
|
||||||
width: calc(100% - 290px);
|
width: 100%;
|
||||||
height: calc(100% - 42px);
|
height: calc(100% - 42px);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
.cn-entity--list {
|
.cn-entity--list {
|
||||||
display: flex;
|
display: flex;
|
||||||
//border: 1px #E2E5EC solid;
|
border: 1px #E2E5EC solid;
|
||||||
//margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
//border-radius: 4px;
|
border-radius: 4px;
|
||||||
// 新版实体列表改版,后续记得解开
|
|
||||||
|
|
||||||
.cn-entity__collapse {
|
.cn-entity__collapse {
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
@@ -13,8 +12,8 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
background-color: #F3F7FA;
|
background-color: #F3F7FA;
|
||||||
//border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
// 新版实体列表改版,后续记得解开
|
|
||||||
span {
|
span {
|
||||||
transform: rotate(0);
|
transform: rotate(0);
|
||||||
transition: all linear .2s;
|
transition: all linear .2s;
|
||||||
@@ -41,12 +40,12 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
//align-content: center;
|
align-content: center;
|
||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
//border-radius: 0 4px 4px 0;
|
border-radius: 0 4px 4px 0;
|
||||||
// 新版实体列表改版,后续记得解开
|
|
||||||
.cn-entity__icon {
|
.cn-entity__icon {
|
||||||
margin-left: 26px;
|
margin-left: 26px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
@@ -77,13 +76,12 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding-bottom: 3px;
|
padding-bottom: 3px;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
//.cn-entity__header-title {
|
.cn-entity__header-title {
|
||||||
// margin-right: 10px;
|
margin-right: 10px;
|
||||||
//}
|
}
|
||||||
//.cn-entity__header-tag {
|
.cn-entity__header-tag {
|
||||||
//
|
|
||||||
//}
|
}
|
||||||
// 新版实体列表改版,后续记得解开
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cn-entity__body {
|
.cn-entity__body {
|
||||||
@@ -161,27 +159,21 @@
|
|||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//.show-detail {
|
.row-item-label {
|
||||||
// flex-shrink: 0;
|
font-family: NotoSansSChineseRegular;
|
||||||
// padding: 0 30px;
|
font-size: 14px;
|
||||||
// font-size: 12px;
|
color: #717171;
|
||||||
// color: #3976CB;
|
font-weight: 400;
|
||||||
// //color: #2C72C6;
|
}
|
||||||
// //font-weight: 400;
|
|
||||||
// //margin-top: -17px;
|
.row-item-value {
|
||||||
// // 新版实体列表改版,后续记得解开
|
font-family: NotoSansSChineseRegular;
|
||||||
//
|
font-size: 14px;
|
||||||
// &:hover {
|
color: #353636;
|
||||||
// cursor: pointer;
|
font-weight: 400;
|
||||||
// }
|
}
|
||||||
//
|
}
|
||||||
// //i {
|
|
||||||
// // font-size: 12px;
|
|
||||||
// // margin-right: 5px;
|
|
||||||
// //}
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,13 +75,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tag-search__add" @click="addCondition">{{$t('entities.advancedSearch.add')}}</div>
|
<div class="tag-search__add" @click="addCondition">{{$t('entities.advancedSearch.add')}}</div>
|
||||||
<div class="search__suffixes search__suffixes--tag-mode">
|
<div class="search__suffixes search__suffixes--tag-mode">
|
||||||
<div class="search__suffix" @click="changeMode">
|
<div class="search__suffix" style="margin-right: 12px" @click="changeMode">
|
||||||
<!-- 新版实体列表改版,后续记得解开-->
|
|
||||||
<!-- <div class="search__suffix" style="margin-right: 12px" @click="changeMode">-->
|
|
||||||
<i class="cn-icon cn-icon-search-normal"></i>
|
<i class="cn-icon cn-icon-search-normal"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="search__suffix" @click="search">
|
<div class="search__suffix new-search__suffix" @click="search">
|
||||||
<!-- <div class="search__suffix new-search__suffix" @click="search">-->
|
|
||||||
<i class="el-icon-search"></i>
|
<i class="el-icon-search"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -440,20 +437,19 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!--// 新版实体列表改版,后续记得解开-->
|
<style lang="scss">
|
||||||
<!--<style lang="scss">-->
|
.new-search__suffix {
|
||||||
<!--.new-search__suffix {-->
|
width: 41px;
|
||||||
<!-- width: 41px;-->
|
height: 41px;
|
||||||
<!-- height: 41px;-->
|
line-height: 41px;
|
||||||
<!-- line-height: 41px;-->
|
background: #38ACD2;
|
||||||
<!-- background: #38ACD2;-->
|
text-align: center;
|
||||||
<!-- text-align: center;-->
|
margin-top: -10px;
|
||||||
<!-- margin-top: -10px;-->
|
margin-right: -10px;
|
||||||
<!-- margin-right: -10px;-->
|
|
||||||
|
|
||||||
<!-- .el-icon-search {-->
|
.el-icon-search {
|
||||||
<!-- color: #fff !important;-->
|
color: #fff !important;
|
||||||
<!-- margin-top: 9px !important;-->
|
margin-top: 9px !important;
|
||||||
<!-- }-->
|
}
|
||||||
<!--}-->
|
}
|
||||||
<!--</style>-->
|
</style>
|
||||||
|
|||||||
@@ -4,13 +4,12 @@
|
|||||||
></textarea>
|
></textarea>
|
||||||
<div class="search__suffixes search__suffixes--text-mode">
|
<div class="search__suffixes search__suffixes--text-mode">
|
||||||
<div class="search__suffix" @click="changeMode">
|
<div class="search__suffix" @click="changeMode">
|
||||||
<i class="cn-icon cn-icon-search-advance"></i>
|
<i class="cn-icon cn-icon-filter"></i>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="search__suffix-close" @click="cleanParams">-->
|
<div class="search__suffix-close" @click="cleanParams">
|
||||||
<!-- <i class="el-icon-error"></i>-->
|
<i class="el-icon-error"></i>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- <div class="search__suffix new-search__suffix" @click="search">-->
|
<div class="search__suffix new-search__suffix" @click="search">
|
||||||
<div class="search__suffix" @click="search">
|
|
||||||
<i class="el-icon-search"></i>
|
<i class="el-icon-search"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,9 +42,9 @@ export default {
|
|||||||
},
|
},
|
||||||
emits: ['changeMode', 'search'],
|
emits: ['changeMode', 'search'],
|
||||||
methods: {
|
methods: {
|
||||||
// cleanParams () {
|
cleanParams () {
|
||||||
// toRaw(this.codeMirror).setValue('')
|
toRaw(this.codeMirror).setValue('')
|
||||||
// },
|
},
|
||||||
initCodeMirror () {
|
initCodeMirror () {
|
||||||
this.codeMirror = CodeMirror.fromTextArea(this.$refs.textSearch, {
|
this.codeMirror = CodeMirror.fromTextArea(this.$refs.textSearch, {
|
||||||
mode: {
|
mode: {
|
||||||
@@ -189,28 +188,28 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!--<style lang="scss">-->
|
<style lang="scss">
|
||||||
<!--.search__suffix-close {-->
|
.search__suffix-close {
|
||||||
<!-- .el-icon-error {-->
|
.el-icon-error {
|
||||||
<!-- font-size: 17px;-->
|
font-size: 17px;
|
||||||
<!-- color: #C4C4C4;-->
|
color: #C4C4C4;
|
||||||
<!-- margin: 0 12px;-->
|
margin: 0 12px;
|
||||||
<!-- cursor: pointer;-->
|
cursor: pointer;
|
||||||
<!-- }-->
|
}
|
||||||
<!--}-->
|
}
|
||||||
|
|
||||||
<!--.new-search__suffix {-->
|
.new-search__suffix {
|
||||||
<!-- width: 41px;-->
|
width: 41px;
|
||||||
<!-- height: 41px;-->
|
height: 41px;
|
||||||
<!-- line-height: 41px;-->
|
line-height: 41px;
|
||||||
<!-- background: #38ACD2;-->
|
background: #38ACD2;
|
||||||
<!-- text-align: center;-->
|
text-align: center;
|
||||||
<!-- margin-top: -10px;-->
|
margin-top: -10px;
|
||||||
<!-- margin-right: -10px;-->
|
margin-right: -10px;
|
||||||
|
|
||||||
<!-- .el-icon-search {-->
|
.el-icon-search {
|
||||||
<!-- color: #fff !important;-->
|
color: #fff !important;
|
||||||
<!-- margin-top: 9px !important;-->
|
margin-top: 9px !important;
|
||||||
<!-- }-->
|
}
|
||||||
<!--}-->
|
}
|
||||||
<!--</style>-->
|
</style>
|
||||||
|
|||||||
@@ -20,10 +20,7 @@ export default {
|
|||||||
entityDetectionStyle () {
|
entityDetectionStyle () {
|
||||||
const route = this.$route.name !== undefined ? this.$route.name : this.$route
|
const route = this.$route.name !== undefined ? this.$route.name : this.$route
|
||||||
if (listScrollPath.indexOf(route.path) > -1) {
|
if (listScrollPath.indexOf(route.path) > -1) {
|
||||||
// 新版实体列表改版,后续记得解开
|
return 'overflow:auto;'
|
||||||
const style = route.path === listScrollPath[0] ? 'overflow:auto;background-color: #EFF2F5;' : 'overflow:auto;'
|
|
||||||
// const style = 'overflow:auto;'
|
|
||||||
return style
|
|
||||||
} else {
|
} else {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,12 @@ export default {
|
|||||||
this.loadingRelationshipOne = true
|
this.loadingRelationshipOne = true
|
||||||
get(relationshipUrlOne, this.getQueryParams()).then(response => {
|
get(relationshipUrlOne, this.getQueryParams()).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
const relationshipDataOne = response.data.result
|
const relationshipDataOne = []
|
||||||
|
if (response.data.result.length > 0) {
|
||||||
|
response.data.result.forEach(item => {
|
||||||
|
relationshipDataOne.push({ value: item, show: true })
|
||||||
|
})
|
||||||
|
}
|
||||||
// 将请求数据 传入方法中
|
// 将请求数据 传入方法中
|
||||||
this.relatedServerWidth(relationshipDataOne, refOne, 1)
|
this.relatedServerWidth(relationshipDataOne, refOne, 1)
|
||||||
}
|
}
|
||||||
@@ -30,7 +35,12 @@ export default {
|
|||||||
this.loadingRelationshipTwo = true
|
this.loadingRelationshipTwo = true
|
||||||
get(relationshipUrlTow, this.getQueryParams()).then(response => {
|
get(relationshipUrlTow, this.getQueryParams()).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
const relationshipDataTwo = response.data.result
|
const relationshipDataTwo = []
|
||||||
|
if (response.data.result.length > 0) {
|
||||||
|
response.data.result.forEach(item => {
|
||||||
|
relationshipDataTwo.push({ value: item, show: true })
|
||||||
|
})
|
||||||
|
}
|
||||||
// 将请求数据 传入方法中
|
// 将请求数据 传入方法中
|
||||||
this.relatedServerWidth(relationshipDataTwo, refTow, 2)
|
this.relatedServerWidth(relationshipDataTwo, refTow, 2)
|
||||||
}
|
}
|
||||||
@@ -45,7 +55,7 @@ export default {
|
|||||||
let flag = true
|
let flag = true
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
// 每条数据的宽度
|
// 每条数据的宽度
|
||||||
const width = getTextRect(item.appName || item.domain || item.ip).width + 67
|
const width = getTextRect(item.value).width + 67
|
||||||
if (width > 67 && width !== 0) {
|
if (width > 67 && width !== 0) {
|
||||||
sum += width
|
sum += width
|
||||||
if (flag && sum >= relatedServerWidth && num === 1) {
|
if (flag && sum >= relatedServerWidth && num === 1) {
|
||||||
|
|||||||
@@ -451,6 +451,300 @@ if (openMock) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/query/list.*`), 'get', function (requestObj) {
|
||||||
|
const result = {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 3,
|
||||||
|
list: [
|
||||||
|
{ entityValue: '192.168.12.34', entityType: 'ip' },
|
||||||
|
{ entityValue: 'gdbzkz.com', entityType: 'domain' },
|
||||||
|
{ entityValue: 'qqvideo', entityType: 'app' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/detail/basic.*`), 'get', function (requestObj) {
|
||||||
|
const entityType = getEntityType(requestObj.url)
|
||||||
|
let result = {}
|
||||||
|
switch (entityType) {
|
||||||
|
case ('domain'): {
|
||||||
|
result = {
|
||||||
|
whois: {
|
||||||
|
registrarName: 'Beijing Baidu Company',
|
||||||
|
registrantOrg: 'Beijing Baidu Netcom Science Technology Co., Ltd.',
|
||||||
|
registrantCountry: 'China',
|
||||||
|
email: '信息已设置隐私保护',
|
||||||
|
createDate: 1685329698,
|
||||||
|
expireDate: 1685329698
|
||||||
|
},
|
||||||
|
icp: {
|
||||||
|
icpSiteLicense: '京ICP证030173号',
|
||||||
|
icpCompanyName: '北京百度网讯科技有限公司',
|
||||||
|
icpCompanyType: '企业'
|
||||||
|
},
|
||||||
|
category: {
|
||||||
|
name: '门户网站',
|
||||||
|
group: '互联网',
|
||||||
|
reputationLevel: 'Trustworthy'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('ip'): {
|
||||||
|
result = {
|
||||||
|
asn: { id: 2, asn: '14061', organization: 'DIGITALOCEAN-ASN - DigitalOcean, LLC, US' },
|
||||||
|
location: {
|
||||||
|
continent: 'North America',
|
||||||
|
country: 'United States',
|
||||||
|
province: 'New York',
|
||||||
|
city: '',
|
||||||
|
lngwgs: '-74.006',
|
||||||
|
latwgs: '40.713',
|
||||||
|
isp: 'dba Omsoft',
|
||||||
|
owner: 'tie net'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('app'): {
|
||||||
|
result = {
|
||||||
|
category: {
|
||||||
|
appName: 'QQ',
|
||||||
|
appId: 333,
|
||||||
|
appCategory: '娱乐',
|
||||||
|
appSubcategory: '聊天',
|
||||||
|
appRisk: '1',
|
||||||
|
appDescription: '聊天社交软件',
|
||||||
|
appLongname: 'Tencent qq',
|
||||||
|
appTechnology: 'socket',
|
||||||
|
appCompany: 'tencent',
|
||||||
|
appCompanyCategory: '互联网'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/detail/kb/intelligence/tag.*`), 'get', function (requestObj) {
|
||||||
|
const entityType = getEntityType(requestObj.url)
|
||||||
|
let result = {}
|
||||||
|
switch (entityType) {
|
||||||
|
case ('domain'): {
|
||||||
|
result = {
|
||||||
|
malware: {
|
||||||
|
threatType: 'command and control',
|
||||||
|
malwareName: '情报攻击',
|
||||||
|
malwareAlias: '攻击'
|
||||||
|
},
|
||||||
|
darkweb: {
|
||||||
|
nodeType: 'mtproxy'
|
||||||
|
},
|
||||||
|
userDefinedTags: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
tagValue: '门户网站'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('ip'): {
|
||||||
|
result = {
|
||||||
|
malware: {
|
||||||
|
threatType: 'command and control',
|
||||||
|
malwareName: 'IcedID',
|
||||||
|
malwareAlias: 'BokBot,IceID'
|
||||||
|
},
|
||||||
|
darkweb: {
|
||||||
|
nodeType: '12p'
|
||||||
|
},
|
||||||
|
psiphon3Ip: {
|
||||||
|
type: 'high',
|
||||||
|
method: 'passive_ml',
|
||||||
|
confidence: 88,
|
||||||
|
confidenceLevel: 'confirmed'
|
||||||
|
},
|
||||||
|
userDefinedTags: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
tagValue: '门户网站'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('app'): {
|
||||||
|
result = {
|
||||||
|
userDefinedTags: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
tagValue: '门户网站'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
tagValue: '新闻软件'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/detail/domain/relate.*`), 'get', function (requestObj) {
|
||||||
|
const relateType = getRelateType(requestObj.url)
|
||||||
|
let result = {}
|
||||||
|
switch (relateType) {
|
||||||
|
case ('ip'): {
|
||||||
|
result = {
|
||||||
|
total: 5,
|
||||||
|
result: ['bittorrent', 'qq_web', 'wechat', 'tencent', 'outlook']
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('app'): {
|
||||||
|
result = {
|
||||||
|
total: 5,
|
||||||
|
result: ['192.107.175.180', '192.107.175.180', '192.107.175.180', '192.107.175.180', '192.107.175.180']
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/detail/ip/relate.*`), 'get', function (requestObj) {
|
||||||
|
const relateType = getRelateType(requestObj.url)
|
||||||
|
let result = {}
|
||||||
|
switch (relateType) {
|
||||||
|
case ('domain'): {
|
||||||
|
result = {
|
||||||
|
total: 5,
|
||||||
|
result: ['bittorrent', 'qq_web', 'wechat', 'tencent', 'outlook']
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('app'): {
|
||||||
|
result = {
|
||||||
|
total: 5,
|
||||||
|
result: ['gdbzkz.com', 'gdbzkz.com', 'gdbzkz.com', 'gdbzkz.com', 'gdbzkz.com']
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/detail/app/relate.*`), 'get', function (requestObj) {
|
||||||
|
const relateType = getRelateType(requestObj.url)
|
||||||
|
let result = {}
|
||||||
|
switch (relateType) {
|
||||||
|
case ('ip'): {
|
||||||
|
result = {
|
||||||
|
total: 5,
|
||||||
|
result: ['gdbzkz.com', 'gdbzkz.com', 'gdbzkz.com', 'gdbzkz.com', 'gdbzkz.com']
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('domain'): {
|
||||||
|
result = {
|
||||||
|
total: 5,
|
||||||
|
result: ['192.107.175.180', '192.107.175.180', '192.107.175.180', '192.107.175.180', '192.107.175.180']
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/detail/traffic/performance.*`), 'get', function (requestObj) {
|
||||||
|
const result = {
|
||||||
|
resultType: 'object',
|
||||||
|
result: {
|
||||||
|
httpResponseLatencyValue: null,
|
||||||
|
httpResponseLatencyP50: null,
|
||||||
|
httpResponseLatencyP90: null,
|
||||||
|
httpResponseLatencyP99: null,
|
||||||
|
sslConLatencyValue: 191,
|
||||||
|
sslConLatencyP50: 137,
|
||||||
|
sslConLatencyP90: 311,
|
||||||
|
sslConLatencyP99: 1610,
|
||||||
|
establishLatencyValue: 42,
|
||||||
|
establishLatencyP50: 33,
|
||||||
|
establishLatencyP90: 54,
|
||||||
|
establishLatencyP99: 177,
|
||||||
|
sequenceGapLossPercentValue: 0.001,
|
||||||
|
sequenceGapLossPercentP50: 0,
|
||||||
|
sequenceGapLossPercentP90: 0.0038,
|
||||||
|
sequenceGapLossPercentP99: 0.0087,
|
||||||
|
pktRetransPercentValue: 0.0124,
|
||||||
|
pktRetransPercentP50: 0.0096,
|
||||||
|
pktRetransPercentP90: 0.0183,
|
||||||
|
pktRetransPercentP99: 0.0769
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/overview/active.*`), 'get', function (requestObj) {
|
||||||
|
const data = { domainCount: 755, ipCount: 8373, appCount: 263 }
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/overview/new.*`), 'get', function (requestObj) {
|
||||||
|
const data = { domainCount: 262, ipCount: 4201, appCount: 43 }
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/overview/total.*`), 'get', function (requestObj) {
|
||||||
|
const data = { domainCount: 7686274, ipCount: 2169957, appCount: 856 }
|
||||||
|
|
||||||
|
return {
|
||||||
|
msg: 'success',
|
||||||
|
code: 200,
|
||||||
|
data: data
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getQuery = (url) => {
|
const getQuery = (url) => {
|
||||||
@@ -467,3 +761,31 @@ const getQuery = (url) => {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getEntityType = (url) => {
|
||||||
|
let entityType = ''
|
||||||
|
if (url.indexOf('/domain?') > -1) {
|
||||||
|
entityType = 'domain'
|
||||||
|
}
|
||||||
|
if (url.indexOf('/ip?') > -1) {
|
||||||
|
entityType = 'ip'
|
||||||
|
}
|
||||||
|
if (url.indexOf('/app?') > -1) {
|
||||||
|
entityType = 'app'
|
||||||
|
}
|
||||||
|
return entityType
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRelateType = (url) => {
|
||||||
|
let entityType = ''
|
||||||
|
if (url.indexOf('/domains?') > -1) {
|
||||||
|
entityType = 'domain'
|
||||||
|
}
|
||||||
|
if (url.indexOf('/ips?') > -1) {
|
||||||
|
entityType = 'ip'
|
||||||
|
}
|
||||||
|
if (url.indexOf('/apps?') > -1) {
|
||||||
|
entityType = 'app'
|
||||||
|
}
|
||||||
|
return entityType
|
||||||
|
}
|
||||||
|
|||||||
@@ -262,7 +262,47 @@ export const api = {
|
|||||||
ipRelatedDomain: apiVersion + '/entity/graph/relation/ip/relate/domains',
|
ipRelatedDomain: apiVersion + '/entity/graph/relation/ip/relate/domains',
|
||||||
ipRelatedApp: apiVersion + '/entity/graph/relation/ip/relate/apps',
|
ipRelatedApp: apiVersion + '/entity/graph/relation/ip/relate/apps',
|
||||||
appRelatedIp: apiVersion + '/entity/graph/relation/app/relate/ips',
|
appRelatedIp: apiVersion + '/entity/graph/relation/app/relate/ips',
|
||||||
appRelatedDomain: apiVersion + '/entity/graph/relation/app/relate/domains'
|
appRelatedDomain: apiVersion + '/entity/graph/relation/app/relate/domains',
|
||||||
|
basicInfo: apiVersion + '/entity/graph/relation/basic',
|
||||||
|
tags: apiVersion + '/entity/graph/relation/kb/intelligence/tag'
|
||||||
|
},
|
||||||
|
entityList: {
|
||||||
|
list: apiVersion + '/entity/explorer/query/list', // 实体列表
|
||||||
|
domainBasicInfo: apiVersion + '/entity/explorer/detail/basic/domain', // Domain实体响应结果
|
||||||
|
ipBasicInfo: apiVersion + '/entity/explorer/detail/basic/ip', // ip实体响应
|
||||||
|
appBasicInfo: apiVersion + '/entity/explorer/detail/basic/app', // app实体响应
|
||||||
|
domainTags: apiVersion + '/entity/explorer/detail/kb/intelligence/tag/domain', // Domain实体标签响应结果
|
||||||
|
ipTags: apiVersion + '/entity/explorer/detail/kb/intelligence/tag/ip', // ip实体标签响应结果
|
||||||
|
appTags: apiVersion + '/entity/explorer/detail/kb/intelligence/tag/app', // app实体标签响应结果
|
||||||
|
domainThroughput: apiVersion + '/entity/explorer/detail/traffic/throughput/domain', // 实体流量信息
|
||||||
|
ipThroughput: apiVersion + '/entity/explorer/detail/traffic/throughput/ip', // 实体流量信息
|
||||||
|
appThroughput: apiVersion + '/entity/explorer/detail/traffic/throughput/app', // 实体流量信息
|
||||||
|
domainPerformance: apiVersion + '/entity/explorer/detail/traffic/performance/domain', // domain网络质量
|
||||||
|
ipPerformance: apiVersion + '/entity/explorer/detail/traffic/performance/ip', // ip网络质量
|
||||||
|
appPerformance: apiVersion + '/entity/explorer/detail/traffic/performance/app', // app网络质量
|
||||||
|
domainRelatedApp: apiVersion + '/entity/explorer/detail/domain/relate/apps', // 域名相关app
|
||||||
|
domainRelatedIp: apiVersion + '/entity/explorer/detail/domain/relate/ips', // 域名相关ip
|
||||||
|
appRelatedDomain: apiVersion + '/entity/explorer/detail/app/relate/domains', // app相关域名
|
||||||
|
appRelatedIp: apiVersion + '/entity/explorer/detail/app/relate/ips', // app相关ip
|
||||||
|
ipRelatedApp: apiVersion + '/entity/explorer/detail/ip/relate/apps', // ip相关app
|
||||||
|
ipRelatedDomain: apiVersion + '/entity/explorer/detail/ip/relate/domains', // ip相关域名
|
||||||
|
ipRelatedPort: apiVersion + '/entity/explorer/detail/ip/relate/ports', // ip开放端口
|
||||||
|
domainTrafficMap: apiVersion + '/entity/explorer/detail/traffic/map/domain', // domain流量地图
|
||||||
|
ipTrafficMap: apiVersion + '/entity/explorer/detail/traffic/map/ip', // ip流量地图
|
||||||
|
appTrafficMap: apiVersion + '/entity/explorer/detail/traffic/map/app', // app流量地图
|
||||||
|
summaryCount: apiVersion + '/entity/explorer/query/summaryCount', // 实体基数统计
|
||||||
|
aggCountry: apiVersion + '/entity/explorer/top/aggCountry', // 国家实体基数统计
|
||||||
|
aggAsn: apiVersion + '/entity/explorer/top/aggAsn', // ASN实体基数统计
|
||||||
|
aggCity: apiVersion + '/entity/explorer/top/aggCity', // 城市实体基数统计
|
||||||
|
domainSecurity: apiVersion + '/entity/explorer/detail/event/security/domain', // domain安全事件详情
|
||||||
|
ipSecurity: apiVersion + '/entity/explorer/detail/event/security/domain', // ip安全事件详情
|
||||||
|
appSecurity: apiVersion + '/entity/explorer/detail/event/security/domain', // app安全事件详情
|
||||||
|
domainEventPerformance: apiVersion + '/entity/explorer/detail/event/performance/domain', // domain服务质量详情
|
||||||
|
ipEventPerformance: apiVersion + '/entity/explorer/detail/event/performance/ip', // ip服务质量详情
|
||||||
|
appEventPerformance: apiVersion + '/entity/explorer/detail/event/performance/app', // app服务质量详情
|
||||||
|
entityActive: apiVersion + '/entity/explorer/overview/active', // entity首页active数据概览
|
||||||
|
entityNew: apiVersion + '/entity/explorer/overview/new', // entity首页new数据概览
|
||||||
|
entityTotal: apiVersion + '/entity/explorer/overview/total' // entity首页total数据概览
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ export const columnList = [
|
|||||||
label: 'IP.Address'
|
label: 'IP.Address'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ip_location_country',
|
name: 'country',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
label: 'IP.Country'
|
label: 'IP.Country'
|
||||||
},
|
},
|
||||||
@@ -292,12 +292,12 @@ export const columnList = [
|
|||||||
label: 'IP.Province'
|
label: 'IP.Province'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ip_location_city',
|
name: 'region',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
label: 'IP.City'
|
label: 'IP.City'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ip_asn',
|
name: 'asn',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
label: 'IP.ASN'
|
label: 'IP.ASN'
|
||||||
},
|
},
|
||||||
@@ -367,7 +367,7 @@ export const columnList = [
|
|||||||
label: 'Domain.Whois address'
|
label: 'Domain.Whois address'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'domain_whois_city',
|
name: 'region',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
label: 'Domain.Whois city'
|
label: 'Domain.Whois city'
|
||||||
},
|
},
|
||||||
@@ -377,7 +377,7 @@ export const columnList = [
|
|||||||
label: 'Domain.Whois state'
|
label: 'Domain.Whois state'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'domain_whois_country',
|
name: 'country',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
label: 'Domain.Whois country'
|
label: 'Domain.Whois country'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,60 +3,60 @@
|
|||||||
class="entity-explorer"
|
class="entity-explorer"
|
||||||
:class="{'entity-explorer--show-list': showList}">
|
:class="{'entity-explorer--show-list': showList}">
|
||||||
<!-- 顶部工具栏,在列表页显示 -->
|
<!-- 顶部工具栏,在列表页显示 -->
|
||||||
<!-- <div class="explorer-top-tools explorer-top-tools-new" v-show="showList">-->
|
<div class="explorer-top-tools explorer-top-tools-new" style="margin: 2px 0;" v-show="showList">
|
||||||
<!-- <div class="explorer-detection-top-tools">-->
|
<div class="explorer-detection-top-tools">
|
||||||
<!-- <div class="explorer-top-tools-title">{{$t('network.entity')}}</div>-->
|
<div class="explorer-top-tools-title" style="padding: 0;margin-left: -10px;">{{$t('network.entity')}}</div>
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div class="explorer-top-tools">-->
|
|
||||||
<!-- <DateTimeRange :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" :date-range="timeFilter.dateRangeValue" ref="dateTimeRange" @change="reload"/>-->
|
|
||||||
<!-- <TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>-->
|
|
||||||
<!-- <el-button-group size="mini">-->
|
|
||||||
<!-- <el-button size="mini" @click="listMode = 'list'" :class="{'active': listMode === 'list'}"><i class="cn-icon cn-icon-list"></i></el-button>-->
|
|
||||||
<!-- <el-button size="mini" @click="listMode = 'block'" :class="{'active': listMode === 'block'}"><i class="cn-icon cn-icon-blocks"></i></el-button>-->
|
|
||||||
<!-- </el-button-group>-->
|
|
||||||
<div class="explorer-top-tools" v-show="showList">
|
|
||||||
<DateTimeRange :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" :date-range="timeFilter.dateRangeValue" ref="dateTimeRange" @change="reload"/>
|
|
||||||
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
|
|
||||||
<el-button-group size="mini">
|
|
||||||
<el-button size="mini" @click="setListMode('list')" :class="{'active': listMode === 'list'}"><i class="cn-icon cn-icon-list"></i></el-button>
|
|
||||||
<el-button size="mini" @click="setListMode('block')" :class="{'active': listMode === 'block'}"><i class="cn-icon cn-icon-blocks"></i></el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- 搜索组件 -->
|
<!-- 搜索组件 -->
|
||||||
<explorer-search
|
<explorer-search
|
||||||
|
v-if="!showList"
|
||||||
ref="search"
|
ref="search"
|
||||||
:class="{'explorer-search--show-list': showList}"
|
:class="{'explorer-search--show-list': showList}"
|
||||||
:show-list="showList"
|
:show-list="showList"
|
||||||
@search="search"
|
@search="search"
|
||||||
></explorer-search>
|
></explorer-search>
|
||||||
|
|
||||||
<!--todo静态数据,之后记得修改-->
|
|
||||||
<!-- <div class="explorer-result" v-if="showList">-->
|
|
||||||
<!-- 8,866 results,IP 2666,Domain 3200,APP 3000-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- 内容区 -->
|
<!-- 内容区 -->
|
||||||
<div class="explorer-container" v-if="showList" style="height: calc(100% - 20px); flex-direction: column">
|
<div v-if="showList" style="display: flex;flex-direction: row;">
|
||||||
<div style="display: flex; height: auto;">
|
<entity-filter
|
||||||
<entity-filter
|
:filter-data="newFilterData"
|
||||||
:filter-data="filterData"
|
:loading-left="loadingLeft"
|
||||||
:loading-left="loadingLeft"
|
:q="q"
|
||||||
:q="q"
|
:time-filter="timeFilter"
|
||||||
:time-filter="timeFilter"
|
@filter="filter"
|
||||||
@filter="filter"
|
></entity-filter>
|
||||||
></entity-filter>
|
<div class="explorer-container" style="height: calc(100% - 62px);flex-direction: column;width: 100%;">
|
||||||
<entity-list
|
<explorer-search
|
||||||
:list-data="listData"
|
ref="search"
|
||||||
:list-mode="listMode"
|
:class="{'explorer-search--show-list': showList}"
|
||||||
:pageObj="pageObj"
|
:show-list="showList"
|
||||||
:time-filter="timeFilter"
|
@search="search"
|
||||||
@pageSize="pageSize"
|
></explorer-search>
|
||||||
@pageNo="pageNo"
|
|
||||||
:loading="listLoading"
|
<div style="display: flex;flex-direction: column;height: calc(100% - 42px);">
|
||||||
></entity-list>
|
<div class="explorer-result" v-if="showList">
|
||||||
|
<loading :loading="loadingCount"></loading>
|
||||||
|
<span>{{ summaryCount.total }}</span>results,IP
|
||||||
|
<span>{{ summaryCount.ipCount }}</span>,Domain
|
||||||
|
<span>{{ summaryCount.fqdnCount }}</span>,APP
|
||||||
|
<span>{{ summaryCount.appCount }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<entity-list
|
||||||
|
style="width: 100%;"
|
||||||
|
:list-data="listData"
|
||||||
|
:list-mode="listMode"
|
||||||
|
:pageObj="pageObj"
|
||||||
|
:time-filter="timeFilter"
|
||||||
|
@pageSize="pageSize"
|
||||||
|
@pageNo="pageNo"
|
||||||
|
:loading="listLoading"
|
||||||
|
></entity-list>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="explorer-foot" v-else>
|
|
||||||
|
<div class="explorer-foot" v-if="!showList">
|
||||||
<div>
|
<div>
|
||||||
<el-divider direction="vertical"></el-divider>
|
<el-divider direction="vertical"></el-divider>
|
||||||
<div class="entity-overview">
|
<div class="entity-overview">
|
||||||
@@ -150,8 +150,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ExplorerSearch from '@/views/entityExplorer/search/ExplorerSearch'
|
import ExplorerSearch from '@/views/entityExplorer/search/ExplorerSearch'
|
||||||
import DateTimeRange from '@/components/common/TimeRange/DateTimeRange'
|
|
||||||
import TimeRefresh from '@/components/common/TimeRange/TimeRefresh'
|
|
||||||
import EntityFilter from '@/views/entityExplorer/EntityFilter'
|
import EntityFilter from '@/views/entityExplorer/EntityFilter'
|
||||||
import EntityList from '@/views/entityExplorer/entityList/EntityList'
|
import EntityList from '@/views/entityExplorer/entityList/EntityList'
|
||||||
import { entityType, defaultPageSize, riskLevelMapping } from '@/utils/constants'
|
import { entityType, defaultPageSize, riskLevelMapping } from '@/utils/constants'
|
||||||
@@ -172,8 +170,6 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
Loading,
|
Loading,
|
||||||
ExplorerSearch,
|
ExplorerSearch,
|
||||||
DateTimeRange,
|
|
||||||
TimeRefresh,
|
|
||||||
EntityFilter,
|
EntityFilter,
|
||||||
EntityList
|
EntityList
|
||||||
},
|
},
|
||||||
@@ -210,23 +206,15 @@ export default {
|
|||||||
{
|
{
|
||||||
label: this.$t('overall.country'),
|
label: this.$t('overall.country'),
|
||||||
column: 'countryDistinctCount',
|
column: 'countryDistinctCount',
|
||||||
topColumn: 'ip_location_country', // top弹框查询字段
|
topColumn: 'country', // top弹框查询字段
|
||||||
icon: 'cn-icon cn-icon-country',
|
icon: 'cn-icon cn-icon-country',
|
||||||
showTopTen: false,
|
showTopTen: false,
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: this.$t('overall.province'),
|
|
||||||
column: 'provinceDistinctCount',
|
|
||||||
topColumn: 'ip_location_province', // top弹框查询字段
|
|
||||||
icon: 'cn-icon cn-icon-position',
|
|
||||||
showTopTen: false,
|
|
||||||
value: 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: this.$t('overall.city'),
|
label: this.$t('overall.city'),
|
||||||
column: 'cityDistinctCount',
|
column: 'cityDistinctCount',
|
||||||
topColumn: 'ip_location_city', // top弹框查询字段
|
topColumn: 'region', // top弹框查询字段
|
||||||
icon: 'cn-icon cn-icon-city',
|
icon: 'cn-icon cn-icon-city',
|
||||||
showTopTen: false,
|
showTopTen: false,
|
||||||
value: 0
|
value: 0
|
||||||
@@ -234,7 +222,7 @@ export default {
|
|||||||
{
|
{
|
||||||
label: this.$t('entities.asn'),
|
label: this.$t('entities.asn'),
|
||||||
column: 'asnDistinctCount',
|
column: 'asnDistinctCount',
|
||||||
topColumn: 'ip_asn', // top弹框查询字段
|
topColumn: 'asn', // top弹框查询字段
|
||||||
icon: 'cn-icon cn-icon-cloud',
|
icon: 'cn-icon cn-icon-cloud',
|
||||||
showTopTen: false,
|
showTopTen: false,
|
||||||
value: 0
|
value: 0
|
||||||
@@ -346,6 +334,26 @@ export default {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
newFilterData: [
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-registration-country',
|
||||||
|
title: 'Top Countries',
|
||||||
|
totalCount: 0,
|
||||||
|
data: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-city',
|
||||||
|
title: 'Top Cities',
|
||||||
|
totalCount: 0,
|
||||||
|
data: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'cn-icon cn-icon-as',
|
||||||
|
title: 'Top ASNs',
|
||||||
|
totalCount: 0,
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
],
|
||||||
listData: [],
|
listData: [],
|
||||||
q: '',
|
q: '',
|
||||||
metaList: [],
|
metaList: [],
|
||||||
@@ -367,7 +375,14 @@ export default {
|
|||||||
// 实体详情列表页面 左侧筛选条件
|
// 实体详情列表页面 左侧筛选条件
|
||||||
loadingLeft: false,
|
loadingLeft: false,
|
||||||
initFlag: false, // 初始化标志,避免初始化时pageSize和pageNo会调用搜索
|
initFlag: false, // 初始化标志,避免初始化时pageSize和pageNo会调用搜索
|
||||||
timer: null // 初始化标志的延时器,需要销毁
|
timer: null, // 初始化标志的延时器,需要销毁
|
||||||
|
summaryCount: {
|
||||||
|
total: 0,
|
||||||
|
fqdnCount: 0,
|
||||||
|
ipCount: 0,
|
||||||
|
appCount: 0
|
||||||
|
},
|
||||||
|
loadingCount: false // 实体基数统计的loading
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -420,6 +435,12 @@ export default {
|
|||||||
return result
|
return result
|
||||||
},
|
},
|
||||||
search (param) {
|
search (param) {
|
||||||
|
// todo 下版本08版本删除 ---- start
|
||||||
|
if (param && param.q.indexOf("QUERY('") > -1) {
|
||||||
|
this.$message.error(this.$t('overall.versionNotSupportThisFormat'))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// 下版本08版本删除 ---- end
|
||||||
let q
|
let q
|
||||||
let metaList
|
let metaList
|
||||||
if (param) {
|
if (param) {
|
||||||
@@ -489,29 +510,35 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.limitFilterType = false
|
this.limitFilterType = false
|
||||||
}
|
}
|
||||||
this.queryFilter({ entityType: entityType, q: this.q, ...this.timeFilter })
|
// this.queryFilter({ entityType: entityType, q: this.q, ...this.timeFilter })
|
||||||
if (entityType === 'ip') {
|
// if (entityType === 'ip') {
|
||||||
this.queryFilter({ entityType: 'dns', q: this.q, ...this.timeFilter })
|
// this.queryFilter({ entityType: 'dns', q: this.q, ...this.timeFilter })
|
||||||
}
|
// }
|
||||||
|
this.queryFilterNew({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
||||||
this.queryList({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
this.queryList({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
||||||
this.queryListTotal({ q: this.q, ...this.timeFilter })
|
this.queryCount({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
||||||
|
// this.queryListTotal({ q: this.q, ...this.timeFilter })
|
||||||
} else {
|
} else {
|
||||||
this.limitFilterType = false
|
this.limitFilterType = false
|
||||||
this.queryFilter({ entityType: 'ip', q: this.q, ...this.timeFilter })
|
// this.queryFilter({ entityType: 'ip', q: this.q, ...this.timeFilter })
|
||||||
this.queryFilter({ entityType: 'domain', q: this.q, ...this.timeFilter })
|
// this.queryFilter({ entityType: 'domain', q: this.q, ...this.timeFilter })
|
||||||
this.queryFilter({ entityType: 'app', q: this.q, ...this.timeFilter })
|
// this.queryFilter({ entityType: 'app', q: this.q, ...this.timeFilter })
|
||||||
this.queryFilter({ entityType: 'dns', q: this.q, ...this.timeFilter })
|
// this.queryFilter({ entityType: 'dns', q: this.q, ...this.timeFilter })
|
||||||
|
this.queryFilterNew({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
||||||
this.queryList({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
this.queryList({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
||||||
this.queryListTotal({ q: this.q, ...this.timeFilter })
|
this.queryCount({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
||||||
|
// this.queryListTotal({ q: this.q, ...this.timeFilter })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.limitFilterType = false
|
this.limitFilterType = false
|
||||||
this.queryFilter({ entityType: 'ip', ...this.timeFilter })
|
// this.queryFilter({ entityType: 'ip', ...this.timeFilter })
|
||||||
this.queryFilter({ entityType: 'app', ...this.timeFilter })
|
// this.queryFilter({ entityType: 'app', ...this.timeFilter })
|
||||||
this.queryFilter({ entityType: 'domain', ...this.timeFilter })
|
// this.queryFilter({ entityType: 'domain', ...this.timeFilter })
|
||||||
this.queryFilter({ entityType: 'dns', ...this.timeFilter })
|
// this.queryFilter({ entityType: 'dns', ...this.timeFilter })
|
||||||
|
this.queryFilterNew({ ...this.pageObj, ...this.timeFilter })
|
||||||
this.queryList({ ...this.pageObj, ...this.timeFilter })
|
this.queryList({ ...this.pageObj, ...this.timeFilter })
|
||||||
this.queryListTotal({ ...this.timeFilter })
|
this.queryCount({ ...this.pageObj, ...this.timeFilter })
|
||||||
|
// this.queryListTotal({ ...this.timeFilter })
|
||||||
|
|
||||||
// 延时一秒,避免初始化时pageSize为20,pageNo为1也会调用“搜索”的情况
|
// 延时一秒,避免初始化时pageSize为20,pageNo为1也会调用“搜索”的情况
|
||||||
if (!this.initFlag) {
|
if (!this.initFlag) {
|
||||||
@@ -636,27 +663,87 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
/** 新版查询filter数据 */
|
||||||
|
queryFilterNew (params) {
|
||||||
|
const queryParams = {
|
||||||
|
// startTime: getSecond(params.startTime),
|
||||||
|
// endTime: getSecond(params.endTime),
|
||||||
|
resource: params.q || ''
|
||||||
|
}
|
||||||
|
this.loadingLeft = true
|
||||||
|
const aggCountry = get(api.entity.entityList.aggCountry, queryParams)
|
||||||
|
const aggCity = get(api.entity.entityList.aggCity, queryParams)
|
||||||
|
const aggAsn = get(api.entity.entityList.aggAsn, queryParams)
|
||||||
|
|
||||||
|
Promise.all([aggCountry, aggCity, aggAsn]).then(response => {
|
||||||
|
response.forEach((item, index) => {
|
||||||
|
if (item.code === 200 && item.data.list) {
|
||||||
|
this.newFilterData[index].data = []
|
||||||
|
item.data.list.forEach(item => {
|
||||||
|
const obj = { label: item.value, flag: '011-china', topColumn: 'country', value: item.uniqueEntities }
|
||||||
|
if (index === 0) {
|
||||||
|
obj.flag = item.uniqueEntities // 接口字段名称为'China',目前svg名称为'011-china',后续再指定方案调整
|
||||||
|
}
|
||||||
|
if (index === 1) {
|
||||||
|
obj.topColumn = 'region'
|
||||||
|
}
|
||||||
|
if (index === 2) {
|
||||||
|
obj.topColumn = 'asn'
|
||||||
|
}
|
||||||
|
this.newFilterData[index].data.push(obj)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(e => {
|
||||||
|
// e
|
||||||
|
}).finally(() => {
|
||||||
|
this.loadingLeft = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/** 实体列表查询 */
|
||||||
queryList (params) {
|
queryList (params) {
|
||||||
this.listLoading = true
|
this.listLoading = true
|
||||||
const queryParams = {
|
const queryParams = {
|
||||||
...params,
|
...params,
|
||||||
startTime: getSecond(params.startTime),
|
// startTime: getSecond(params.startTime),
|
||||||
endTime: getSecond(params.endTime)
|
// endTime: getSecond(params.endTime),
|
||||||
|
resource: params.q || ''
|
||||||
}
|
}
|
||||||
get(api.entityList, queryParams).then(response => {
|
get(api.entity.entityList.list, queryParams).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.listData = []
|
this.listData = []
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.listData = response.data.result
|
this.listData = response.data.list
|
||||||
|
this.pageObj.total = response.data.total
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.error(response.message)
|
|
||||||
this.$message.error(response.message)
|
this.$message.error(response.message)
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
this.listLoading = false
|
this.listLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
/** 实体基数统计 */
|
||||||
|
queryCount (params) {
|
||||||
|
this.loadingCount = true
|
||||||
|
const queryParams = {
|
||||||
|
// startTime: getSecond(params.startTime),
|
||||||
|
// endTime: getSecond(params.endTime),
|
||||||
|
resource: params.q || '' // 目前版本搜索不支持实体名称搜索,下版本改进
|
||||||
|
}
|
||||||
|
get(api.entity.entityList.summaryCount, queryParams).then(response => {
|
||||||
|
if (response.code === 200) {
|
||||||
|
this.summaryCount = response.data
|
||||||
|
} else {
|
||||||
|
this.summaryCount = { total: 0, fqdnCount: 0, ipCount: 0, appCount: 0 }
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
console.log(e)
|
||||||
|
this.summaryCount = { total: 0, fqdnCount: 0, ipCount: 0, appCount: 0 }
|
||||||
|
}).finally(() => {
|
||||||
|
this.loadingCount = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
queryListTotal (params) {
|
queryListTotal (params) {
|
||||||
const queryParams = {
|
const queryParams = {
|
||||||
@@ -677,11 +764,6 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getEntityIndexData () {
|
getEntityIndexData () {
|
||||||
const now = window.$dayJs.tz().valueOf()
|
|
||||||
const timeFilter = {
|
|
||||||
startTime: parseInt(now / 1000 - 3600),
|
|
||||||
endTime: parseInt(now / 1000)
|
|
||||||
}
|
|
||||||
// Total
|
// Total
|
||||||
this.loadingApp = true
|
this.loadingApp = true
|
||||||
this.loadingDomain = true
|
this.loadingDomain = true
|
||||||
@@ -695,61 +777,37 @@ export default {
|
|||||||
this.loadingDomainActive = true
|
this.loadingDomainActive = true
|
||||||
this.loadingIpActive = true
|
this.loadingIpActive = true
|
||||||
|
|
||||||
get(api.entityTotal, { entityType: 'app' }).then(response => {
|
get(api.entity.entityList.entityActive).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.entityAppTotal = response.data.result
|
this.entityDomainTotal = response.data.domainCount
|
||||||
}
|
this.entityIpTotal = response.data.ipCount
|
||||||
this.loadingApp = false
|
this.entityAppTotal = response.data.appCount
|
||||||
})
|
|
||||||
get(api.entityTotal, { entityType: 'domain' }).then(response => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
this.entityDomainTotal = response.data.result
|
|
||||||
}
|
}
|
||||||
this.loadingDomain = false
|
this.loadingDomain = false
|
||||||
})
|
|
||||||
get(api.entityTotal, { entityType: 'ip' }).then(response => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
this.entityIpTotal = response.data.result
|
|
||||||
}
|
|
||||||
this.loadingIp = false
|
this.loadingIp = false
|
||||||
|
this.loadingApp = false
|
||||||
})
|
})
|
||||||
// New
|
// New
|
||||||
get(api.entityNew, { entityType: 'app', ...timeFilter }).then(response => {
|
get(api.entity.entityList.entityNew).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.entityAppNew = response.data.result
|
this.entityDomainNew = response.data.domainCount
|
||||||
}
|
this.entityIpNew = response.data.ipCount
|
||||||
this.loadingAppNew = false
|
this.entityAppNew = response.data.appCount
|
||||||
})
|
|
||||||
get(api.entityNew, { entityType: 'domain', ...timeFilter }).then(response => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
this.entityDomainNew = response.data.result
|
|
||||||
}
|
}
|
||||||
this.loadingDomainNew = false
|
this.loadingDomainNew = false
|
||||||
})
|
|
||||||
get(api.entityNew, { entityType: 'ip', ...timeFilter }).then(response => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
this.entityIpNew = response.data.result
|
|
||||||
}
|
|
||||||
this.loadingIpNew = false
|
this.loadingIpNew = false
|
||||||
|
this.loadingAppNew = false
|
||||||
})
|
})
|
||||||
// Active
|
// Active
|
||||||
get(api.entityActive, { entityType: 'app', ...timeFilter }).then(response => {
|
get(api.entity.entityList.entityActive).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.entityAppActive = response.data.result
|
this.entityDomainActive = response.data.domainCount
|
||||||
}
|
this.entityIpActive = response.data.ipCount
|
||||||
this.loadingAppActive = false
|
this.entityAppActive = response.data.appCount
|
||||||
})
|
|
||||||
get(api.entityActive, { entityType: 'domain', ...timeFilter }).then(response => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
this.entityDomainActive = response.data.result
|
|
||||||
}
|
}
|
||||||
this.loadingDomainActive = false
|
this.loadingDomainActive = false
|
||||||
})
|
|
||||||
get(api.entityActive, { entityType: 'ip', ...timeFilter }).then(response => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
this.entityIpActive = response.data.result
|
|
||||||
}
|
|
||||||
this.loadingIpActive = false
|
this.loadingIpActive = false
|
||||||
|
this.loadingAppActive = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
cleanFilterData (index) {
|
cleanFilterData (index) {
|
||||||
|
|||||||
@@ -1,150 +1,76 @@
|
|||||||
<template >
|
<template>
|
||||||
<div class="entity-filter-case">
|
<div class="entity-filter-case">
|
||||||
<div class="filter-case__header">{{$t('entities.filter')}}</div>
|
<div class="filter-case__header">{{ $t('entities.filter1') }}</div>
|
||||||
<div
|
|
||||||
class="entity-filter"
|
|
||||||
v-for="(filters, index) in filterData"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<div class="filter__header">{{filters.title}}</div>
|
|
||||||
<div class="filter__body">
|
|
||||||
|
|
||||||
<div class="filter__row" v-for="(item, i) in filters.data" :key="i">
|
<div class="entity-filter" v-for="(item, index) in filterData" :key="index">
|
||||||
<el-popover popper-class="filter__row-popover" placement="right-start" :width="440" v-model:visible="item.showTopTen">
|
<div class="filter__header">
|
||||||
<template #reference>
|
<i :class="item.icon"></i>
|
||||||
<div class="filter__row-popover" @click="showTopDialog(i, item, filters)">
|
{{ item.title }}
|
||||||
<div class="row__label">
|
</div>
|
||||||
<i :class="item.icon"></i>
|
|
||||||
<span>{{item.label}}</span>
|
<div class="filter__body" style="position: relative">
|
||||||
</div>
|
<loading :loading="loadingLeft" style="top: -5px;"></loading>
|
||||||
<div class="row__value">
|
<div class="filter__body-item" v-for="(data, i) in item.data" :key="i" @click="filter(data.label, data)">
|
||||||
<loading :loading="loadingLeft" size="small"></loading>
|
<div class="filter__body-item-left">
|
||||||
<span>{{item.value}}</span>
|
<!-- 当前无更好方案匹配国旗,后续解决-->
|
||||||
</div>
|
<!-- <div v-if="data.flag">-->
|
||||||
</div>
|
<!-- <img :src="require(`../../../public/images/flag/${data.flag}.svg`)" class="filter-country-flag"/>-->
|
||||||
</template>
|
<!-- </div>-->
|
||||||
<entity-top
|
<div class="filter__body-item-left-index">{{ i+1 }}</div>
|
||||||
ref="entityTopTenPop"
|
<div class="filter__body-item-left-label">
|
||||||
:loading="loading"
|
<el-tooltip :content="data.label" placement="top" effect="light" :disabled="disabledLabel">
|
||||||
:popover-data="popoverData"
|
<span @mouseenter="handleMouse(`filter${index}${i}`)" :id="`filter${index}${i}`">{{ data.label }}</span>
|
||||||
:item-data="itemData"
|
</el-tooltip>
|
||||||
:total-count="totalCount"
|
</div>
|
||||||
:top-column="item.topColumn"
|
</div>
|
||||||
@filter="filter"
|
|
||||||
></entity-top>
|
<div class="filter__body-item-right">{{ data.value }}</div>
|
||||||
</el-popover>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="filter-hr"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import EntityTop from '@/views/entityExplorer/EntityTop'
|
|
||||||
import { get } from '@/utils/http'
|
|
||||||
import { api } from '@/utils/api'
|
|
||||||
import Loading from '@/components/common/Loading'
|
import Loading from '@/components/common/Loading'
|
||||||
import { getSecond } from '@/utils/date-util'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EntityFilter',
|
name: 'EntityFilter',
|
||||||
components: {
|
components: { Loading },
|
||||||
Loading,
|
|
||||||
EntityTop
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
filterData: Array,
|
filterData: {
|
||||||
q: String,
|
type: Object
|
||||||
timeFilter: Object,
|
},
|
||||||
loadingLeft: Boolean
|
loadingLeft: {
|
||||||
|
type: Boolean
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
topList: 'list',
|
disabledLabel: true
|
||||||
topData: [],
|
|
||||||
entityTopTenData: [],
|
|
||||||
currentColumn: {},
|
|
||||||
totalCount: 0,
|
|
||||||
loading: false,
|
|
||||||
popoverData: [],
|
|
||||||
itemData: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
currentColumn (n, o) {
|
|
||||||
if (n.column === 'dnsServerOrgCount') {
|
|
||||||
this.totalCount = this.filterData[3].orgTotalCount
|
|
||||||
} else if (n.column === 'dnsServerSoftwareCount') {
|
|
||||||
this.totalCount = this.filterData[3].softwareTotalCount
|
|
||||||
} else if (n.column === 'dnsServerOsCount') {
|
|
||||||
this.totalCount = this.filterData[3].osTotalCount
|
|
||||||
} else if (n.column === 'categoryDistinctCount' && n.type === 'app') {
|
|
||||||
this.totalCount = this.filterData[1].totalCount
|
|
||||||
} else {
|
|
||||||
let count = 0
|
|
||||||
this.filterData.forEach(f => {
|
|
||||||
const filter = f.data.some(d => d.column === n.column)
|
|
||||||
if (filter) {
|
|
||||||
count = f.totalCount
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.totalCount = count
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showTopDialog (i, item, filter) {
|
/**
|
||||||
if (this.currentColumn.column === item.column && item.showTopTen) {
|
* 判断文字是否溢出,超出则鼠标移入tooltip显示,否则鼠标移入不显示
|
||||||
item.showTopTen = false
|
* @param id
|
||||||
return
|
*/
|
||||||
|
handleMouse (id) {
|
||||||
|
const dom = document.getElementById(id)
|
||||||
|
if (dom) {
|
||||||
|
const width = document.getElementById(id).offsetWidth
|
||||||
|
this.disabledLabel = width < 180
|
||||||
|
} else {
|
||||||
|
this.disabledLabel = true
|
||||||
}
|
}
|
||||||
this.filterData.forEach(f => {
|
|
||||||
f.data.forEach(ff => {
|
|
||||||
ff.showTopTen = false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
item.showTopTen = true
|
|
||||||
this.currentColumn = {
|
|
||||||
column: item.column,
|
|
||||||
type: filter.type
|
|
||||||
}
|
|
||||||
const queryParams = {
|
|
||||||
q: this.q,
|
|
||||||
entityType: filter.type,
|
|
||||||
column: item.topColumn,
|
|
||||||
top: 10,
|
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
|
||||||
endTime: getSecond(this.timeFilter.endTime)
|
|
||||||
}
|
|
||||||
this.loading = true
|
|
||||||
this.popoverData = []
|
|
||||||
this.itemData = {}
|
|
||||||
get(api.filterTop, queryParams).then(response => {
|
|
||||||
if (response.code === 200) {
|
|
||||||
if (this.currentColumn.column === item.column) {
|
|
||||||
if (filter.type === 'dns') {
|
|
||||||
this.popoverData = response.data.result.filter(f => {
|
|
||||||
return f.count > 0
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.popoverData = response.data.result
|
|
||||||
}
|
|
||||||
this.itemData = item
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.popoverData = []
|
|
||||||
this.itemData = item
|
|
||||||
}
|
|
||||||
this.loading = false
|
|
||||||
}).catch(e => {
|
|
||||||
this.popoverData = []
|
|
||||||
this.itemData = item
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
filter (name, topData) {
|
filter (name, data) {
|
||||||
this.showTopDialog('', topData)
|
this.$emit('filter', name, data)
|
||||||
this.$emit('filter', name, topData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -9,75 +9,76 @@
|
|||||||
<div class="cn-entity__case">
|
<div class="cn-entity__case">
|
||||||
<div class="cn-entity__icon"><i :class="iconClass"></i></div>
|
<div class="cn-entity__icon"><i :class="iconClass"></i></div>
|
||||||
<div class="cn-entity__row">
|
<div class="cn-entity__row">
|
||||||
<div class="cn-entity__header">
|
<!--标签-->
|
||||||
{{ entityData.ipAddr || entityData.domainName || entityData.appName || 'Unknown' }}
|
<div class="cn-entity__header" style="display: flex;align-items: center">
|
||||||
<!-- <div class="cn-entity__header" style="display: flex">-->
|
<span class="cn-entity__header-title">{{ entityData.entityValue || 'Unknown' }}</span>
|
||||||
<!-- <span class="cn-entity__header-title">{{ entityData.ipAddr || entityData.domainName || entityData.appName || 'Unknown' }}</span>-->
|
<span class="entity-detail" style="display: flex;margin-left: 6px;margin-top: 1px;">
|
||||||
<!-- <span class="entity-detail" style="display: flex">-->
|
<span v-for="(item, index) in levelTwoTags" :key="index" class="entity-tag entity-tag--small margin-r-10" :class="`entity-tag--level-two-${item.type}`">
|
||||||
<!-- <span style="width: 62px;" class="entity-tag entity-tag--small entity-tag--level-two-positive margin-r-6">信息技术</span>-->
|
{{ item.value }}
|
||||||
<!-- <span style="width: 50px;" class="entity-tag entity-tag--small entity-tag--level-two-normal margin-r-6">互联网</span>-->
|
</span>
|
||||||
<!-- </span>-->
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cn-entity__body">
|
<div class="cn-entity__body">
|
||||||
<div class="body__basic-info">
|
<div class="body__basic-info">
|
||||||
<div class="basic-info">
|
<div class="basic-info">
|
||||||
<template v-if="entityData.entityType === 'ip'">
|
<template v-if="entityData.entityType === 'ip'">
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-country"></i>
|
<i class="cn-icon cn-icon-country"></i>
|
||||||
<span>{{ $t('overall.country') }} : </span>
|
<span class="row-item-label">{{ $t('overall.country') }} : </span>
|
||||||
<span>{{ entityData.ipLocationCountry || '-' }}</span>
|
<span class="row-item-value">{{ entityData.location ? entityData.location.country : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-position"></i>
|
<i class="cn-icon cn-icon-position"></i>
|
||||||
<span>{{ $t('overall.region') }} : </span>
|
<span class="row-item-label">{{ $t('overall.region') }} : </span>
|
||||||
<span>{{ ipLocationRegion(entityData) }}</span>
|
<span class="row-item-value">{{ entityData.location ? ipLocationRegion(entityData.location) : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-cloud"></i>
|
<i class="cn-icon cn-icon-cloud"></i>
|
||||||
<span>{{ $t('entities.asn') }} : </span>
|
<span class="row-item-label">{{ $t('entities.asn') }} : </span>
|
||||||
<span>{{ entityData.ipAsn || '-' }}</span>
|
<span class="row-item-value">{{ entityData.asn ? entityData.asn.asn : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="entityData.entityType === 'domain'">
|
<template v-else-if="entityData.entityType === 'domain'">
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-category"></i>
|
<i class="cn-icon cn-icon-sub-category"></i>
|
||||||
<span>{{ $t('entities.domainDetail.categoryGroup') }} : </span>
|
<span class="row-item-label">{{ $t('entities.category') }} : </span>
|
||||||
<span>{{ entityData.domainCategoryGroup || '-' }}</span>
|
<span class="row-item-value">{{ entityData.category ? entityData.category.name : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-sub-category"></i>
|
<i class="cn-icon cn-icon-category"></i>
|
||||||
<span>{{ $t('entities.category') }} : </span>
|
<span class="row-item-label">{{ $t('entities.subcategory') }} : </span>
|
||||||
<span>{{ entityData.domainCategory || '-' }}</span>
|
<span class="row-item-value">{{ entityData.category ? entityData.category.group : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-credit"></i>
|
<i class="cn-icon cn-icon-credit"></i>
|
||||||
<span>{{ $t('entities.reputationLevel') }} : </span>
|
<span class="row-item-label">{{ $t('entities.reputationLevel') }} : </span>
|
||||||
<span>{{ entityData.domainReputationScore || '-' }}</span>
|
<span class="row-item-value">{{ entityData.category ? entityData.category.reputationLevel : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="entityData.entityType === 'app'">
|
<template v-else-if="entityData.entityType === 'app'">
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-id"></i>
|
<i class="cn-icon cn-icon-id"></i>
|
||||||
<span>{{ $t('entities.category') }} : </span>
|
<span class="row-item-label">{{ $t('entities.category') }} : </span>
|
||||||
<span>{{ entityData.appCategory || '-' }}</span>
|
<span class="row-item-value">{{ entityData.category ? entityData.category.appCategory : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-category"></i>
|
<i class="cn-icon cn-icon-category"></i>
|
||||||
<span>{{ $t('entities.subcategory') }} : </span>
|
<span class="row-item-label">{{ $t('entities.subcategory') }} : </span>
|
||||||
<span>{{ entityData.appSubcategory || '-' }}</span>
|
<span class="row-item-value">{{ entityData.category ? entityData.category.appSubcategory : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-sub-category"></i>
|
<i class="cn-icon cn-icon-sub-category"></i>
|
||||||
<span>{{ $t('entities.risk') }} : </span>
|
<span class="row-item-label">{{ $t('entities.risk') }} : </span>
|
||||||
<span>{{ appRisk(entityData.appRisk) || '-' }}</span>
|
<span class="row-item-value">{{ entityData.category ? appRisk(entityData.category.appRisk) : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 通用字段 -->
|
<!-- 通用字段 -->
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<div class="item__box">
|
<div class="item__box">
|
||||||
<i class="cn-icon cn-icon-rise"></i>
|
<i class="cn-icon cn-icon-rise"></i>
|
||||||
<span>{{ $t('entities.sentThroughput') }} : </span>
|
<span class="row-item-label">{{ $t('entities.sentThroughput') }} : </span>
|
||||||
<span>
|
<span class="row-item-value">
|
||||||
{{
|
{{
|
||||||
entityData.bytesSentRate ? unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ') + 'ps' : '-'
|
entityData.bytesSentRate ? unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ') + 'ps' : '-'
|
||||||
}}
|
}}
|
||||||
@@ -107,8 +108,8 @@
|
|||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<div class="item__box">
|
<div class="item__box">
|
||||||
<i class="cn-icon cn-icon-fall"></i>
|
<i class="cn-icon cn-icon-fall"></i>
|
||||||
<span>{{ $t('entities.receivedThroughput') }} : </span>
|
<span class="row-item-label">{{ $t('entities.receivedThroughput') }} : </span>
|
||||||
<span>
|
<span class="row-item-value">
|
||||||
{{
|
{{
|
||||||
entityData.bytesReceivedRate ? unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ') + 'ps' : '-'
|
entityData.bytesReceivedRate ? unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ') + 'ps' : '-'
|
||||||
}}
|
}}
|
||||||
@@ -133,23 +134,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--新版实体列表改版,去除这一段-->
|
|
||||||
<div class="basic-info__item">
|
|
||||||
<i class="cn-icon cn-icon-entity-alert"></i>
|
|
||||||
<span>{{ $t('entities.recentAlert') }} : </span>
|
|
||||||
<span>{{ entityData.performanceCount }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="basic-info__item">
|
|
||||||
<i class="cn-icon cn-icon-safe"></i>
|
|
||||||
<span>{{ $t('entities.recentSecurity') }} : </span>
|
|
||||||
<span>{{ entityData.securityCount }}</span>
|
|
||||||
</div>
|
|
||||||
<!--新版实体列表改版,去除这一段-->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="show-detail" @click="showDetail">-->
|
|
||||||
<!-- {{ $t('overall.detail') }}>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- 新版实体列表改版,后续记得解开-->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -172,6 +157,10 @@ import DetailOverview from '@/views/entityExplorer/entityList/detailOverview/Det
|
|||||||
import entityListMixin from './entityListMixin'
|
import entityListMixin from './entityListMixin'
|
||||||
import relatedServer from '@/mixins/relatedServer'
|
import relatedServer from '@/mixins/relatedServer'
|
||||||
import Loading from '@/components/common/Loading'
|
import Loading from '@/components/common/Loading'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { api } from '@/utils/api'
|
||||||
|
import { entityDetailTags, psiphon3IpType } from '@/utils/constants'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Row',
|
name: 'Row',
|
||||||
@@ -188,35 +177,109 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
isCollapse: true // 是否是折叠状态
|
isCollapse: true, // 是否是折叠状态
|
||||||
|
levelTwoTags: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
ipLocationRegion () {
|
ipLocationRegion () {
|
||||||
return function (entityData) {
|
return function (entityData) {
|
||||||
const hasProvinceAndCity =
|
const hasProvinceAndCity =
|
||||||
entityData.ipLocationProvince &&
|
entityData.province &&
|
||||||
entityData.ipLocationCity &&
|
entityData.city &&
|
||||||
entityData.ipLocationProvince !== 'null' &&
|
entityData.province !== 'null' &&
|
||||||
entityData.ipLocationCity !== 'null'
|
entityData.city !== 'null'
|
||||||
const hasProvince =
|
const hasProvince =
|
||||||
entityData.ipLocationProvince &&
|
entityData.province &&
|
||||||
entityData.ipLocationProvince !== 'null'
|
entityData.province !== 'null'
|
||||||
const hasCity =
|
const hasCity =
|
||||||
entityData.ipLocationCity && entityData.ipLocationCity !== 'null'
|
entityData.city && entityData.city !== 'null'
|
||||||
if (hasProvinceAndCity) {
|
if (hasProvinceAndCity) {
|
||||||
return `${entityData.ipLocationProvince}, ${entityData.ipLocationCity}`
|
return `${entityData.province}, ${entityData.city}`
|
||||||
} else if (hasProvince) {
|
} else if (hasProvince) {
|
||||||
return entityData.ipLocationProvince
|
return entityData.province
|
||||||
} else if (hasCity) {
|
} else if (hasCity) {
|
||||||
return entityData.ipLocationCity
|
return entityData.city
|
||||||
} else {
|
} else {
|
||||||
return '-'
|
return '-'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
mounted () {
|
||||||
|
this.initData()
|
||||||
|
this.initTagsData()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initData () {
|
||||||
|
let url = ''
|
||||||
|
switch (this.entity.entityType) {
|
||||||
|
case ('domain'): {
|
||||||
|
url = api.entity.entityList.domainBasicInfo
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('ip'): {
|
||||||
|
url = api.entity.entityList.ipBasicInfo
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('app'): {
|
||||||
|
url = api.entity.entityList.appBasicInfo
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
axios.get(`${url}?resource=${this.entity.entityValue}`).then(response => {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.entityData = { ...response.data.data, ...this.entity }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
initTagsData () {
|
||||||
|
let url = ''
|
||||||
|
switch (this.entity.entityType) {
|
||||||
|
case ('domain'): {
|
||||||
|
url = api.entity.entityList.domainTags
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('ip'): {
|
||||||
|
url = api.entity.entityList.ipTags
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ('app'): {
|
||||||
|
url = api.entity.entityList.appTags
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
axios.get(`${url}?resource=${this.entity.entityValue}`).then(responese => {
|
||||||
|
const res = responese.data
|
||||||
|
if (res.code === 200) {
|
||||||
|
Object.keys(res.data).forEach(k => {
|
||||||
|
if (k !== 'userDefinedTags' && res.data[k]) {
|
||||||
|
Object.keys(res.data[k]).forEach(k2 => {
|
||||||
|
const find = entityDetailTags[this.entity.entityType].find(t => t.name === k2)
|
||||||
|
if (find) {
|
||||||
|
this.levelTwoTags.push({ key: k2, value: this.tagValueHandler(k, k2, res.data[k][k2]), type: find.type })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (_.isArray(res.data.userDefinedTags)) {
|
||||||
|
this.levelTwoTags = _.concat(this.levelTwoTags, res.data.userDefinedTags.map(tag => ({ value: tag.tagValue, type: 'normal' })))
|
||||||
|
}
|
||||||
|
this.hideTagArea = _.isEmpty(this.levelTwoTags)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
tagValueHandler (k, k2, value) {
|
||||||
|
if (k === 'psiphon3Ip') {
|
||||||
|
if (k2 === 'type') {
|
||||||
|
const find = psiphon3IpType.find(t => t.value === value)
|
||||||
|
if (find) {
|
||||||
|
return find.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
},
|
||||||
/* 切换折叠状态 */
|
/* 切换折叠状态 */
|
||||||
switchCollapse () {
|
switchCollapse () {
|
||||||
this.isCollapse = !this.isCollapse
|
this.isCollapse = !this.isCollapse
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
<div class="overview__content">
|
<div class="overview__content">
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">APP ID</div>
|
<div class="row__label row__label--width130">APP ID</div>
|
||||||
<div class="row__content">{{entity.appId|| '-'}}</div>
|
<div class="row__content">{{entity.category.appId || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.category')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.category')}}</div>
|
||||||
<div class="row__content">{{entity.appCategory|| '-'}}</div>
|
<div class="row__content">{{entity.category.appCategory || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.subcategory')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.subcategory')}}</div>
|
||||||
<div class="row__content">{{entity.appSubcategory || '-'}}</div>
|
<div class="row__content">{{entity.category.appSubcategory || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.riskLevel')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.riskLevel')}}</div>
|
||||||
<div class="row__content">{{appRisk(entity.appRisk) || '-'}}</div>
|
<div class="row__content">{{appRisk(parseInt(entity.category.appRisk)) || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('overall.remark')}}</div>
|
<div class="row__label row__label--width130">{{$t('overall.remark')}}</div>
|
||||||
<div class="row__content">{{entity.appDescription || '-'}}</div>
|
<div class="row__content">{{entity.category.appDescription || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,103 +43,78 @@
|
|||||||
<div class="row__charts-msg">{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps</div>
|
<div class="row__charts-msg">{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps</div>
|
||||||
<!-- 曲线-->
|
<!-- 曲线-->
|
||||||
<div class="row__content-loading">
|
<div class="row__content-loading">
|
||||||
<div class="row__charts" :id="`entityDetailSend${entity.appName}`" ></div>
|
<div class="row__charts" :id="`entityDetailSend${entity.entityValue}`" ></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row__content">
|
<div class="row__content row__content-accept">
|
||||||
<div class="row__charts-msg">{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps</div>
|
<div class="row__charts-msg">{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps</div>
|
||||||
<!-- 曲线-->
|
<!-- 曲线-->
|
||||||
<div class="row__content-loading">
|
<div class="row__content-loading">
|
||||||
<div class="row__charts" :id="`entityDetailReceived${entity.appName}`" ></div>
|
<div class="row__charts" :id="`entityDetailReceived${entity.entityValue}`" ></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="overview__row">
|
||||||
|
<div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div>
|
||||||
|
<loading :loading="loadingNetworkQuality" size="small" inner-style="left: 1rem;"></loading>
|
||||||
|
<div class="entity-score" v-if="!loadingNetworkQuality">
|
||||||
|
<div class="circle-icon" v-if="score <= 2 || score === '-'" :class="{'data-score-red': score <= 2 || score === '-'}" ></div>
|
||||||
|
<div class="circle-icon" v-else-if="score <= 4" :class="{'data-score-yellow': score <= 4}" ></div>
|
||||||
|
<div class="circle-icon" v-else-if="score <= 6" :class="{'data-score-green': score <= 6}" ></div>
|
||||||
|
Score:{{score}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overview-item">
|
<div class="overview-item">
|
||||||
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
||||||
<div class="overview__content domain__content">
|
<div class="overview__content domain__content">
|
||||||
<div class="overview__tags domain__tags" ref="relationship">
|
<div class="overview__tags domain__tags" ref="relationship"></div>
|
||||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
<div class="overview__row">
|
||||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
<div class="row__label row__label--width130">{{$t('entities.tab.relatedIp')}}</div>
|
||||||
<div class="overview__domain-tab">
|
|
||||||
<div class="overview__tag domain__tag">
|
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||||
<span class="tag__value">{{relationshipDataOne.length}}</span>
|
<div class="row__content overview__row-related">
|
||||||
<span class="tag__desc">{{$t('entities.relatedDomains')}}</span>
|
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
||||||
</div>
|
{{item.value}}
|
||||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
|
||||||
<span class="tag__desc">{{item.domain}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-btn">
|
|
||||||
<div class="overview__domain-more" @click="more(relationshipDataOne, 1)" v-if="relationshipShowOne">...</div>
|
<div v-if="relationshipShowOne">
|
||||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreOne" v-ele-click-outside="mouseout">
|
<el-popover placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataOne" :key="item">
|
<template #reference>
|
||||||
<span v-if="item.domain" :title="item.domain">{{item.domain}}</span>
|
<div class="data-item show-more-related">...</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
<div v-for="(item, index) in relationshipDataOne" :key="index">{{item.value}}</div>
|
||||||
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
</div>
|
||||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
|
||||||
<div class="overview__domain-tab">
|
<div class="overview__row overview__row-related">
|
||||||
<div class="overview__tag domain__tag">
|
<div class="row__label row__label--width130">{{$t('entities.tab.relatedIp')}}</div>
|
||||||
<span class="tag__value">{{relationshipDataTwo.length}}</span>
|
|
||||||
<span class="tag__desc">{{$t('entities.relatedServerIp')}}</span>
|
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||||
</div>
|
<div class="row__content">
|
||||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||||
<span class="tag__desc">{{item.ip}}</span>
|
{{item.value}}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-btn">
|
|
||||||
<div class="overview__domain-more" @click="more(relationshipDataTwo, 2)" v-if="relationshipShowTwo">...</div>
|
<div v-if="relationshipShowTwo">
|
||||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreTwo" v-ele-click-outside="mouseout">
|
<el-popover class="entity-expand-detail" placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataTwo" :key="item">
|
<template #reference>
|
||||||
<span v-if="item.ip" :title="item.ip">{{item.ip}}</span>
|
<div class="data-item show-more-related">...</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
<div v-for="(item, index) in relationshipDataTwo" :key="index">{{item.value}}</div>
|
||||||
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview-item">
|
|
||||||
<div class="overview__title">{{$t('overall.networkQuality')}}</div>
|
|
||||||
<div class="overview__content overview__content-loading-net">
|
|
||||||
<loading :loading="loadingNetworkQuality" size="small"></loading>
|
|
||||||
<div class="overview__row overview__row--single-value">
|
|
||||||
<chart-single-value
|
|
||||||
v-for="(chartInfo, i) in singleValues.chartInfos"
|
|
||||||
:chart-info="chartInfo"
|
|
||||||
:chart-data="singleValues.chartDatas[i]"
|
|
||||||
:key="i"
|
|
||||||
class="cn-chart__single-value--detail-overview"
|
|
||||||
></chart-single-value>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overview-item">
|
|
||||||
<div class="overview__title">{{$t('entities.accessLink')}}</div>
|
|
||||||
<div class="overview__content">
|
|
||||||
<div class="overview__tags">
|
|
||||||
<div class="overview__tag overview__tag-loading">
|
|
||||||
<loading :loading="loadingOut" size="small"></loading>
|
|
||||||
<span class="tag__desc">{{$t('entities.outLinkTrafficPercentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkOutId ? entityData.linkOutId : '-'}},</span>
|
|
||||||
<span class="tag__desc">{{$t('entities.percentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkOutPercent ? unitConvert(entityData.linkOutPercent, unitTypes.percent).join(' ') : '-'}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="overview__tag overview__tag-loading">
|
|
||||||
<loading :loading="loadingIn" size="small"></loading>
|
|
||||||
<span class="tag__desc">{{$t('entities.inLinkTrafficPercentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkInId ? entityData.linkInId : '-'}},</span>
|
|
||||||
<span class="tag__desc">{{$t('entities.percentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkInPercent ? unitConvert(entityData.linkInPercent, unitTypes.percent).join(' ') : '-'}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overview-item">
|
<div class="overview-item">
|
||||||
<div class="overview__title">{{$t('overall.alert')}}</div>
|
<div class="overview__title">{{$t('overall.alert')}}</div>
|
||||||
<div class="overview__content overview__content-loading">
|
<div class="overview__content overview__content-loading">
|
||||||
@@ -148,20 +123,17 @@
|
|||||||
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row" v-if="performanceData.length > 0">
|
<div class="overview__row" v-if="performanceData.length > 0">
|
||||||
<div class="row__label">{{$t('entities.recentAlert')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.recentAlert')}}</div>
|
||||||
<div class="row__content">{{entityData.performanceNum}}</div>
|
<div class="row__content">{{entityData.performanceNum}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row overview__row--small-font" v-for="(performance, index) in entityData.performanceList" :key="index">
|
<div class="overview__row overview__row--small-font" v-for="(performance, index) in entityData.performanceList" :key="index">
|
||||||
<div class="row__label row__label--width160">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
<div class="row__label row__label--width130">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
||||||
<div class="row__content row__content--width200">
|
<div class="row__content row__content--width90">
|
||||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
||||||
<div>{{performance.eventType}}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row__content-loading" style="position: relative;" >
|
<div class="row__content-loading" style="position: relative;">
|
||||||
<loading :loading="!loadingAlert && loadingPerformance[index]?loadingPerformance[index]:false" :id="`loading${entity.ipAddr}_${index}`" size="small"></loading>
|
<div class="performance-event-remark">{{performance.eventType}}</div>
|
||||||
<div class="row__charts" :id="`entityPerformanceChart${entity.appName}_${index}`"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row__desc"></div>
|
<div class="row__desc"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row overview__row--small-font" v-if="performanceData && performanceData.length > 5">
|
<div class="overview__row overview__row--small-font" v-if="performanceData && performanceData.length > 5">
|
||||||
@@ -177,15 +149,26 @@
|
|||||||
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row" v-if="securityData.length > 0">
|
<div class="overview__row" v-if="securityData.length > 0">
|
||||||
<div class="row__label">{{$t('entities.recentSecurity')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.recentSecurity')}}</div>
|
||||||
<div class="row__content">{{entityData.securityNum}}</div>
|
<div class="row__content">{{entityData.securityNum}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row overview__row--small-font" v-for="(security, index) in entityData.securityList" :key="index">
|
|
||||||
<div class="row__label row__label--width160">{{dateFormatByAppearance(security.startTime) || '-'}}</div>
|
<div class="overview__row overview__row--small-font" v-for="(security, index) in entityData.securityList" :key="index">
|
||||||
<div class="row__content row__content--width200">
|
<div class="row__label row__label--width130">{{dateFormatByAppearance(security.startTime) || '-'}}</div>
|
||||||
|
<div class="row__content row__content--width90">
|
||||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(security)">{{security.eventSeverity}}</div>
|
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(security)">{{security.eventSeverity}}</div>
|
||||||
<div>{{security.securityType}}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cn-detection__header">
|
||||||
|
<i class="cn-icon cn-icon-attacker"></i>
|
||||||
|
<span>{{ security.offenderIp }}</span>
|
||||||
|
<div class="domain" v-if="security.offenderIp===security.serverIp">{{ security.domain }}</div>
|
||||||
|
<span class="line">-------</span>
|
||||||
|
<span class="circle"></span>
|
||||||
|
<i class="cn-icon cn-icon-attacked"></i>
|
||||||
|
<span>{{ security.victimIp }}</span>
|
||||||
|
<div class="domain" v-if="security.victimIp===security.serverIp">{{ security.domain }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row__desc"></div>
|
<div class="row__desc"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row overview__row--small-font" v-if="securityData && securityData.length > 5">
|
<div class="overview__row overview__row--small-font" v-if="securityData && securityData.length > 5">
|
||||||
@@ -213,34 +196,38 @@ import { unitTypes } from '@/utils/constants'
|
|||||||
import unitConvert from '@/utils/unit-convert'
|
import unitConvert from '@/utils/unit-convert'
|
||||||
import Chart from '@/views/charts/Chart'
|
import Chart from '@/views/charts/Chart'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
|
|
||||||
import { get } from '@/utils/http'
|
import { get } from '@/utils/http'
|
||||||
import relatedServer from '@/mixins/relatedServer'
|
import relatedServer from '@/mixins/relatedServer'
|
||||||
import { getSecond, getMillisecond } from '@/utils/date-util'
|
import { dateFormatByAppearance, getMillisecond, getSecond } from '@/utils/date-util'
|
||||||
import Loading from '@/components/common/Loading'
|
import Loading from '@/components/common/Loading'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
mixins: [entityDetailMixin, relatedServer],
|
mixins: [entityDetailMixin, relatedServer],
|
||||||
components: {
|
components: {
|
||||||
Chart,
|
Chart,
|
||||||
Loading,
|
Loading
|
||||||
ChartSingleValue
|
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
// entityData: {}
|
// entityData: {}
|
||||||
entityType: 'app',
|
entityType: 'app',
|
||||||
trafficUrl: api.entityAppDetailTraffic,
|
// trafficUrl: api.entityAppDetailTraffic,
|
||||||
|
trafficUrl: api.entity.entityList.appThroughput,
|
||||||
relationUrl: api.entityAppDetailRelation,
|
relationUrl: api.entityAppDetailRelation,
|
||||||
networkQuantityUrl: api.entityAppDetailNetworkQuantity,
|
// networkQuantityUrl: api.entityAppDetailNetworkQuantity,
|
||||||
|
networkQuantityUrl: api.entity.entityList.appPerformance,
|
||||||
linkInUrl: api.entityAppDetailLinkIn,
|
linkInUrl: api.entityAppDetailLinkIn,
|
||||||
linkOutUrl: api.entityAppDetailLinkOut,
|
linkOutUrl: api.entityAppDetailLinkOut,
|
||||||
performanceUrl: api.entityAppDetailPerformance,
|
// performanceUrl: api.entityAppDetailPerformance,
|
||||||
securityUrl: api.entityAppDetailSecurity,
|
performanceUrl: api.entity.entityList.appEventPerformance,
|
||||||
trafficUrlMap: api.entityAppDetailTrafficMap,
|
securityUrl: api.entity.entityList.appSecurity,
|
||||||
relatedServerDomainUrl: api.entityAppRelatedServerDomain,
|
// securityUrl: api.entityAppDetailSecurity,
|
||||||
relatedServerIpUrl: api.entityAppRelatedServerIp,
|
// trafficUrlMap: api.entityAppDetailTrafficMap,
|
||||||
|
trafficUrlMap: api.entity.entityList.appTrafficMap,
|
||||||
|
relatedServerDomainUrl: api.entity.entityList.appRelatedDomain,
|
||||||
|
relatedServerIpUrl: api.entity.entityList.appRelatedIp,
|
||||||
chartData: null,
|
chartData: null,
|
||||||
listMode: 'list',
|
listMode: 'list',
|
||||||
singleValues: {
|
singleValues: {
|
||||||
@@ -296,34 +283,34 @@ export default {
|
|||||||
i18n: 'entities.pktRetransPercent'
|
i18n: 'entities.pktRetransPercent'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
chartDatas: [null, null, null, null, null],
|
chartDatas: [null, null, null, null, null]
|
||||||
loadingTraffic: false,
|
},
|
||||||
loadingRelationshipOne: false,
|
loadingTraffic: false,
|
||||||
loadingRelationshipTwo: false,
|
loadingRelationshipOne: false,
|
||||||
loadingNetworkQuality: false,
|
loadingRelationshipTwo: false,
|
||||||
loadingOut: false,
|
loadingNetworkQuality: false,
|
||||||
loadingIn: false,
|
loadingOut: false,
|
||||||
loadingAlert: false,
|
loadingIn: false,
|
||||||
loadingSecurityEvents: false,
|
loadingAlert: false,
|
||||||
loadingMap: false
|
loadingSecurityEvents: false,
|
||||||
}
|
loadingMap: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getMillisecond,
|
getMillisecond,
|
||||||
|
dateFormatByAppearance,
|
||||||
getQueryParams () {
|
getQueryParams () {
|
||||||
const queryParams = {
|
return {
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
endTime: getSecond(this.timeFilter.endTime),
|
endTime: getSecond(this.timeFilter.endTime),
|
||||||
appName: this.entity.appName
|
resource: this.entity.entityValue,
|
||||||
|
appName: this.entity.entityValue
|
||||||
}
|
}
|
||||||
return queryParams
|
|
||||||
},
|
},
|
||||||
getPerformanceQueryParams () {
|
getPerformanceQueryParams () {
|
||||||
const queryParams = {
|
return {
|
||||||
appName: this.entity.appName
|
appName: this.entity.entityValue
|
||||||
}
|
}
|
||||||
return queryParams
|
|
||||||
},
|
},
|
||||||
handleRelationData (result) {
|
handleRelationData (result) {
|
||||||
this.entityData.domainCount = result.domainCount
|
this.entityData.domainCount = result.domainCount
|
||||||
@@ -353,6 +340,7 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
setup (props) {
|
setup (props) {
|
||||||
|
const entityData = ref({ ...props.entity })
|
||||||
return {
|
return {
|
||||||
chart: {
|
chart: {
|
||||||
params: {
|
params: {
|
||||||
@@ -366,7 +354,8 @@ export default {
|
|||||||
entityCopy: {
|
entityCopy: {
|
||||||
..._.cloneDeep(props.entity)
|
..._.cloneDeep(props.entity)
|
||||||
},
|
},
|
||||||
unitConvert
|
unitConvert,
|
||||||
|
entityData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,36 +4,32 @@
|
|||||||
<div class="overview__content">
|
<div class="overview__content">
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.category')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.category')}}</div>
|
||||||
<div class="row__content">{{entityData.domainCategory || '-'}}</div>
|
<div class="row__content">{{entityData.category ? entityData.category.categoryName : '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.domainDetail.categoryGroup')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.domainDetail.categoryGroup')}}</div>
|
||||||
<div class="row__content">{{entityData.domainCategoryGroup || '-'}}</div>
|
<div class="row__content">{{entityData.category ? entityData.category.categoryGroup : '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.reputationLevel')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.reputationLevel')}}</div>
|
||||||
<div class="row__content">{{entityData.domainReputationScore || '-'}}</div>
|
<div class="row__content">{{entityData.category ? entityData.category.reputationLevel : '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.registration')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.registration')}}</div>
|
||||||
<div class="row__content">{{entityData.domainWhoisAddress || '-'}}</div>
|
<div class="row__content">{{entityData.whois ? entityData.whois.registrantCountry : '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.org')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.org')}}</div>
|
||||||
<div class="row__content">{{entityData.domainWhoisOrg || '-'}}</div>
|
<div class="row__content">{{entityData.whois ? entityData.whois.registrantOrg : '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.icpCompanyName')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.icpCompanyName')}}</div>
|
||||||
<div class="row__content">{{entityData.domainIcpCompanyName || '-'}}</div>
|
<div class="row__content">{{entityData.icp ? entityData.icp.icpCompanyName : '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('entities.icpLicense')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.icpLicense')}}</div>
|
||||||
<div class="row__content">{{entityData.domainIcpSiteLicense || '-'}}</div>
|
<div class="row__content">{{entityData.icp ? entityData.icp.icpSiteLicense : '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="overview__row">
|
|
||||||
<div class="row__label row__label--width130">{{$t('overall.remark')}}</div>
|
|
||||||
<div class="row__content">{{entityData.domainDescription || '-'}}</div>
|
|
||||||
</div>-->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview-item">
|
<div class="overview-item">
|
||||||
@@ -55,103 +51,78 @@
|
|||||||
<div class="row__charts-msg">{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps</div>
|
<div class="row__charts-msg">{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps</div>
|
||||||
<!-- 曲线-->
|
<!-- 曲线-->
|
||||||
<div class="row__content-loading">
|
<div class="row__content-loading">
|
||||||
<div class="row__charts" :id="`entityDetailSend${entity.domainName}`" >{</div>
|
<div class="row__charts" :id="`entityDetailSend${entity.entityValue}`" >{</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row__content">
|
<div class="row__content row__content-accept">
|
||||||
<div class="row__charts-msg">{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps</div>
|
<div class="row__charts-msg">{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps</div>
|
||||||
<!-- 曲线-->
|
<!-- 曲线-->
|
||||||
<div class="row__content-loading">
|
<div class="row__content-loading">
|
||||||
<div class="row__charts" :id="`entityDetailReceived${entity.domainName}`" ></div>
|
<div class="row__charts" :id="`entityDetailReceived${entity.entityValue}`" ></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="overview__row">
|
||||||
|
<div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div>
|
||||||
|
<loading :loading="loadingNetworkQuality" size="small" inner-style="left: 1rem;"></loading>
|
||||||
|
<div class="entity-score" v-if="!loadingNetworkQuality">
|
||||||
|
<div class="circle-icon" v-if="score <= 2 || score === '-'" :class="{'data-score-red': score <= 2 || score === '-'}" ></div>
|
||||||
|
<div class="circle-icon" v-else-if="score <= 4" :class="{'data-score-yellow': score <= 4}" ></div>
|
||||||
|
<div class="circle-icon" v-else-if="score <= 6" :class="{'data-score-green': score <= 6}" ></div>
|
||||||
|
Score:{{score}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overview-item">
|
<div class="overview-item">
|
||||||
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
||||||
<div class="overview__content domain__content">
|
<div class="overview__content domain__content">
|
||||||
<div class="overview__tags domain__tags" ref="relationship">
|
<div class="overview__tags domain__tags" ref="relationship"></div>
|
||||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
<div class="overview__row">
|
||||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
<div class="row__label row__label--width130">{{$t('entities.tab.relatedApp')}}</div>
|
||||||
<div class="overview__domain-tab">
|
|
||||||
<div class="overview__tag domain__tag">
|
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||||
<span class="tag__value">{{relationshipDataOne.length}}</span>
|
<div class="row__content overview__row-related">
|
||||||
<span class="tag__desc">{{$t('entities.relatedApp')}}</span>
|
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
||||||
</div>
|
{{item.value}}
|
||||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
|
||||||
<span class="tag__desc">{{item.appName}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-btn">
|
|
||||||
<div class="overview__domain-more" @click="more(relationshipDataOne, 1)" v-if="relationshipShowOne">...</div>
|
<div v-if="relationshipShowOne">
|
||||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreOne" v-ele-click-outside="mouseout">
|
<el-popover placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataOne" :key="item">
|
<template #reference>
|
||||||
<span v-if="item.appName" :title="item.appName">{{item.appName}}</span>
|
<div class="data-item show-more-related">...</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
<div v-for="(item, index) in relationshipDataOne" :key="index">{{item.value}}</div>
|
||||||
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
</div>
|
||||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
|
||||||
<div class="overview__domain-tab">
|
<div class="overview__row overview__row-related">
|
||||||
<div class="overview__tag domain__tag">
|
<div class="row__label row__label--width130">{{$t('entities.tab.relatedIp')}}</div>
|
||||||
<span class="tag__value">{{relationshipDataTwo.length}}</span>
|
|
||||||
<span class="tag__desc">{{$t('entities.relatedServerIp')}}</span>
|
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||||
</div>
|
<div class="row__content">
|
||||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||||
<span class="tag__desc">{{item.ip}}</span>
|
{{item.value}}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-btn">
|
|
||||||
<div class="overview__domain-more" @click="more(relationshipDataTwo, 2)" v-if="relationshipShowTwo">...</div>
|
<div v-if="relationshipShowTwo">
|
||||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreTwo" v-ele-click-outside="mouseout">
|
<el-popover class="entity-expand-detail" placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataTwo" :key="item">
|
<template #reference>
|
||||||
<span v-if="item.ip" :title="item.ip">{{item.ip}}</span>
|
<div class="data-item show-more-related">...</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
<div v-for="(item, index) in relationshipDataTwo" :key="index">{{item.value}}</div>
|
||||||
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview-item">
|
|
||||||
<div class="overview__title">{{$t('overall.networkQuality')}}</div>
|
|
||||||
<div class="overview__content overview__content-loading-net">
|
|
||||||
<loading :loading="loadingNetworkQuality" size="small"></loading>
|
|
||||||
<div class="overview__row overview__row--single-value">
|
|
||||||
<chart-single-value
|
|
||||||
v-for="(chartInfo, i) in singleValues.chartInfos"
|
|
||||||
:chart-info="chartInfo"
|
|
||||||
:chart-data="singleValues.chartDatas[i]"
|
|
||||||
:key="i"
|
|
||||||
class="cn-chart__single-value--detail-overview"
|
|
||||||
></chart-single-value>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overview-item">
|
|
||||||
<div class="overview__title">{{$t('entities.accessLink')}}</div>
|
|
||||||
<div class="overview__content">
|
|
||||||
<div class="overview__tags">
|
|
||||||
<div class="overview__tag overview__tag-loading">
|
|
||||||
<loading :loading="loadingOut" size="small"></loading>
|
|
||||||
<span class="tag__desc">{{$t('entities.outLinkTrafficPercentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkOutId ? entityData.linkOutId : '-'}},</span>
|
|
||||||
<span class="tag__desc">{{$t('entities.percentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkOutPercent ? unitConvert(entityData.linkOutPercent, unitTypes.percent).join(' ') : '-'}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="overview__tag overview__tag-loading">
|
|
||||||
<loading :loading="loadingIn" size="small"></loading>
|
|
||||||
<span class="tag__desc">{{$t('entities.inLinkTrafficPercentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkInId ? entityData.linkInId : '-'}},</span>
|
|
||||||
<span class="tag__desc">{{$t('entities.percentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkInPercent ? unitConvert(entityData.linkInPercent, unitTypes.percent).join(' ') : '-'}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overview-item">
|
<div class="overview-item">
|
||||||
<div class="overview__title">{{$t('overall.alert')}}</div>
|
<div class="overview__title">{{$t('overall.alert')}}</div>
|
||||||
<div class="overview__content overview__content-loading">
|
<div class="overview__content overview__content-loading">
|
||||||
@@ -160,18 +131,16 @@
|
|||||||
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row" v-if="performanceData.length > 0">
|
<div class="overview__row" v-if="performanceData.length > 0">
|
||||||
<div class="row__label">{{$t('entities.recentAlert')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.recentAlert')}}</div>
|
||||||
<div class="row__content">{{entityData.performanceNum}}</div>
|
<div class="row__content">{{entityData.performanceNum}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row overview__row--small-font" v-for="(performance, index) in entityData.performanceList" :key="index">
|
<div class="overview__row overview__row--small-font" v-for="(performance, index) in entityData.performanceList" :key="index">
|
||||||
<div class="row__label row__label--width160">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
<div class="row__label row__label--width130">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
||||||
<div class="row__content row__content--width200">
|
<div class="row__content row__content--width90">
|
||||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
||||||
<div>{{performance.eventType}}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row__content-loading" style="position: relative;" >
|
<div class="row__content-loading" style="position: relative;">
|
||||||
<loading :loading="!loadingAlert && loadingPerformance[index]?loadingPerformance[index]:false" :id="`loading${entity.ipAddr}_${index}`" size="small"></loading>
|
<div class="performance-event-remark">{{performance.eventType}}</div>
|
||||||
<div class="row__charts" :id="`entityPerformanceChart${entity.domainName}_${index}`"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row__desc"></div>
|
<div class="row__desc"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -188,14 +157,24 @@
|
|||||||
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row" v-if="securityData.length > 0">
|
<div class="overview__row" v-if="securityData.length > 0">
|
||||||
<div class="row__label">{{$t('entities.recentSecurity')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.recentSecurity')}}</div>
|
||||||
<div class="row__content">{{entityData.securityNum}}</div>
|
<div class="row__content">{{entityData.securityNum}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overview__row overview__row--small-font" v-for="(security, i) in entityData.securityList" :key="i">
|
<div class="overview__row overview__row--small-font" v-for="(security, i) in entityData.securityList" :key="i">
|
||||||
<div class="row__label row__label--width160">{{dateFormatByAppearance(getMillisecond(security.startTime)) || '-'}}</div>
|
<div class="row__label row__label--width130">{{dateFormatByAppearance(getMillisecond(security.startTime)) || '-'}}</div>
|
||||||
<div class="row__content row__content--width200">
|
<div class="row__content row__content--width90">
|
||||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(security)">{{security.eventSeverity}}</div>
|
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(security)">{{security.eventSeverity}}</div>
|
||||||
<div>{{security.securityType}}</div>
|
</div>
|
||||||
|
<div class="cn-detection__header">
|
||||||
|
<i class="cn-icon cn-icon-attacker"></i>
|
||||||
|
<span>{{ security.offenderIp }}</span>
|
||||||
|
<div class="domain" v-if="security.offenderIp===security.serverIp">{{ security.domain }}</div>
|
||||||
|
<span class="line">-------</span>
|
||||||
|
<span class="circle"></span>
|
||||||
|
<i class="cn-icon cn-icon-attacked"></i>
|
||||||
|
<span>{{ security.victimIp }}</span>
|
||||||
|
<div class="domain" v-if="security.victimIp===security.serverIp">{{ security.domain }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row__desc"></div>
|
<div class="row__desc"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -218,7 +197,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
|
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import entityDetailMixin from './entityDetailMixin'
|
import entityDetailMixin from './entityDetailMixin'
|
||||||
import { unitTypes } from '@/utils/constants'
|
import { unitTypes } from '@/utils/constants'
|
||||||
@@ -227,13 +205,13 @@ import Chart from '@/views/charts/Chart'
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { get } from '@/utils/http'
|
import { get } from '@/utils/http'
|
||||||
import relatedServer from '@/mixins/relatedServer'
|
import relatedServer from '@/mixins/relatedServer'
|
||||||
import { getSecond, getMillisecond } from '@/utils/date-util'
|
import { dateFormatByAppearance, getMillisecond, getSecond } from '@/utils/date-util'
|
||||||
import Loading from '@/components/common/Loading'
|
import Loading from '@/components/common/Loading'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Domain',
|
name: 'Domain',
|
||||||
components: {
|
components: {
|
||||||
ChartSingleValue,
|
|
||||||
Loading,
|
Loading,
|
||||||
Chart
|
Chart
|
||||||
},
|
},
|
||||||
@@ -242,16 +220,21 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// entityData: {},
|
// entityData: {},
|
||||||
entityType: 'domain',
|
entityType: 'domain',
|
||||||
trafficUrl: api.entityDomainDetailTraffic,
|
// trafficUrl: api.entityDomainDetailTraffic,
|
||||||
|
trafficUrl: api.entity.entityList.domainThroughput,
|
||||||
relationUrl: api.entityDomainDetailRelation,
|
relationUrl: api.entityDomainDetailRelation,
|
||||||
networkQuantityUrl: api.entityDomainDetailNetworkQuantity,
|
networkQuantityUrl: api.entity.entityList.domainPerformance,
|
||||||
|
// networkQuantityUrl: api.entityDomainDetailNetworkQuantity,
|
||||||
linkInUrl: api.entityDomainDetailLinkIn,
|
linkInUrl: api.entityDomainDetailLinkIn,
|
||||||
linkOutUrl: api.entityDomainDetailLinkOut,
|
linkOutUrl: api.entityDomainDetailLinkOut,
|
||||||
performanceUrl: api.entityDomainDetailPerformance,
|
// performanceUrl: api.entityDomainDetailPerformance,
|
||||||
securityUrl: api.entityDomainDetailSecurity,
|
performanceUrl: api.entity.entityList.domainEventPerformance,
|
||||||
trafficUrlMap: api.entityDomainDetailTrafficMap,
|
// securityUrl: api.entityDomainDetailSecurity,
|
||||||
relatedServerIpUrl: api.entityDomainRelatedServerIp,
|
securityUrl: api.entity.entityList.domainSecurity,
|
||||||
relatedServerAppUrl: api.entityDomainRelatedServerApp,
|
// trafficUrlMap: api.entityDomainDetailTrafficMap,
|
||||||
|
trafficUrlMap: api.entity.entityList.domainTrafficMap,
|
||||||
|
relatedServerIpUrl: api.entity.entityList.domainRelatedIp,
|
||||||
|
relatedServerAppUrl: api.entity.entityList.domainRelatedApp,
|
||||||
basicProperties: api.entityDomainDetailBasic,
|
basicProperties: api.entityDomainDetailBasic,
|
||||||
chartData: null,
|
chartData: null,
|
||||||
listMode: 'list',
|
listMode: 'list',
|
||||||
@@ -308,34 +291,34 @@ export default {
|
|||||||
i18n: 'entities.pktRetransPercent'
|
i18n: 'entities.pktRetransPercent'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
chartDatas: [null, null, null, null, null],
|
chartDatas: [null, null, null, null, null]
|
||||||
loadingTraffic: false,
|
},
|
||||||
loadingRelationshipOne: false,
|
loadingTraffic: false,
|
||||||
loadingRelationshipTwo: false,
|
loadingRelationshipOne: false,
|
||||||
loadingNetworkQuality: false,
|
loadingRelationshipTwo: false,
|
||||||
loadingOut: false,
|
loadingNetworkQuality: false,
|
||||||
loadingIn: false,
|
loadingOut: false,
|
||||||
loadingAlert: false,
|
loadingIn: false,
|
||||||
loadingSecurityEvents: false,
|
loadingAlert: false,
|
||||||
loadingMap: false
|
loadingSecurityEvents: false,
|
||||||
}
|
loadingMap: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getMillisecond,
|
getMillisecond,
|
||||||
|
dateFormatByAppearance,
|
||||||
getQueryParams () {
|
getQueryParams () {
|
||||||
const queryParams = {
|
return {
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
endTime: getSecond(this.timeFilter.endTime),
|
endTime: getSecond(this.timeFilter.endTime),
|
||||||
domain: this.entity.domainName
|
resource: this.entity.entityValue,
|
||||||
|
domain: this.entity.entityValue
|
||||||
}
|
}
|
||||||
return queryParams
|
|
||||||
},
|
},
|
||||||
getPerformanceQueryParams () {
|
getPerformanceQueryParams () {
|
||||||
const queryParams = {
|
return {
|
||||||
domain: this.entity.domainName
|
domain: this.entity.entityValue
|
||||||
}
|
}
|
||||||
return queryParams
|
|
||||||
},
|
},
|
||||||
handleRelationData (result) {
|
handleRelationData (result) {
|
||||||
this.entityData.appCount = result.appCount
|
this.entityData.appCount = result.appCount
|
||||||
@@ -383,9 +366,10 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
setup (props) {
|
setup (props) {
|
||||||
|
const entityData = ref({ ...props.entity })
|
||||||
const entityCopy = {
|
const entityCopy = {
|
||||||
..._.cloneDeep(props.entity),
|
..._.cloneDeep(props.entity),
|
||||||
domain: props.entity.domainName
|
domain: props.entity.entityValue
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
chart: {
|
chart: {
|
||||||
@@ -398,7 +382,8 @@ export default {
|
|||||||
},
|
},
|
||||||
entityCopy,
|
entityCopy,
|
||||||
unitTypes,
|
unitTypes,
|
||||||
unitConvert
|
unitConvert,
|
||||||
|
entityData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,15 @@
|
|||||||
<div class="overview__content">
|
<div class="overview__content">
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('overall.location')}}</div>
|
<div class="row__label row__label--width130">{{$t('overall.location')}}</div>
|
||||||
<div class="row__content">{{ipLocationRegion(entity)}}</div>
|
<div class="row__content">{{ipLocationRegion(entity.location)}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__label row__label--width130">ASN</div>
|
<div class="row__label row__label--width130">ASN</div>
|
||||||
<div class="row__content">{{entity.ipAsn || '-'}}</div>
|
<div class="row__content">{{entity.asn ? entity.asn.asn : '-'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="overview__row">
|
||||||
|
<div class="row__label row__label--width130">{{$t('entities.openPort')}}</div>
|
||||||
|
<div class="row__content">{{ openPort }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -44,7 +48,7 @@
|
|||||||
<!-- 曲线-->
|
<!-- 曲线-->
|
||||||
<div class="row__content-loading">
|
<div class="row__content-loading">
|
||||||
<loading :loading="!loadingDns && loading" size="small"></loading>
|
<loading :loading="!loadingDns && loading" size="small"></loading>
|
||||||
<div class="row__charts" :id="`entityDnsServerInfo${entity.ipAddr}`"></div>
|
<div class="row__charts" :id="`entityDnsServerInfo${entity.entityValue}`"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -70,103 +74,77 @@
|
|||||||
<div class="row__charts-msg">{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps</div>
|
<div class="row__charts-msg">{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps</div>
|
||||||
<!-- 曲线-->
|
<!-- 曲线-->
|
||||||
<div class="row__content-loading">
|
<div class="row__content-loading">
|
||||||
<div class="row__charts" :id="`entityDetailSend${entity.ipAddr}`"></div>
|
<div class="row__charts" :id="`entityDetailSend${entity.entityValue}`"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row__content">
|
<div class="row__content row__content-accept">
|
||||||
<div class="row__charts-msg">{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps</div>
|
<div class="row__charts-msg">{{$t('overall.received')}}:{{unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ')}}ps</div>
|
||||||
<!-- 曲线-->
|
<!-- 曲线-->
|
||||||
<div class="row__content-loading">
|
<div class="row__content-loading">
|
||||||
<div class="row__charts" :id="`entityDetailReceived${entity.ipAddr}`"></div>
|
<div class="row__charts" :id="`entityDetailReceived${entity.entityValue}`"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="overview__row">
|
||||||
|
<div class="row__label row__label--width130">{{$t('entities.networkQualityRating')}}</div>
|
||||||
|
<loading :loading="loadingNetworkQuality" size="small" inner-style="left: 1rem;"></loading>
|
||||||
|
<div class="entity-score" v-if="!loadingNetworkQuality">
|
||||||
|
<div class="circle-icon" v-if="score <= 2 || score === '-'" :class="{'data-score-red': score <= 2 || score === '-'}" ></div>
|
||||||
|
<div class="circle-icon" v-else-if="score <= 4" :class="{'data-score-yellow': score <= 4}" ></div>
|
||||||
|
<div class="circle-icon" v-else-if="score <= 6" :class="{'data-score-green': score <= 6}" ></div>
|
||||||
|
Score:{{score}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overview-item">
|
<div class="overview-item">
|
||||||
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
||||||
<div class="overview__content domain__content">
|
<div class="overview__content domain__content">
|
||||||
<div class="overview__tags domain__tags" ref="relationship">
|
<div class="overview__tags domain__tags" ref="relationship"></div>
|
||||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
<div class="overview__row overview__row-related">
|
||||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
<div class="row__label row__label--width130">{{$t('entities.tab.relatedApp')}}</div>
|
||||||
<div class="overview__domain-tab">
|
|
||||||
<div class="overview__tag domain__tag">
|
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||||
<span class="tag__value">{{relationshipDataOne.length}}</span>
|
<div class="row__content">
|
||||||
<span class="tag__desc">{{$t('entities.relatedDomains')}}</span>
|
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
||||||
</div>
|
{{item.value}}
|
||||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
|
||||||
<span class="tag__desc">{{item.domain}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-btn">
|
|
||||||
<div class="overview__domain-more" @click="more(relationshipDataOne, 1)" v-if="relationshipShowOne">...</div>
|
<div v-if="relationshipShowOne">
|
||||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreOne" v-ele-click-outside="mouseout">
|
<el-popover placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataOne" :key="item">
|
<template #reference>
|
||||||
<span v-if="item.domain" :title="item.domain">{{item.domain}}</span>
|
<div class="data-item show-more-related">...</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
<div class="popover-content" v-for="(item, index) in relationshipDataOne" :key="index">{{item.value}}</div>
|
||||||
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
</div>
|
||||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
|
||||||
<div class="overview__domain-tab">
|
<div class="overview__row overview__row-related">
|
||||||
<div class="overview__tag domain__tag">
|
<div class="row__label row__label--width130">{{$t('entities.relatedDomain')}}</div>
|
||||||
<span class="tag__value">{{relationshipDataTwo.length}}</span>
|
|
||||||
<span class="tag__desc">{{$t('entities.relatedApp')}}</span>
|
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||||
</div>
|
<div class="row__content">
|
||||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||||
<span class="tag__desc">{{item.appName}}</span>
|
{{item.value}}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__domain-btn">
|
|
||||||
<div class="overview__domain-more" @click="more(relationshipDataTwo, 2)" v-if="relationshipShowTwo">...</div>
|
<div v-if="relationshipShowTwo">
|
||||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreTwo" v-ele-click-outside="mouseout">
|
<el-popover class="entity-expand-detail" placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataTwo" :key="item">
|
<template #reference>
|
||||||
<span v-if="item.appName" :title="item.appName">{{item.appName}}</span>
|
<div class="data-item show-more-related">...</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
<div v-for="(item, index) in relationshipDataTwo" :key="index">{{item.value}}</div>
|
||||||
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview-item">
|
|
||||||
<div class="overview__title">{{$t('overall.networkQuality')}}</div>
|
|
||||||
<div class="overview__content overview__content-loading-net">
|
|
||||||
<loading :loading="loadingNetworkQuality" size="small"></loading>
|
|
||||||
<div class="overview__row overview__row--single-value">
|
|
||||||
<chart-single-value
|
|
||||||
v-for="(chartInfo, i) in singleValues.chartInfos"
|
|
||||||
:chart-info="chartInfo"
|
|
||||||
:chart-data="singleValues.chartDatas[i]"
|
|
||||||
:key="i"
|
|
||||||
class="cn-chart__single-value--detail-overview"
|
|
||||||
></chart-single-value>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overview-item">
|
|
||||||
<div class="overview__title">{{$t('entities.accessLink')}}</div>
|
|
||||||
<div class="overview__content">
|
|
||||||
<div class="overview__tags">
|
|
||||||
<div class="overview__tag overview__tag-loading">
|
|
||||||
<loading :loading="loadingOut" size="small"></loading>
|
|
||||||
<span class="tag__desc">{{$t('entities.outLinkTrafficPercentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkOutId ? entityData.linkOutId : '-'}}, </span>
|
|
||||||
<span class="tag__desc">{{$t('entities.percentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkOutPercent ? unitConvert(entityData.linkOutPercent, unitTypes.percent).join(' ') : '-'}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="overview__tag overview__tag-loading">
|
|
||||||
<loading :loading="loadingIn" size="small"></loading>
|
|
||||||
<span class="tag__desc">{{$t('entities.inLinkTrafficPercentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkInId ? entityData.linkInId : '-'}}, </span>
|
|
||||||
<span class="tag__desc">{{$t('entities.percentage')}}</span>
|
|
||||||
<span class="tag__value">{{entityData.linkInPercent ? unitConvert(entityData.linkInPercent, unitTypes.percent).join(' ') : '-'}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overview-item">
|
<div class="overview-item">
|
||||||
<div class="overview__title">{{$t('overall.alert')}}</div>
|
<div class="overview__title">{{$t('overall.alert')}}</div>
|
||||||
<div class="overview__content overview__content-loading">
|
<div class="overview__content overview__content-loading">
|
||||||
@@ -175,18 +153,16 @@
|
|||||||
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row" v-if="performanceData.length > 0">
|
<div class="overview__row" v-if="performanceData.length > 0">
|
||||||
<div class="row__label">{{$t('entities.recentAlert')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.recentAlert')}}</div>
|
||||||
<div class="row__content">{{entityData.performanceNum}}</div>
|
<div class="row__content">{{entityData.performanceNum}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row overview__row--small-font" v-for="(performance, index) in entityData.performanceList" :key="index">
|
<div class="overview__row overview__row--small-font" v-for="(performance, index) in entityData.performanceList" :key="index">
|
||||||
<div class="row__label row__label--width160">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
<div class="row__label row__label--width130">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
||||||
<div class="row__content">
|
<div class="row__content row__content--width90">
|
||||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
||||||
<div>{{performance.eventType}}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row__content-loading" style="position: relative; padding-left: 10px;">
|
<div class="row__content-loading" style="position: relative;">
|
||||||
<loading :loading="!loadingAlert && loadingPerformance[index]?loadingPerformance[index]:false" :id="`loading${entity.ipAddr}_${index}`" size="small"></loading>
|
<div class="performance-event-remark">{{performance.eventType}}</div>
|
||||||
<div class="row__charts" :id="`entityPerformanceChart${entity.ipAddr}_${index}`"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row__desc"></div>
|
<div class="row__desc"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -203,15 +179,26 @@
|
|||||||
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row" v-if="securityData.length > 0">
|
<div class="overview__row" v-if="securityData.length > 0">
|
||||||
<div class="row__label">{{$t('entities.recentSecurity')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.recentSecurity')}}</div>
|
||||||
<div class="row__content">{{entityData.securityNum}}</div>
|
<div class="row__content">{{entityData.securityNum}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overview__row overview__row--small-font" v-for="(security, index) in entityData.securityList" :key="index">
|
<div class="overview__row overview__row--small-font" v-for="(security, index) in entityData.securityList" :key="index">
|
||||||
<div class="row__label row__label--width160">{{dateFormatByAppearance(security.startTime) || '-'}}</div>
|
<div class="row__label row__label--width130">{{dateFormatByAppearance(security.startTime) || '-'}}</div>
|
||||||
<div class="row__content row__content--width200">
|
<div class="row__content row__content--width90">
|
||||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(security)">{{security.eventSeverity}}</div>
|
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(security)">{{security.eventSeverity}}</div>
|
||||||
<div>{{security.securityType}}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cn-detection__header" >
|
||||||
|
<i class="cn-icon cn-icon-attacker"></i>
|
||||||
|
<span>{{ security.offenderIp }}</span>
|
||||||
|
<div class="domain" v-if="security.offenderIp===security.serverIp">{{ security.domain }}</div>
|
||||||
|
<span class="line">-------</span>
|
||||||
|
<span class="circle"></span>
|
||||||
|
<i class="cn-icon cn-icon-attacked"></i>
|
||||||
|
<span>{{ security.victimIp }}</span>
|
||||||
|
<div class="domain" v-if="security.victimIp===security.serverIp">{{ security.domain }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row__desc"></div>
|
<div class="row__desc"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="overview__row overview__row--small-font" v-if="securityData && securityData.length > 5">
|
<div class="overview__row overview__row--small-font" v-if="securityData && securityData.length > 5">
|
||||||
@@ -234,7 +221,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import entityDetailMixin from './entityDetailMixin'
|
import entityDetailMixin from './entityDetailMixin'
|
||||||
import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
|
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import { unitTypes } from '@/utils/constants'
|
import { unitTypes } from '@/utils/constants'
|
||||||
import unitConvert from '@/utils/unit-convert'
|
import unitConvert from '@/utils/unit-convert'
|
||||||
@@ -242,30 +228,35 @@ import Chart from '@/views/charts/Chart'
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { get } from '@/utils/http'
|
import { get } from '@/utils/http'
|
||||||
import relatedServer from '@/mixins/relatedServer'
|
import relatedServer from '@/mixins/relatedServer'
|
||||||
import { getSecond, getMillisecond } from '@/utils/date-util'
|
import { dateFormatByAppearance, getMillisecond, getSecond } from '@/utils/date-util'
|
||||||
import Loading from '@/components/common/Loading'
|
import Loading from '@/components/common/Loading'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Ip',
|
name: 'Ip',
|
||||||
mixins: [entityDetailMixin, relatedServer],
|
mixins: [entityDetailMixin, relatedServer],
|
||||||
components: {
|
components: {
|
||||||
Loading,
|
Loading,
|
||||||
Chart,
|
Chart
|
||||||
ChartSingleValue
|
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
entityType: 'ip',
|
entityType: 'ip',
|
||||||
trafficUrl: api.entityIpDetailTraffic,
|
// trafficUrl: api.entityIpDetailTraffic,
|
||||||
trafficUrlMap: api.entityIpDetailTrafficMap,
|
trafficUrl: api.entity.entityList.ipThroughput,
|
||||||
|
// trafficUrlMap: api.entityIpDetailTrafficMap,
|
||||||
|
trafficUrlMap: api.entity.entityList.ipTrafficMap,
|
||||||
relationUrl: api.entityIpDetailRelation,
|
relationUrl: api.entityIpDetailRelation,
|
||||||
networkQuantityUrl: api.entityIpDetailNetworkQuantity,
|
// networkQuantityUrl: api.entityIpDetailNetworkQuantity,
|
||||||
|
networkQuantityUrl: api.entity.entityList.ipPerformance,
|
||||||
linkInUrl: api.entityIpDetailLinkIn,
|
linkInUrl: api.entityIpDetailLinkIn,
|
||||||
linkOutUrl: api.entityIpDetailLinkOut,
|
linkOutUrl: api.entityIpDetailLinkOut,
|
||||||
performanceUrl: api.entityIpDetailPerformance,
|
performanceUrl: api.entity.entityList.ipEventPerformance,
|
||||||
securityUrl: api.entityIpDetailSecurity,
|
// performanceUrl: api.entityIpDetailPerformance,
|
||||||
relatedServerDomainUrl: api.entityIpRelatedServerDomain,
|
// securityUrl: api.entityIpDetailSecurity,
|
||||||
relatedServerAppUrl: api.entityIpRelatedServerApp,
|
securityUrl: api.entity.entityList.ipSecurity,
|
||||||
|
relatedServerDomainUrl: api.entity.entityList.ipRelatedDomain,
|
||||||
|
relatedServerAppUrl: api.entity.entityList.ipRelatedApp,
|
||||||
entityDetectionsIpUrl: api.entityDetectionsIp,
|
entityDetectionsIpUrl: api.entityDetectionsIp,
|
||||||
entityDetectionsIpQueryRateUrl: api.entityDetectionsIpQueryRate,
|
entityDetectionsIpQueryRateUrl: api.entityDetectionsIpQueryRate,
|
||||||
listMode: 'list',
|
listMode: 'list',
|
||||||
@@ -336,21 +327,22 @@ export default {
|
|||||||
loadingIn: false,
|
loadingIn: false,
|
||||||
loadingAlert: false,
|
loadingAlert: false,
|
||||||
loadingSecurityEvents: false,
|
loadingSecurityEvents: false,
|
||||||
loadingMap: false
|
loadingMap: false,
|
||||||
|
openPort: '-'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
ipLocationRegion () {
|
ipLocationRegion () {
|
||||||
return function (entityData) {
|
return function (entityData) {
|
||||||
let result = ''
|
let result = ''
|
||||||
if (entityData.ipLocationCountry) {
|
if (entityData.country) {
|
||||||
result += `${entityData.ipLocationCountry},`
|
result += `${entityData.country},`
|
||||||
}
|
}
|
||||||
if (entityData.ipLocationProvince) {
|
if (entityData.province) {
|
||||||
result += `${entityData.ipLocationProvince},`
|
result += `${entityData.province},`
|
||||||
}
|
}
|
||||||
if (entityData.ipLocationCity) {
|
if (entityData.city) {
|
||||||
result += `${entityData.ipLocationCity},`
|
result += `${entityData.city},`
|
||||||
}
|
}
|
||||||
result = result.substr(0, result.length - 1)
|
result = result.substr(0, result.length - 1)
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -381,19 +373,19 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getMillisecond,
|
getMillisecond,
|
||||||
|
dateFormatByAppearance,
|
||||||
getQueryParams () {
|
getQueryParams () {
|
||||||
const queryParams = {
|
return {
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
endTime: getSecond(this.timeFilter.endTime),
|
endTime: getSecond(this.timeFilter.endTime),
|
||||||
ip: this.entity.ipAddr
|
resource: this.entity.entityValue,
|
||||||
|
ip: this.entity.entityValue
|
||||||
}
|
}
|
||||||
return queryParams
|
|
||||||
},
|
},
|
||||||
getPerformanceQueryParams () {
|
getPerformanceQueryParams () {
|
||||||
const queryParams = {
|
return {
|
||||||
serverIp: this.entity.ipAddr
|
serverIp: this.entity.entityValue
|
||||||
}
|
}
|
||||||
return queryParams
|
|
||||||
},
|
},
|
||||||
handleRelationData (result) {
|
handleRelationData (result) {
|
||||||
this.entityData.appCount = result.appCount
|
this.entityData.appCount = result.appCount
|
||||||
@@ -411,11 +403,29 @@ export default {
|
|||||||
queryRelated () {
|
queryRelated () {
|
||||||
this.getRelatedServerDataOne(this.relatedServerDomainUrl)
|
this.getRelatedServerDataOne(this.relatedServerDomainUrl)
|
||||||
this.getRelatedServerDataTwo(this.relatedServerAppUrl)
|
this.getRelatedServerDataTwo(this.relatedServerAppUrl)
|
||||||
|
},
|
||||||
|
getOpenPort () {
|
||||||
|
const params = {
|
||||||
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
|
endTime: getSecond(this.timeFilter.endTime),
|
||||||
|
resource: this.entity.entityValue
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.get(api.entity.entityList.ipRelatedPort, { params: params }).then(res => {
|
||||||
|
if (res.data.code === 200 && res.data.data.result.length) {
|
||||||
|
this.openPort = ''
|
||||||
|
res.data.data.result.forEach(item => {
|
||||||
|
this.openPort += item.port + '/' + item.l7Protocol + ','
|
||||||
|
})
|
||||||
|
this.openPort = this.openPort.slice(0, -1)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.queryParams = this.getQueryParams()
|
this.queryParams = this.getQueryParams()
|
||||||
this.chartGetMap()
|
this.chartGetMap()
|
||||||
|
this.getOpenPort()
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.queryRelated()
|
this.queryRelated()
|
||||||
@@ -425,7 +435,7 @@ export default {
|
|||||||
setup (props) {
|
setup (props) {
|
||||||
const entityCopy = {
|
const entityCopy = {
|
||||||
..._.cloneDeep(props.entity),
|
..._.cloneDeep(props.entity),
|
||||||
ip: props.entity.ipAddr
|
ip: props.entity.entityValue
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
chart: {
|
chart: {
|
||||||
@@ -434,7 +444,7 @@ export default {
|
|||||||
unitType: 'number',
|
unitType: 'number',
|
||||||
valueColumn: 'sessions'
|
valueColumn: 'sessions'
|
||||||
},
|
},
|
||||||
id: props.entity.ipAddr,
|
id: props.entity.entityValue,
|
||||||
type: 2
|
type: 2
|
||||||
},
|
},
|
||||||
entityCopy,
|
entityCopy,
|
||||||
@@ -444,3 +454,110 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
//.type-content {
|
||||||
|
// margin-bottom:15px;
|
||||||
|
// display:flex;
|
||||||
|
// flex-flow: row wrap;
|
||||||
|
// width:100%;
|
||||||
|
.data-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(119,131,145,0.06);
|
||||||
|
border: 1px solid rgba(119,131,145,0.36);
|
||||||
|
border-radius: 2px;
|
||||||
|
height:28px;
|
||||||
|
padding:8px 15px;
|
||||||
|
margin-right:10px;
|
||||||
|
//margin-bottom:15px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #353636;
|
||||||
|
font-weight: 400;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.show-more-related {
|
||||||
|
height: 28px;
|
||||||
|
line-height: 28px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
.entity-score {
|
||||||
|
.circle-icon {
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
.data-score-red {
|
||||||
|
background: #E26154;
|
||||||
|
}
|
||||||
|
.data-score-yellow {
|
||||||
|
background: #E5A219;
|
||||||
|
}
|
||||||
|
.data-score-green {
|
||||||
|
background: #749F4D;
|
||||||
|
}
|
||||||
|
height:24px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #046ECA;
|
||||||
|
font-weight: 500;
|
||||||
|
display:flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.cn-detection__header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
color: #333333;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
color: #7b8fa2;
|
||||||
|
margin-right: 5px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
color: #da5656;
|
||||||
|
margin-left: 12px;
|
||||||
|
font-size: xx-small;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border: 2px solid #da5656;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.domain {
|
||||||
|
background: #EFF2F5;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333333;
|
||||||
|
letter-spacing: 0;
|
||||||
|
line-height: 14px;
|
||||||
|
margin-left: 5px;
|
||||||
|
font-style: italic;
|
||||||
|
padding: 0 2px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-popper {
|
||||||
|
min-width: 90px !important;
|
||||||
|
width: auto !important;
|
||||||
|
max-width: 300px !important;
|
||||||
|
max-height: 180px !important;
|
||||||
|
overflow: scroll !important;
|
||||||
|
line-height: 24px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { riskLevelMapping, unitTypes } from '@/utils/constants'
|
|||||||
import unitConvert from '@/utils/unit-convert'
|
import unitConvert from '@/utils/unit-convert'
|
||||||
import { shallowRef, markRaw } from 'vue'
|
import { shallowRef, markRaw } from 'vue'
|
||||||
import { metricOption } from '@/views/detections/options/detectionOptions'
|
import { metricOption } from '@/views/detections/options/detectionOptions'
|
||||||
import { sortBy, reverseSortBy } from '@/utils/tools'
|
import { sortBy, reverseSortBy, computeScore } from '@/utils/tools'
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
|
|
||||||
@@ -45,29 +45,13 @@ export default {
|
|||||||
metricChart: null,
|
metricChart: null,
|
||||||
performanceChartList: [],
|
performanceChartList: [],
|
||||||
loadingPerformance: [],
|
loadingPerformance: [],
|
||||||
|
score: '-', // 网络质量评分
|
||||||
performanceMetricEndTimeInterval: 3600 // 服务质量事件指标的结束时间与开始时间的秒间隔
|
performanceMetricEndTimeInterval: 3600 // 服务质量事件指标的结束时间与开始时间的秒间隔
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
entityName () {
|
entityName () {
|
||||||
let name
|
return this.entity.entityValue
|
||||||
switch (this.entity.entityType) {
|
|
||||||
case ('ip'): {
|
|
||||||
name = this.entity.ipAddr
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ('domain'): {
|
|
||||||
name = this.entity.domainName
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ('app'): {
|
|
||||||
name = this.entity.appName
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
},
|
},
|
||||||
appRisk () {
|
appRisk () {
|
||||||
return function (level) {
|
return function (level) {
|
||||||
@@ -234,7 +218,7 @@ export default {
|
|||||||
this.performanceChartList.push(metricChart)
|
this.performanceChartList.push(metricChart)
|
||||||
this.echartsArray.push(shallowRef(metricChart))
|
this.echartsArray.push(shallowRef(metricChart))
|
||||||
} else {
|
} else {
|
||||||
const chartDom = document.getElementById(`entityPerformanceChart${this.entityName}${index}`)
|
const chartDom = document.getElementById(`entityPerformanceChart${this.entityName}_${index}`)
|
||||||
chartDom.innerHTML = '<span style="padding-left:5px;">-</span>'
|
chartDom.innerHTML = '<span style="padding-left:5px;">-</span>'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -272,6 +256,14 @@ export default {
|
|||||||
if (this.networkQuantityUrl) {
|
if (this.networkQuantityUrl) {
|
||||||
get(this.networkQuantityUrl, this.getQueryParams()).then(response => {
|
get(this.networkQuantityUrl, this.getQueryParams()).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
|
const data = {
|
||||||
|
establishLatencyMs: response.data.result.establishLatencyValue || null,
|
||||||
|
httpResponseLatency: response.data.result.httpResponseLatencyValue || null,
|
||||||
|
sslConLatency: response.data.result.sslConLatencyValue || null,
|
||||||
|
tcpLostlenPercent: response.data.result.sequenceGapLossPercentValue || null,
|
||||||
|
pktRetransPercent: response.data.result.pktRetransPercentValue || null
|
||||||
|
}
|
||||||
|
this.score = computeScore(data)
|
||||||
this.entityData.establishLatencyValue = response.data.result.establishLatencyValue
|
this.entityData.establishLatencyValue = response.data.result.establishLatencyValue
|
||||||
this.entityData.establishLatencyP50 = response.data.result.establishLatencyP50
|
this.entityData.establishLatencyP50 = response.data.result.establishLatencyP50
|
||||||
this.entityData.establishLatencyP90 = response.data.result.establishLatencyP90
|
this.entityData.establishLatencyP90 = response.data.result.establishLatencyP90
|
||||||
@@ -389,11 +381,6 @@ export default {
|
|||||||
this.entityData.performanceNum = response.data.result.length
|
this.entityData.performanceNum = response.data.result.length
|
||||||
this.performanceData = response.data.result
|
this.performanceData = response.data.result
|
||||||
this.entityData.performanceList = this.getTargetPageData(1, this.showMore.performancePageSize, this.performanceData)
|
this.entityData.performanceList = this.getTargetPageData(1, this.showMore.performancePageSize, this.performanceData)
|
||||||
this.$nextTick(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.queryEntityDetailPerformanceChart(this.entityData.performanceList, 0)
|
|
||||||
}, 200)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
this.loadingAlert = false
|
this.loadingAlert = false
|
||||||
})
|
})
|
||||||
@@ -412,16 +399,16 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
performanceShowMore (num) {
|
performanceShowMore (num) {
|
||||||
const startIndex = this.showMore.performancePageSize
|
// const startIndex = this.showMore.performancePageSize
|
||||||
this.showMore.performancePageSize += num
|
this.showMore.performancePageSize += num
|
||||||
this.entityData.performanceList = this.getTargetPageData(this.showMore.pageNo, this.showMore.performancePageSize, this.performanceData)
|
this.entityData.performanceList = this.getTargetPageData(this.showMore.pageNo, this.showMore.performancePageSize, this.performanceData)
|
||||||
this.$nextTick(() => {
|
// this.$nextTick(() => {
|
||||||
setTimeout(() => {
|
// setTimeout(() => lltext
|
||||||
if (this.entityData.performanceList && this.entityData.performanceList.length > 0) {
|
// if (this.entityData.performanceList && this.entityData.performanceList.length > 0) {
|
||||||
this.queryEntityDetailPerformanceChart(this.entityData.performanceList.slice(startIndex, this.entityData.performanceList.length), startIndex)
|
// this.queryEntityDetailPerformanceChart(this.entityData.performanceList.slice(startIndex, this.entityData.performanceList.length), startIndex)
|
||||||
}
|
// }
|
||||||
}, 200)
|
// }, 200)
|
||||||
})
|
// })
|
||||||
},
|
},
|
||||||
|
|
||||||
securityShowMore (num) {
|
securityShowMore (num) {
|
||||||
@@ -520,6 +507,7 @@ export default {
|
|||||||
this.chartOption = _.cloneDeep(entityListLineOption)
|
this.chartOption = _.cloneDeep(entityListLineOption)
|
||||||
setTimeout(() => { this.queryEntityDetail() })
|
setTimeout(() => { this.queryEntityDetail() })
|
||||||
const _this = this
|
const _this = this
|
||||||
|
this.entityData = { ...this.entityData, ...this.entity }
|
||||||
this.emitter.on('switch-collapse', function () {
|
this.emitter.on('switch-collapse', function () {
|
||||||
setTimeout(() => { _this.queryEntityDetail() }, 200)
|
setTimeout(() => { _this.queryEntityDetail() }, 200)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -45,43 +45,10 @@ export default {
|
|||||||
return className
|
return className
|
||||||
},
|
},
|
||||||
entityType () {
|
entityType () {
|
||||||
let type
|
return this.entity.entityValue
|
||||||
switch (this.entityData.entityType) {
|
|
||||||
case 'ip': {
|
|
||||||
type = this.entityData.ipAddr
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'domain': {
|
|
||||||
type = this.entityData.domainName
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'app': {
|
|
||||||
type = this.entityData.appName
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return type
|
|
||||||
},
|
},
|
||||||
entityName () {
|
entityName () {
|
||||||
let name
|
return this.entity.entityValue
|
||||||
switch (this.entityData.entityType) {
|
|
||||||
case ('ip'): {
|
|
||||||
name = this.entity.ipAddr
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ('domain'): {
|
|
||||||
name = this.entity.domainName
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ('app'): {
|
|
||||||
name = this.entity.appName
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
},
|
},
|
||||||
appRisk () {
|
appRisk () {
|
||||||
return function (level) {
|
return function (level) {
|
||||||
@@ -94,32 +61,11 @@ export default {
|
|||||||
queryParams () {
|
queryParams () {
|
||||||
let params
|
let params
|
||||||
const now = window.$dayJs.tz().valueOf()
|
const now = window.$dayJs.tz().valueOf()
|
||||||
switch (this.entityData.entityType) {
|
// eslint-disable-next-line prefer-const
|
||||||
case ('ip'): {
|
params = {
|
||||||
params = {
|
startTime: this.timeFilter.startTime ? getSecond(this.timeFilter.startTime) : Math.floor(now / 1000 - 3600),
|
||||||
startTime: this.timeFilter.startTime ? getSecond(this.timeFilter.startTime) : Math.floor(now / 1000 - 3600),
|
endTime: this.timeFilter.endTime ? getSecond(this.timeFilter.endTime) : Math.floor(now / 1000),
|
||||||
endTime: this.timeFilter.endTime ? getSecond(this.timeFilter.endTime) : Math.floor(now / 1000),
|
resource: this.entityData.entityValue
|
||||||
ip: this.entityData.ipAddr
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ('domain'): {
|
|
||||||
params = {
|
|
||||||
startTime: this.timeFilter.startTime ? getSecond(this.timeFilter.startTime) : Math.floor(now / 1000 - 3600),
|
|
||||||
endTime: this.timeFilter.endTime ? getSecond(this.timeFilter.endTime) : Math.floor(now / 1000),
|
|
||||||
domain: this.entityData.domainName
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case ('app'): {
|
|
||||||
params = {
|
|
||||||
startTime: this.timeFilter.startTime ? getSecond(this.timeFilter.startTime) : Math.floor(now / 1000 - 3600),
|
|
||||||
endTime: this.timeFilter.endTime ? getSecond(this.timeFilter.endTime) : Math.floor(now / 1000),
|
|
||||||
appName: this.entityData.appName
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default: break
|
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
@@ -130,7 +76,7 @@ export default {
|
|||||||
path: '/entityDetail',
|
path: '/entityDetail',
|
||||||
query: {
|
query: {
|
||||||
entityType: this.entityData.entityType,
|
entityType: this.entityData.entityType,
|
||||||
entityName: this.entityData.ipAddr || this.entityData.domainName || this.entityData.appName
|
entityName: this.entityData.entityValue
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
window.open(href, '_blank')
|
window.open(href, '_blank')
|
||||||
@@ -140,7 +86,7 @@ export default {
|
|||||||
path: '/entityGraph',
|
path: '/entityGraph',
|
||||||
query: {
|
query: {
|
||||||
entityType: this.entityData.entityType,
|
entityType: this.entityData.entityType,
|
||||||
entityName: this.entityData.ipAddr || this.entityData.domainName || this.entityData.appName
|
entityName: this.entityData.entityValue
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
window.open(href, '_blank')
|
window.open(href, '_blank')
|
||||||
@@ -209,9 +155,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
endTime: getSecond(this.timeFilter.endTime),
|
endTime: getSecond(this.timeFilter.endTime),
|
||||||
appName: this.entityType,
|
resource: this.entityType
|
||||||
domain: this.entityType,
|
|
||||||
ip: this.entityType
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
queryEntityDetailTraffic () {
|
queryEntityDetailTraffic () {
|
||||||
@@ -295,30 +239,36 @@ export default {
|
|||||||
},
|
},
|
||||||
resize () {
|
resize () {
|
||||||
this.echartsArray.forEach(item => { item.value.resize() })
|
this.echartsArray.forEach(item => { item.value.resize() })
|
||||||
|
},
|
||||||
|
initUrl () {
|
||||||
|
if (this.entity.entityType) {
|
||||||
|
switch (this.entity.entityType) {
|
||||||
|
case 'ip': {
|
||||||
|
// this.trafficUrl = api.entityIpDetailTraffic
|
||||||
|
this.trafficUrl = api.entity.entityList.ipThroughput
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'domain': {
|
||||||
|
// this.trafficUrl = api.entityDomainDetailTraffic
|
||||||
|
this.trafficUrl = api.entity.entityList.domainThroughput
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'app': {
|
||||||
|
// this.trafficUrl = api.entityAppDetailTraffic
|
||||||
|
this.trafficUrl = api.entity.entityList.appThroughput
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
entityData: {
|
entityData: {
|
||||||
deep: true,
|
deep: true,
|
||||||
handler (n) {
|
handler (n) {
|
||||||
if (n.entityType) {
|
this.initUrl()
|
||||||
switch (n.entityType) {
|
|
||||||
case 'ip': {
|
|
||||||
this.trafficUrl = api.entityIpDetailTraffic
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'domain': {
|
|
||||||
this.trafficUrl = api.entityDomainDetailTraffic
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'app': {
|
|
||||||
this.trafficUrl = api.entityAppDetailTraffic
|
|
||||||
break
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -326,7 +276,9 @@ export default {
|
|||||||
this.debounceFunc = this.$_.debounce(this.resize, 200)
|
this.debounceFunc = this.$_.debounce(this.resize, 200)
|
||||||
window.addEventListener('resize', this.debounceFunc)
|
window.addEventListener('resize', this.debounceFunc)
|
||||||
this.chartOption = _.cloneDeep(entityListLineOption)
|
this.chartOption = _.cloneDeep(entityListLineOption)
|
||||||
this.entityData = _.cloneDeep(this.entity)
|
// this.entityData = _.cloneDeep(this.entity)
|
||||||
|
this.entityData = { ...this.entityData, ...this.entity }
|
||||||
|
this.initUrl()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.querySecurity()
|
this.querySecurity()
|
||||||
this.queryEntityDetailTraffic()
|
this.queryEntityDetailTraffic()
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
<div class="explorer-search">
|
<div class="explorer-search">
|
||||||
<div class="explorer-search__title" v-show="!showList">{{$t('search.title')}}</div>
|
<div class="explorer-search__title" v-show="!showList">{{$t('search.title')}}</div>
|
||||||
<div class="explorer-search__input-case" :class="{'explorer-search__input-case--question-mark-in-line': showList}">
|
<div class="explorer-search__input-case" :class="{'explorer-search__input-case--question-mark-in-line': showList}">
|
||||||
<div class="explorer-search__input">
|
<div class="explorer-search__input" style="border: 1px #DEDEDE solid;height: 42px;">
|
||||||
<!--新版实体列表改版,后续记得解开-->
|
|
||||||
<!--<div class="explorer-search__input" style="border: 1px #DEDEDE solid;height: 42px;">-->
|
|
||||||
<advanced-search
|
<advanced-search
|
||||||
ref="search"
|
ref="search"
|
||||||
:column-list="columnList"
|
:column-list="columnList"
|
||||||
|
|||||||
Reference in New Issue
Block a user