CN-1150: 实体列表接口对接
This commit is contained in:
@@ -10,10 +10,9 @@
|
||||
right: 10px;
|
||||
|
||||
.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;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@@ -222,3 +222,10 @@
|
||||
padding: 0 4px;
|
||||
//color: white;
|
||||
}
|
||||
|
||||
.performance-event-remark {
|
||||
font-family: NotoSansSChineseRegular;
|
||||
font-size: 12px;
|
||||
color: #353636;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@@ -1,104 +1,100 @@
|
||||
.entity-filter-case {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 280px;
|
||||
margin-right: 10px;
|
||||
width: 320px;
|
||||
margin-right: 20px;
|
||||
overflow: auto;
|
||||
z-index: 1;
|
||||
border: 1px solid rgba(226, 229, 236, 1) !important;
|
||||
border-radius: 4px !important;
|
||||
|
||||
.filter-case__header {
|
||||
background-color: #E1E6ED;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 8px;
|
||||
height: 36px;
|
||||
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;
|
||||
padding-left: 8px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
color: #666;
|
||||
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__row {
|
||||
padding: 0 15px;
|
||||
|
||||
.filter__header {
|
||||
height: 46px;
|
||||
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;
|
||||
cursor: pointer;
|
||||
transition: all linear .2s;
|
||||
.filter__row-popover {
|
||||
display: flex;
|
||||
line-height: 26px;
|
||||
font-size: 14px;
|
||||
color: #353636;
|
||||
font-weight: 400;
|
||||
|
||||
.filter-country-flag {
|
||||
width: 18px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
&:hover, &.filter__row--active {
|
||||
background-color: #F3F7FA;
|
||||
}
|
||||
.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;
|
||||
.filter__body-item-left-index {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
.chart__loading img {
|
||||
left: unset;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.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);
|
||||
background: #EFF2F5;
|
||||
border-radius: 2px;
|
||||
margin-right: 6px;
|
||||
font-family: NotoSansHans-Black;
|
||||
font-size: 9px;
|
||||
color: #96A2B0;
|
||||
font-weight: 900;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.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;
|
||||
border-radius: 2px;
|
||||
transition: all .2s;
|
||||
//border: 1px solid #E2E5EC; 新版实体列表改版,后续记得解开
|
||||
border: 1px solid #E2E5EC;
|
||||
|
||||
&:hover .cn-entity__header .header__content {
|
||||
|
||||
|
||||
@@ -160,6 +160,10 @@
|
||||
&:last-of-type {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.el-popper {
|
||||
min-width: 90px !important;
|
||||
}
|
||||
}
|
||||
.row__content-accept {
|
||||
margin-left: 39px;
|
||||
@@ -187,6 +191,12 @@
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.overview__row-related {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.overview__content.domain__content {
|
||||
@@ -306,3 +316,8 @@
|
||||
.margin-l-140 {
|
||||
margin-left: 140px;
|
||||
}
|
||||
|
||||
.line-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.entity-list {
|
||||
width: calc(100% - 290px);
|
||||
width: 100%;
|
||||
height: calc(100% - 42px);
|
||||
flex: 1;
|
||||
position: relative;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
.cn-entity--list {
|
||||
display: flex;
|
||||
//border: 1px #E2E5EC solid;
|
||||
//margin-bottom: 10px;
|
||||
//border-radius: 4px;
|
||||
// 新版实体列表改版,后续记得解开
|
||||
border: 1px #E2E5EC solid;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 4px;
|
||||
|
||||
.cn-entity__collapse {
|
||||
margin-bottom: 1px;
|
||||
@@ -13,8 +12,8 @@
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
background-color: #F3F7FA;
|
||||
//border-radius: 4px 0 0 4px;
|
||||
// 新版实体列表改版,后续记得解开
|
||||
border-radius: 4px 0 0 4px;
|
||||
|
||||
span {
|
||||
transform: rotate(0);
|
||||
transition: all linear .2s;
|
||||
@@ -41,12 +40,12 @@
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
//align-content: center;
|
||||
align-content: center;
|
||||
padding: 16px 0;
|
||||
margin-bottom: 1px;
|
||||
background-color: white;
|
||||
//border-radius: 0 4px 4px 0;
|
||||
// 新版实体列表改版,后续记得解开
|
||||
border-radius: 0 4px 4px 0;
|
||||
|
||||
.cn-entity__icon {
|
||||
margin-left: 26px;
|
||||
margin-right: 10px;
|
||||
@@ -77,13 +76,12 @@
|
||||
font-size: 16px;
|
||||
padding-bottom: 3px;
|
||||
color: #333333;
|
||||
//.cn-entity__header-title {
|
||||
// margin-right: 10px;
|
||||
//}
|
||||
//.cn-entity__header-tag {
|
||||
//
|
||||
//}
|
||||
// 新版实体列表改版,后续记得解开
|
||||
.cn-entity__header-title {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.cn-entity__header-tag {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.cn-entity__body {
|
||||
@@ -161,27 +159,21 @@
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//.show-detail {
|
||||
// flex-shrink: 0;
|
||||
// padding: 0 30px;
|
||||
// font-size: 12px;
|
||||
// color: #3976CB;
|
||||
// //color: #2C72C6;
|
||||
// //font-weight: 400;
|
||||
// //margin-top: -17px;
|
||||
// // 新版实体列表改版,后续记得解开
|
||||
//
|
||||
// &:hover {
|
||||
// cursor: pointer;
|
||||
// }
|
||||
//
|
||||
// //i {
|
||||
// // font-size: 12px;
|
||||
// // margin-right: 5px;
|
||||
// //}
|
||||
//}
|
||||
.row-item-label {
|
||||
font-family: NotoSansSChineseRegular;
|
||||
font-size: 14px;
|
||||
color: #717171;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.row-item-value {
|
||||
font-family: NotoSansSChineseRegular;
|
||||
font-size: 14px;
|
||||
color: #353636;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,13 +75,10 @@
|
||||
</div>
|
||||
<div class="tag-search__add" @click="addCondition">{{$t('entities.advancedSearch.add')}}</div>
|
||||
<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>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -440,20 +437,19 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<!--// 新版实体列表改版,后续记得解开-->
|
||||
<!--<style lang="scss">-->
|
||||
<!--.new-search__suffix {-->
|
||||
<!-- width: 41px;-->
|
||||
<!-- height: 41px;-->
|
||||
<!-- line-height: 41px;-->
|
||||
<!-- background: #38ACD2;-->
|
||||
<!-- text-align: center;-->
|
||||
<!-- margin-top: -10px;-->
|
||||
<!-- margin-right: -10px;-->
|
||||
<style lang="scss">
|
||||
.new-search__suffix {
|
||||
width: 41px;
|
||||
height: 41px;
|
||||
line-height: 41px;
|
||||
background: #38ACD2;
|
||||
text-align: center;
|
||||
margin-top: -10px;
|
||||
margin-right: -10px;
|
||||
|
||||
<!-- .el-icon-search {-->
|
||||
<!-- color: #fff !important;-->
|
||||
<!-- margin-top: 9px !important;-->
|
||||
<!-- }-->
|
||||
<!--}-->
|
||||
<!--</style>-->
|
||||
.el-icon-search {
|
||||
color: #fff !important;
|
||||
margin-top: 9px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,13 +4,12 @@
|
||||
></textarea>
|
||||
<div class="search__suffixes search__suffixes--text-mode">
|
||||
<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 class="search__suffix-close" @click="cleanParams">-->
|
||||
<!-- <i class="el-icon-error"></i>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="search__suffix new-search__suffix" @click="search">-->
|
||||
<div class="search__suffix" @click="search">
|
||||
<div class="search__suffix-close" @click="cleanParams">
|
||||
<i class="el-icon-error"></i>
|
||||
</div>
|
||||
<div class="search__suffix new-search__suffix" @click="search">
|
||||
<i class="el-icon-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,9 +42,9 @@ export default {
|
||||
},
|
||||
emits: ['changeMode', 'search'],
|
||||
methods: {
|
||||
// cleanParams () {
|
||||
// toRaw(this.codeMirror).setValue('')
|
||||
// },
|
||||
cleanParams () {
|
||||
toRaw(this.codeMirror).setValue('')
|
||||
},
|
||||
initCodeMirror () {
|
||||
this.codeMirror = CodeMirror.fromTextArea(this.$refs.textSearch, {
|
||||
mode: {
|
||||
@@ -189,28 +188,28 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<!--<style lang="scss">-->
|
||||
<!--.search__suffix-close {-->
|
||||
<!-- .el-icon-error {-->
|
||||
<!-- font-size: 17px;-->
|
||||
<!-- color: #C4C4C4;-->
|
||||
<!-- margin: 0 12px;-->
|
||||
<!-- cursor: pointer;-->
|
||||
<!-- }-->
|
||||
<!--}-->
|
||||
<style lang="scss">
|
||||
.search__suffix-close {
|
||||
.el-icon-error {
|
||||
font-size: 17px;
|
||||
color: #C4C4C4;
|
||||
margin: 0 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
<!--.new-search__suffix {-->
|
||||
<!-- width: 41px;-->
|
||||
<!-- height: 41px;-->
|
||||
<!-- line-height: 41px;-->
|
||||
<!-- background: #38ACD2;-->
|
||||
<!-- text-align: center;-->
|
||||
<!-- margin-top: -10px;-->
|
||||
<!-- margin-right: -10px;-->
|
||||
.new-search__suffix {
|
||||
width: 41px;
|
||||
height: 41px;
|
||||
line-height: 41px;
|
||||
background: #38ACD2;
|
||||
text-align: center;
|
||||
margin-top: -10px;
|
||||
margin-right: -10px;
|
||||
|
||||
<!-- .el-icon-search {-->
|
||||
<!-- color: #fff !important;-->
|
||||
<!-- margin-top: 9px !important;-->
|
||||
<!-- }-->
|
||||
<!--}-->
|
||||
<!--</style>-->
|
||||
.el-icon-search {
|
||||
color: #fff !important;
|
||||
margin-top: 9px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -20,10 +20,7 @@ export default {
|
||||
entityDetectionStyle () {
|
||||
const route = this.$route.name !== undefined ? this.$route.name : this.$route
|
||||
if (listScrollPath.indexOf(route.path) > -1) {
|
||||
// 新版实体列表改版,后续记得解开
|
||||
const style = route.path === listScrollPath[0] ? 'overflow:auto;background-color: #EFF2F5;' : 'overflow:auto;'
|
||||
// const style = 'overflow:auto;'
|
||||
return style
|
||||
return 'overflow:auto;'
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
|
||||
@@ -19,7 +19,12 @@ export default {
|
||||
this.loadingRelationshipOne = true
|
||||
get(relationshipUrlOne, this.getQueryParams()).then(response => {
|
||||
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)
|
||||
}
|
||||
@@ -30,7 +35,12 @@ export default {
|
||||
this.loadingRelationshipTwo = true
|
||||
get(relationshipUrlTow, this.getQueryParams()).then(response => {
|
||||
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)
|
||||
}
|
||||
@@ -45,7 +55,7 @@ export default {
|
||||
let flag = true
|
||||
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) {
|
||||
sum += width
|
||||
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) => {
|
||||
@@ -467,3 +761,31 @@ const getQuery = (url) => {
|
||||
}
|
||||
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',
|
||||
ipRelatedApp: apiVersion + '/entity/graph/relation/ip/relate/apps',
|
||||
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'
|
||||
},
|
||||
{
|
||||
name: 'ip_location_country',
|
||||
name: 'country',
|
||||
type: 'string',
|
||||
label: 'IP.Country'
|
||||
},
|
||||
@@ -292,12 +292,12 @@ export const columnList = [
|
||||
label: 'IP.Province'
|
||||
},
|
||||
{
|
||||
name: 'ip_location_city',
|
||||
name: 'region',
|
||||
type: 'string',
|
||||
label: 'IP.City'
|
||||
},
|
||||
{
|
||||
name: 'ip_asn',
|
||||
name: 'asn',
|
||||
type: 'string',
|
||||
label: 'IP.ASN'
|
||||
},
|
||||
@@ -367,7 +367,7 @@ export const columnList = [
|
||||
label: 'Domain.Whois address'
|
||||
},
|
||||
{
|
||||
name: 'domain_whois_city',
|
||||
name: 'region',
|
||||
type: 'string',
|
||||
label: 'Domain.Whois city'
|
||||
},
|
||||
@@ -377,7 +377,7 @@ export const columnList = [
|
||||
label: 'Domain.Whois state'
|
||||
},
|
||||
{
|
||||
name: 'domain_whois_country',
|
||||
name: 'country',
|
||||
type: 'string',
|
||||
label: 'Domain.Whois country'
|
||||
},
|
||||
|
||||
@@ -3,60 +3,60 @@
|
||||
class="entity-explorer"
|
||||
:class="{'entity-explorer--show-list': showList}">
|
||||
<!-- 顶部工具栏,在列表页显示 -->
|
||||
<!-- <div class="explorer-top-tools explorer-top-tools-new" v-show="showList">-->
|
||||
<!-- <div class="explorer-detection-top-tools">-->
|
||||
<!-- <div class="explorer-top-tools-title">{{$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 class="explorer-top-tools explorer-top-tools-new" style="margin: 2px 0;" v-show="showList">
|
||||
<div class="explorer-detection-top-tools">
|
||||
<div class="explorer-top-tools-title" style="padding: 0;margin-left: -10px;">{{$t('network.entity')}}</div>
|
||||
</div>
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<!-- 搜索组件 -->
|
||||
<explorer-search
|
||||
v-if="!showList"
|
||||
ref="search"
|
||||
:class="{'explorer-search--show-list': showList}"
|
||||
:show-list="showList"
|
||||
@search="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 style="display: flex; height: auto;">
|
||||
<entity-filter
|
||||
:filter-data="filterData"
|
||||
:loading-left="loadingLeft"
|
||||
:q="q"
|
||||
:time-filter="timeFilter"
|
||||
@filter="filter"
|
||||
></entity-filter>
|
||||
<entity-list
|
||||
:list-data="listData"
|
||||
:list-mode="listMode"
|
||||
:pageObj="pageObj"
|
||||
:time-filter="timeFilter"
|
||||
@pageSize="pageSize"
|
||||
@pageNo="pageNo"
|
||||
:loading="listLoading"
|
||||
></entity-list>
|
||||
<div v-if="showList" style="display: flex;flex-direction: row;">
|
||||
<entity-filter
|
||||
:filter-data="newFilterData"
|
||||
:loading-left="loadingLeft"
|
||||
:q="q"
|
||||
:time-filter="timeFilter"
|
||||
@filter="filter"
|
||||
></entity-filter>
|
||||
<div class="explorer-container" style="height: calc(100% - 62px);flex-direction: column;width: 100%;">
|
||||
<explorer-search
|
||||
ref="search"
|
||||
:class="{'explorer-search--show-list': showList}"
|
||||
:show-list="showList"
|
||||
@search="search"
|
||||
></explorer-search>
|
||||
|
||||
<div style="display: flex;flex-direction: column;height: calc(100% - 42px);">
|
||||
<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 class="explorer-foot" v-else>
|
||||
|
||||
<div class="explorer-foot" v-if="!showList">
|
||||
<div>
|
||||
<el-divider direction="vertical"></el-divider>
|
||||
<div class="entity-overview">
|
||||
@@ -150,8 +150,6 @@
|
||||
|
||||
<script>
|
||||
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 EntityList from '@/views/entityExplorer/entityList/EntityList'
|
||||
import { entityType, defaultPageSize, riskLevelMapping } from '@/utils/constants'
|
||||
@@ -172,8 +170,6 @@ export default {
|
||||
components: {
|
||||
Loading,
|
||||
ExplorerSearch,
|
||||
DateTimeRange,
|
||||
TimeRefresh,
|
||||
EntityFilter,
|
||||
EntityList
|
||||
},
|
||||
@@ -210,23 +206,15 @@ export default {
|
||||
{
|
||||
label: this.$t('overall.country'),
|
||||
column: 'countryDistinctCount',
|
||||
topColumn: 'ip_location_country', // top弹框查询字段
|
||||
topColumn: 'country', // top弹框查询字段
|
||||
icon: 'cn-icon cn-icon-country',
|
||||
showTopTen: false,
|
||||
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'),
|
||||
column: 'cityDistinctCount',
|
||||
topColumn: 'ip_location_city', // top弹框查询字段
|
||||
topColumn: 'region', // top弹框查询字段
|
||||
icon: 'cn-icon cn-icon-city',
|
||||
showTopTen: false,
|
||||
value: 0
|
||||
@@ -234,7 +222,7 @@ export default {
|
||||
{
|
||||
label: this.$t('entities.asn'),
|
||||
column: 'asnDistinctCount',
|
||||
topColumn: 'ip_asn', // top弹框查询字段
|
||||
topColumn: 'asn', // top弹框查询字段
|
||||
icon: 'cn-icon cn-icon-cloud',
|
||||
showTopTen: false,
|
||||
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: [],
|
||||
q: '',
|
||||
metaList: [],
|
||||
@@ -367,7 +375,14 @@ export default {
|
||||
// 实体详情列表页面 左侧筛选条件
|
||||
loadingLeft: false,
|
||||
initFlag: false, // 初始化标志,避免初始化时pageSize和pageNo会调用搜索
|
||||
timer: null // 初始化标志的延时器,需要销毁
|
||||
timer: null, // 初始化标志的延时器,需要销毁
|
||||
summaryCount: {
|
||||
total: 0,
|
||||
fqdnCount: 0,
|
||||
ipCount: 0,
|
||||
appCount: 0
|
||||
},
|
||||
loadingCount: false // 实体基数统计的loading
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -420,6 +435,12 @@ export default {
|
||||
return result
|
||||
},
|
||||
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 metaList
|
||||
if (param) {
|
||||
@@ -489,29 +510,35 @@ export default {
|
||||
} else {
|
||||
this.limitFilterType = false
|
||||
}
|
||||
this.queryFilter({ entityType: entityType, q: this.q, ...this.timeFilter })
|
||||
if (entityType === 'ip') {
|
||||
this.queryFilter({ entityType: 'dns', q: this.q, ...this.timeFilter })
|
||||
}
|
||||
// this.queryFilter({ entityType: entityType, q: this.q, ...this.timeFilter })
|
||||
// if (entityType === 'ip') {
|
||||
// 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.queryListTotal({ q: this.q, ...this.timeFilter })
|
||||
this.queryCount({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
||||
// this.queryListTotal({ q: this.q, ...this.timeFilter })
|
||||
} else {
|
||||
this.limitFilterType = false
|
||||
this.queryFilter({ entityType: 'ip', 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: 'dns', 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: 'app', 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.queryListTotal({ q: this.q, ...this.timeFilter })
|
||||
this.queryCount({ q: this.q, ...this.pageObj, ...this.timeFilter })
|
||||
// this.queryListTotal({ q: this.q, ...this.timeFilter })
|
||||
}
|
||||
} else {
|
||||
this.limitFilterType = false
|
||||
this.queryFilter({ entityType: 'ip', ...this.timeFilter })
|
||||
this.queryFilter({ entityType: 'app', ...this.timeFilter })
|
||||
this.queryFilter({ entityType: 'domain', ...this.timeFilter })
|
||||
this.queryFilter({ entityType: 'dns', ...this.timeFilter })
|
||||
// this.queryFilter({ entityType: 'ip', ...this.timeFilter })
|
||||
// this.queryFilter({ entityType: 'app', ...this.timeFilter })
|
||||
// this.queryFilter({ entityType: 'domain', ...this.timeFilter })
|
||||
// this.queryFilter({ entityType: 'dns', ...this.timeFilter })
|
||||
this.queryFilterNew({ ...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也会调用“搜索”的情况
|
||||
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) {
|
||||
this.listLoading = true
|
||||
const queryParams = {
|
||||
...params,
|
||||
startTime: getSecond(params.startTime),
|
||||
endTime: getSecond(params.endTime)
|
||||
// startTime: getSecond(params.startTime),
|
||||
// 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) {
|
||||
this.listData = []
|
||||
this.$nextTick(() => {
|
||||
this.listData = response.data.result
|
||||
this.listData = response.data.list
|
||||
this.pageObj.total = response.data.total
|
||||
})
|
||||
} else {
|
||||
console.error(response.message)
|
||||
this.$message.error(response.message)
|
||||
}
|
||||
}).finally(() => {
|
||||
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) {
|
||||
const queryParams = {
|
||||
@@ -677,11 +764,6 @@ export default {
|
||||
},
|
||||
|
||||
getEntityIndexData () {
|
||||
const now = window.$dayJs.tz().valueOf()
|
||||
const timeFilter = {
|
||||
startTime: parseInt(now / 1000 - 3600),
|
||||
endTime: parseInt(now / 1000)
|
||||
}
|
||||
// Total
|
||||
this.loadingApp = true
|
||||
this.loadingDomain = true
|
||||
@@ -695,61 +777,37 @@ export default {
|
||||
this.loadingDomainActive = true
|
||||
this.loadingIpActive = true
|
||||
|
||||
get(api.entityTotal, { entityType: 'app' }).then(response => {
|
||||
get(api.entity.entityList.entityActive).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityAppTotal = response.data.result
|
||||
}
|
||||
this.loadingApp = false
|
||||
})
|
||||
get(api.entityTotal, { entityType: 'domain' }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityDomainTotal = response.data.result
|
||||
this.entityDomainTotal = response.data.domainCount
|
||||
this.entityIpTotal = response.data.ipCount
|
||||
this.entityAppTotal = response.data.appCount
|
||||
}
|
||||
this.loadingDomain = false
|
||||
})
|
||||
get(api.entityTotal, { entityType: 'ip' }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityIpTotal = response.data.result
|
||||
}
|
||||
this.loadingIp = false
|
||||
this.loadingApp = false
|
||||
})
|
||||
// New
|
||||
get(api.entityNew, { entityType: 'app', ...timeFilter }).then(response => {
|
||||
get(api.entity.entityList.entityNew).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityAppNew = response.data.result
|
||||
}
|
||||
this.loadingAppNew = false
|
||||
})
|
||||
get(api.entityNew, { entityType: 'domain', ...timeFilter }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityDomainNew = response.data.result
|
||||
this.entityDomainNew = response.data.domainCount
|
||||
this.entityIpNew = response.data.ipCount
|
||||
this.entityAppNew = response.data.appCount
|
||||
}
|
||||
this.loadingDomainNew = false
|
||||
})
|
||||
get(api.entityNew, { entityType: 'ip', ...timeFilter }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityIpNew = response.data.result
|
||||
}
|
||||
this.loadingIpNew = false
|
||||
this.loadingAppNew = false
|
||||
})
|
||||
// Active
|
||||
get(api.entityActive, { entityType: 'app', ...timeFilter }).then(response => {
|
||||
get(api.entity.entityList.entityActive).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityAppActive = response.data.result
|
||||
}
|
||||
this.loadingAppActive = false
|
||||
})
|
||||
get(api.entityActive, { entityType: 'domain', ...timeFilter }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityDomainActive = response.data.result
|
||||
this.entityDomainActive = response.data.domainCount
|
||||
this.entityIpActive = response.data.ipCount
|
||||
this.entityAppActive = response.data.appCount
|
||||
}
|
||||
this.loadingDomainActive = false
|
||||
})
|
||||
get(api.entityActive, { entityType: 'ip', ...timeFilter }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.entityIpActive = response.data.result
|
||||
}
|
||||
this.loadingIpActive = false
|
||||
this.loadingAppActive = false
|
||||
})
|
||||
},
|
||||
cleanFilterData (index) {
|
||||
|
||||
@@ -1,150 +1,76 @@
|
||||
<template >
|
||||
<template>
|
||||
<div class="entity-filter-case">
|
||||
<div class="filter-case__header">{{$t('entities.filter')}}</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-case__header">{{ $t('entities.filter1') }}</div>
|
||||
|
||||
<div class="filter__row" v-for="(item, i) in filters.data" :key="i">
|
||||
<el-popover popper-class="filter__row-popover" placement="right-start" :width="440" v-model:visible="item.showTopTen">
|
||||
<template #reference>
|
||||
<div class="filter__row-popover" @click="showTopDialog(i, item, filters)">
|
||||
<div class="row__label">
|
||||
<i :class="item.icon"></i>
|
||||
<span>{{item.label}}</span>
|
||||
</div>
|
||||
<div class="row__value">
|
||||
<loading :loading="loadingLeft" size="small"></loading>
|
||||
<span>{{item.value}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<entity-top
|
||||
ref="entityTopTenPop"
|
||||
:loading="loading"
|
||||
:popover-data="popoverData"
|
||||
:item-data="itemData"
|
||||
:total-count="totalCount"
|
||||
:top-column="item.topColumn"
|
||||
@filter="filter"
|
||||
></entity-top>
|
||||
</el-popover>
|
||||
<div class="entity-filter" v-for="(item, index) in filterData" :key="index">
|
||||
<div class="filter__header">
|
||||
<i :class="item.icon"></i>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
|
||||
<div class="filter__body" style="position: relative">
|
||||
<loading :loading="loadingLeft" style="top: -5px;"></loading>
|
||||
<div class="filter__body-item" v-for="(data, i) in item.data" :key="i" @click="filter(data.label, data)">
|
||||
<div class="filter__body-item-left">
|
||||
<!-- 当前无更好方案匹配国旗,后续解决-->
|
||||
<!-- <div v-if="data.flag">-->
|
||||
<!-- <img :src="require(`../../../public/images/flag/${data.flag}.svg`)" class="filter-country-flag"/>-->
|
||||
<!-- </div>-->
|
||||
<div class="filter__body-item-left-index">{{ i+1 }}</div>
|
||||
<div class="filter__body-item-left-label">
|
||||
<el-tooltip :content="data.label" placement="top" effect="light" :disabled="disabledLabel">
|
||||
<span @mouseenter="handleMouse(`filter${index}${i}`)" :id="`filter${index}${i}`">{{ data.label }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter__body-item-right">{{ data.value }}</div>
|
||||
</div>
|
||||
<div class="filter-hr"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EntityTop from '@/views/entityExplorer/EntityTop'
|
||||
import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import Loading from '@/components/common/Loading'
|
||||
import { getSecond } from '@/utils/date-util'
|
||||
export default {
|
||||
name: 'EntityFilter',
|
||||
components: {
|
||||
Loading,
|
||||
EntityTop
|
||||
},
|
||||
components: { Loading },
|
||||
props: {
|
||||
filterData: Array,
|
||||
q: String,
|
||||
timeFilter: Object,
|
||||
loadingLeft: Boolean
|
||||
filterData: {
|
||||
type: Object
|
||||
},
|
||||
loadingLeft: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
topList: 'list',
|
||||
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
|
||||
}
|
||||
disabledLabel: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showTopDialog (i, item, filter) {
|
||||
if (this.currentColumn.column === item.column && item.showTopTen) {
|
||||
item.showTopTen = false
|
||||
return
|
||||
/**
|
||||
* 判断文字是否溢出,超出则鼠标移入tooltip显示,否则鼠标移入不显示
|
||||
* @param id
|
||||
*/
|
||||
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) {
|
||||
this.showTopDialog('', topData)
|
||||
this.$emit('filter', name, topData)
|
||||
filter (name, data) {
|
||||
this.$emit('filter', name, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -9,75 +9,76 @@
|
||||
<div class="cn-entity__case">
|
||||
<div class="cn-entity__icon"><i :class="iconClass"></i></div>
|
||||
<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">-->
|
||||
<!-- <span class="cn-entity__header-title">{{ entityData.ipAddr || entityData.domainName || entityData.appName || 'Unknown' }}</span>-->
|
||||
<!-- <span class="entity-detail" style="display: flex">-->
|
||||
<!-- <span style="width: 62px;" class="entity-tag entity-tag--small entity-tag--level-two-positive margin-r-6">信息技术</span>-->
|
||||
<!-- <span style="width: 50px;" class="entity-tag entity-tag--small entity-tag--level-two-normal margin-r-6">互联网</span>-->
|
||||
<!-- </span>-->
|
||||
<!--标签-->
|
||||
<div class="cn-entity__header" style="display: flex;align-items: center">
|
||||
<span class="cn-entity__header-title">{{ entityData.entityValue || 'Unknown' }}</span>
|
||||
<span class="entity-detail" style="display: flex;margin-left: 6px;margin-top: 1px;">
|
||||
<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}`">
|
||||
{{ item.value }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="cn-entity__body">
|
||||
<div class="body__basic-info">
|
||||
<div class="basic-info">
|
||||
<template v-if="entityData.entityType === 'ip'">
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-country"></i>
|
||||
<span>{{ $t('overall.country') }} : </span>
|
||||
<span>{{ entityData.ipLocationCountry || '-' }}</span>
|
||||
<span class="row-item-label">{{ $t('overall.country') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.location ? entityData.location.country : '-' }}</span>
|
||||
</div>
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-position"></i>
|
||||
<span>{{ $t('overall.region') }} : </span>
|
||||
<span>{{ ipLocationRegion(entityData) }}</span>
|
||||
<span class="row-item-label">{{ $t('overall.region') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.location ? ipLocationRegion(entityData.location) : '-' }}</span>
|
||||
</div>
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-cloud"></i>
|
||||
<span>{{ $t('entities.asn') }} : </span>
|
||||
<span>{{ entityData.ipAsn || '-' }}</span>
|
||||
<span class="row-item-label">{{ $t('entities.asn') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.asn ? entityData.asn.asn : '-' }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="entityData.entityType === 'domain'">
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-category"></i>
|
||||
<span>{{ $t('entities.domainDetail.categoryGroup') }} : </span>
|
||||
<span>{{ entityData.domainCategoryGroup || '-' }}</span>
|
||||
<i class="cn-icon cn-icon-sub-category"></i>
|
||||
<span class="row-item-label">{{ $t('entities.category') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.category ? entityData.category.name : '-' }}</span>
|
||||
</div>
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-sub-category"></i>
|
||||
<span>{{ $t('entities.category') }} : </span>
|
||||
<span>{{ entityData.domainCategory || '-' }}</span>
|
||||
<i class="cn-icon cn-icon-category"></i>
|
||||
<span class="row-item-label">{{ $t('entities.subcategory') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.category ? entityData.category.group : '-' }}</span>
|
||||
</div>
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-credit"></i>
|
||||
<span>{{ $t('entities.reputationLevel') }} : </span>
|
||||
<span>{{ entityData.domainReputationScore || '-' }}</span>
|
||||
<span class="row-item-label">{{ $t('entities.reputationLevel') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.category ? entityData.category.reputationLevel : '-' }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="entityData.entityType === 'app'">
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-id"></i>
|
||||
<span>{{ $t('entities.category') }} : </span>
|
||||
<span>{{ entityData.appCategory || '-' }}</span>
|
||||
<span class="row-item-label">{{ $t('entities.category') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.category ? entityData.category.appCategory : '-' }}</span>
|
||||
</div>
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-category"></i>
|
||||
<span>{{ $t('entities.subcategory') }} : </span>
|
||||
<span>{{ entityData.appSubcategory || '-' }}</span>
|
||||
<span class="row-item-label">{{ $t('entities.subcategory') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.category ? entityData.category.appSubcategory : '-' }}</span>
|
||||
</div>
|
||||
<div class="basic-info__item">
|
||||
<i class="cn-icon cn-icon-sub-category"></i>
|
||||
<span>{{ $t('entities.risk') }} : </span>
|
||||
<span>{{ appRisk(entityData.appRisk) || '-' }}</span>
|
||||
<span class="row-item-label">{{ $t('entities.risk') }} : </span>
|
||||
<span class="row-item-value">{{ entityData.category ? appRisk(entityData.category.appRisk) : '-' }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 通用字段 -->
|
||||
<div class="basic-info__item">
|
||||
<div class="item__box">
|
||||
<i class="cn-icon cn-icon-rise"></i>
|
||||
<span>{{ $t('entities.sentThroughput') }} : </span>
|
||||
<span>
|
||||
<span class="row-item-label">{{ $t('entities.sentThroughput') }} : </span>
|
||||
<span class="row-item-value">
|
||||
{{
|
||||
entityData.bytesSentRate ? unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ') + 'ps' : '-'
|
||||
}}
|
||||
@@ -107,8 +108,8 @@
|
||||
<div class="basic-info__item">
|
||||
<div class="item__box">
|
||||
<i class="cn-icon cn-icon-fall"></i>
|
||||
<span>{{ $t('entities.receivedThroughput') }} : </span>
|
||||
<span>
|
||||
<span class="row-item-label">{{ $t('entities.receivedThroughput') }} : </span>
|
||||
<span class="row-item-value">
|
||||
{{
|
||||
entityData.bytesReceivedRate ? unitConvert(entityData.bytesReceivedRate, unitTypes.byte).join(' ') + 'ps' : '-'
|
||||
}}
|
||||
@@ -133,23 +134,7 @@
|
||||
</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 class="show-detail" @click="showDetail">-->
|
||||
<!-- {{ $t('overall.detail') }}>-->
|
||||
<!-- </div>-->
|
||||
<!-- 新版实体列表改版,后续记得解开-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -172,6 +157,10 @@ import DetailOverview from '@/views/entityExplorer/entityList/detailOverview/Det
|
||||
import entityListMixin from './entityListMixin'
|
||||
import relatedServer from '@/mixins/relatedServer'
|
||||
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 {
|
||||
name: 'Row',
|
||||
@@ -188,35 +177,109 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
isCollapse: true // 是否是折叠状态
|
||||
isCollapse: true, // 是否是折叠状态
|
||||
levelTwoTags: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
ipLocationRegion () {
|
||||
return function (entityData) {
|
||||
const hasProvinceAndCity =
|
||||
entityData.ipLocationProvince &&
|
||||
entityData.ipLocationCity &&
|
||||
entityData.ipLocationProvince !== 'null' &&
|
||||
entityData.ipLocationCity !== 'null'
|
||||
entityData.province &&
|
||||
entityData.city &&
|
||||
entityData.province !== 'null' &&
|
||||
entityData.city !== 'null'
|
||||
const hasProvince =
|
||||
entityData.ipLocationProvince &&
|
||||
entityData.ipLocationProvince !== 'null'
|
||||
entityData.province &&
|
||||
entityData.province !== 'null'
|
||||
const hasCity =
|
||||
entityData.ipLocationCity && entityData.ipLocationCity !== 'null'
|
||||
entityData.city && entityData.city !== 'null'
|
||||
if (hasProvinceAndCity) {
|
||||
return `${entityData.ipLocationProvince}, ${entityData.ipLocationCity}`
|
||||
return `${entityData.province}, ${entityData.city}`
|
||||
} else if (hasProvince) {
|
||||
return entityData.ipLocationProvince
|
||||
return entityData.province
|
||||
} else if (hasCity) {
|
||||
return entityData.ipLocationCity
|
||||
return entityData.city
|
||||
} else {
|
||||
return '-'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.initData()
|
||||
this.initTagsData()
|
||||
},
|
||||
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 () {
|
||||
this.isCollapse = !this.isCollapse
|
||||
|
||||
@@ -4,23 +4,23 @@
|
||||
<div class="overview__content">
|
||||
<div class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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>
|
||||
@@ -43,103 +43,78 @@
|
||||
<div class="row__charts-msg">{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps</div>
|
||||
<!-- 曲线-->
|
||||
<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 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__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 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 class="overview-item">
|
||||
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
||||
<div class="overview__content domain__content">
|
||||
<div class="overview__tags domain__tags" ref="relationship">
|
||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="overview__domain-tab">
|
||||
<div class="overview__tag domain__tag">
|
||||
<span class="tag__value">{{relationshipDataOne.length}}</span>
|
||||
<span class="tag__desc">{{$t('entities.relatedDomains')}}</span>
|
||||
</div>
|
||||
<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 class="overview__tags domain__tags" ref="relationship"></div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label row__label--width130">{{$t('entities.tab.relatedIp')}}</div>
|
||||
|
||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="row__content overview__row-related">
|
||||
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
||||
{{item.value}}
|
||||
</div>
|
||||
<div class="overview__domain-btn">
|
||||
<div class="overview__domain-more" @click="more(relationshipDataOne, 1)" v-if="relationshipShowOne">...</div>
|
||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreOne" v-ele-click-outside="mouseout">
|
||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataOne" :key="item">
|
||||
<span v-if="item.domain" :title="item.domain">{{item.domain}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="relationshipShowOne">
|
||||
<el-popover placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||
<template #reference>
|
||||
<div class="data-item show-more-related">...</div>
|
||||
</template>
|
||||
<div v-for="(item, index) in relationshipDataOne" :key="index">{{item.value}}</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="overview__domain-tab">
|
||||
<div class="overview__tag domain__tag">
|
||||
<span class="tag__value">{{relationshipDataTwo.length}}</span>
|
||||
<span class="tag__desc">{{$t('entities.relatedServerIp')}}</span>
|
||||
</div>
|
||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||
<span class="tag__desc">{{item.ip}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overview__row overview__row-related">
|
||||
<div class="row__label row__label--width130">{{$t('entities.tab.relatedIp')}}</div>
|
||||
|
||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="row__content">
|
||||
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||
{{item.value}}
|
||||
</div>
|
||||
<div class="overview__domain-btn">
|
||||
<div class="overview__domain-more" @click="more(relationshipDataTwo, 2)" v-if="relationshipShowTwo">...</div>
|
||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreTwo" v-ele-click-outside="mouseout">
|
||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataTwo" :key="item">
|
||||
<span v-if="item.ip" :title="item.ip">{{item.ip}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="relationshipShowTwo">
|
||||
<el-popover class="entity-expand-detail" placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||
<template #reference>
|
||||
<div class="data-item show-more-related">...</div>
|
||||
</template>
|
||||
<div v-for="(item, index) in relationshipDataTwo" :key="index">{{item.value}}</div>
|
||||
</el-popover>
|
||||
</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__title">{{$t('overall.alert')}}</div>
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
<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__content row__content--width200">
|
||||
<div class="overview__row overview__row--small-font" v-for="(performance, index) in entityData.performanceList" :key="index">
|
||||
<div class="row__label row__label--width130">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
||||
<div class="row__content row__content--width90">
|
||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
||||
<div>{{performance.eventType}}</div>
|
||||
</div>
|
||||
<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="row__charts" :id="`entityPerformanceChart${entity.appName}_${index}`"></div>
|
||||
<div class="row__content-loading" style="position: relative;">
|
||||
<div class="performance-event-remark">{{performance.eventType}}</div>
|
||||
</div>
|
||||
|
||||
<div class="row__desc"></div>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
<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__content row__content--width200">
|
||||
|
||||
<div class="overview__row overview__row--small-font" v-for="(security, index) in entityData.securityList" :key="index">
|
||||
<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>{{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 class="row__desc"></div>
|
||||
</div>
|
||||
<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 Chart from '@/views/charts/Chart'
|
||||
import _ from 'lodash'
|
||||
import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
|
||||
import { get } from '@/utils/http'
|
||||
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 { ref } from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
mixins: [entityDetailMixin, relatedServer],
|
||||
components: {
|
||||
Chart,
|
||||
Loading,
|
||||
ChartSingleValue
|
||||
Loading
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// entityData: {}
|
||||
entityType: 'app',
|
||||
trafficUrl: api.entityAppDetailTraffic,
|
||||
// trafficUrl: api.entityAppDetailTraffic,
|
||||
trafficUrl: api.entity.entityList.appThroughput,
|
||||
relationUrl: api.entityAppDetailRelation,
|
||||
networkQuantityUrl: api.entityAppDetailNetworkQuantity,
|
||||
// networkQuantityUrl: api.entityAppDetailNetworkQuantity,
|
||||
networkQuantityUrl: api.entity.entityList.appPerformance,
|
||||
linkInUrl: api.entityAppDetailLinkIn,
|
||||
linkOutUrl: api.entityAppDetailLinkOut,
|
||||
performanceUrl: api.entityAppDetailPerformance,
|
||||
securityUrl: api.entityAppDetailSecurity,
|
||||
trafficUrlMap: api.entityAppDetailTrafficMap,
|
||||
relatedServerDomainUrl: api.entityAppRelatedServerDomain,
|
||||
relatedServerIpUrl: api.entityAppRelatedServerIp,
|
||||
// performanceUrl: api.entityAppDetailPerformance,
|
||||
performanceUrl: api.entity.entityList.appEventPerformance,
|
||||
securityUrl: api.entity.entityList.appSecurity,
|
||||
// securityUrl: api.entityAppDetailSecurity,
|
||||
// trafficUrlMap: api.entityAppDetailTrafficMap,
|
||||
trafficUrlMap: api.entity.entityList.appTrafficMap,
|
||||
relatedServerDomainUrl: api.entity.entityList.appRelatedDomain,
|
||||
relatedServerIpUrl: api.entity.entityList.appRelatedIp,
|
||||
chartData: null,
|
||||
listMode: 'list',
|
||||
singleValues: {
|
||||
@@ -296,34 +283,34 @@ export default {
|
||||
i18n: 'entities.pktRetransPercent'
|
||||
}
|
||||
],
|
||||
chartDatas: [null, null, null, null, null],
|
||||
loadingTraffic: false,
|
||||
loadingRelationshipOne: false,
|
||||
loadingRelationshipTwo: false,
|
||||
loadingNetworkQuality: false,
|
||||
loadingOut: false,
|
||||
loadingIn: false,
|
||||
loadingAlert: false,
|
||||
loadingSecurityEvents: false,
|
||||
loadingMap: false
|
||||
}
|
||||
chartDatas: [null, null, null, null, null]
|
||||
},
|
||||
loadingTraffic: false,
|
||||
loadingRelationshipOne: false,
|
||||
loadingRelationshipTwo: false,
|
||||
loadingNetworkQuality: false,
|
||||
loadingOut: false,
|
||||
loadingIn: false,
|
||||
loadingAlert: false,
|
||||
loadingSecurityEvents: false,
|
||||
loadingMap: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getMillisecond,
|
||||
dateFormatByAppearance,
|
||||
getQueryParams () {
|
||||
const queryParams = {
|
||||
return {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
appName: this.entity.appName
|
||||
resource: this.entity.entityValue,
|
||||
appName: this.entity.entityValue
|
||||
}
|
||||
return queryParams
|
||||
},
|
||||
getPerformanceQueryParams () {
|
||||
const queryParams = {
|
||||
appName: this.entity.appName
|
||||
return {
|
||||
appName: this.entity.entityValue
|
||||
}
|
||||
return queryParams
|
||||
},
|
||||
handleRelationData (result) {
|
||||
this.entityData.domainCount = result.domainCount
|
||||
@@ -353,6 +340,7 @@ export default {
|
||||
})
|
||||
},
|
||||
setup (props) {
|
||||
const entityData = ref({ ...props.entity })
|
||||
return {
|
||||
chart: {
|
||||
params: {
|
||||
@@ -366,7 +354,8 @@ export default {
|
||||
entityCopy: {
|
||||
..._.cloneDeep(props.entity)
|
||||
},
|
||||
unitConvert
|
||||
unitConvert,
|
||||
entityData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,36 +4,32 @@
|
||||
<div class="overview__content">
|
||||
<div class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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 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 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__content-loading">
|
||||
<div class="row__charts" :id="`entityDetailSend${entity.domainName}`" >{</div>
|
||||
<div class="row__charts" :id="`entityDetailSend${entity.entityValue}`" >{</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__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 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 class="overview-item">
|
||||
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
||||
<div class="overview__content domain__content">
|
||||
<div class="overview__tags domain__tags" ref="relationship">
|
||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="overview__domain-tab">
|
||||
<div class="overview__tag domain__tag">
|
||||
<span class="tag__value">{{relationshipDataOne.length}}</span>
|
||||
<span class="tag__desc">{{$t('entities.relatedApp')}}</span>
|
||||
</div>
|
||||
<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 class="overview__tags domain__tags" ref="relationship"></div>
|
||||
<div class="overview__row">
|
||||
<div class="row__label row__label--width130">{{$t('entities.tab.relatedApp')}}</div>
|
||||
|
||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="row__content overview__row-related">
|
||||
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
||||
{{item.value}}
|
||||
</div>
|
||||
<div class="overview__domain-btn">
|
||||
<div class="overview__domain-more" @click="more(relationshipDataOne, 1)" v-if="relationshipShowOne">...</div>
|
||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreOne" v-ele-click-outside="mouseout">
|
||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataOne" :key="item">
|
||||
<span v-if="item.appName" :title="item.appName">{{item.appName}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="relationshipShowOne">
|
||||
<el-popover placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||
<template #reference>
|
||||
<div class="data-item show-more-related">...</div>
|
||||
</template>
|
||||
<div v-for="(item, index) in relationshipDataOne" :key="index">{{item.value}}</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="overview__domain-tab">
|
||||
<div class="overview__tag domain__tag">
|
||||
<span class="tag__value">{{relationshipDataTwo.length}}</span>
|
||||
<span class="tag__desc">{{$t('entities.relatedServerIp')}}</span>
|
||||
</div>
|
||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||
<span class="tag__desc">{{item.ip}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overview__row overview__row-related">
|
||||
<div class="row__label row__label--width130">{{$t('entities.tab.relatedIp')}}</div>
|
||||
|
||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="row__content">
|
||||
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||
{{item.value}}
|
||||
</div>
|
||||
<div class="overview__domain-btn">
|
||||
<div class="overview__domain-more" @click="more(relationshipDataTwo, 2)" v-if="relationshipShowTwo">...</div>
|
||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreTwo" v-ele-click-outside="mouseout">
|
||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataTwo" :key="item">
|
||||
<span v-if="item.ip" :title="item.ip">{{item.ip}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="relationshipShowTwo">
|
||||
<el-popover class="entity-expand-detail" placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||
<template #reference>
|
||||
<div class="data-item show-more-related">...</div>
|
||||
</template>
|
||||
<div v-for="(item, index) in relationshipDataTwo" :key="index">{{item.value}}</div>
|
||||
</el-popover>
|
||||
</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__title">{{$t('overall.alert')}}</div>
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
<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__content row__content--width200">
|
||||
<div class="row__label row__label--width130">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
||||
<div class="row__content row__content--width90">
|
||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
||||
<div>{{performance.eventType}}</div>
|
||||
</div>
|
||||
<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="row__charts" :id="`entityPerformanceChart${entity.domainName}_${index}`"></div>
|
||||
<div class="row__content-loading" style="position: relative;">
|
||||
<div class="performance-event-remark">{{performance.eventType}}</div>
|
||||
</div>
|
||||
<div class="row__desc"></div>
|
||||
</div>
|
||||
@@ -188,14 +157,24 @@
|
||||
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
||||
</div>
|
||||
<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>
|
||||
|
||||
<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__content row__content--width200">
|
||||
<div class="row__label row__label--width130">{{dateFormatByAppearance(getMillisecond(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>{{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 class="row__desc"></div>
|
||||
</div>
|
||||
@@ -218,7 +197,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
|
||||
import { api } from '@/utils/api'
|
||||
import entityDetailMixin from './entityDetailMixin'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
@@ -227,13 +205,13 @@ import Chart from '@/views/charts/Chart'
|
||||
import _ from 'lodash'
|
||||
import { get } from '@/utils/http'
|
||||
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 { ref } from 'vue'
|
||||
|
||||
export default {
|
||||
name: 'Domain',
|
||||
components: {
|
||||
ChartSingleValue,
|
||||
Loading,
|
||||
Chart
|
||||
},
|
||||
@@ -242,16 +220,21 @@ export default {
|
||||
return {
|
||||
// entityData: {},
|
||||
entityType: 'domain',
|
||||
trafficUrl: api.entityDomainDetailTraffic,
|
||||
// trafficUrl: api.entityDomainDetailTraffic,
|
||||
trafficUrl: api.entity.entityList.domainThroughput,
|
||||
relationUrl: api.entityDomainDetailRelation,
|
||||
networkQuantityUrl: api.entityDomainDetailNetworkQuantity,
|
||||
networkQuantityUrl: api.entity.entityList.domainPerformance,
|
||||
// networkQuantityUrl: api.entityDomainDetailNetworkQuantity,
|
||||
linkInUrl: api.entityDomainDetailLinkIn,
|
||||
linkOutUrl: api.entityDomainDetailLinkOut,
|
||||
performanceUrl: api.entityDomainDetailPerformance,
|
||||
securityUrl: api.entityDomainDetailSecurity,
|
||||
trafficUrlMap: api.entityDomainDetailTrafficMap,
|
||||
relatedServerIpUrl: api.entityDomainRelatedServerIp,
|
||||
relatedServerAppUrl: api.entityDomainRelatedServerApp,
|
||||
// performanceUrl: api.entityDomainDetailPerformance,
|
||||
performanceUrl: api.entity.entityList.domainEventPerformance,
|
||||
// securityUrl: api.entityDomainDetailSecurity,
|
||||
securityUrl: api.entity.entityList.domainSecurity,
|
||||
// trafficUrlMap: api.entityDomainDetailTrafficMap,
|
||||
trafficUrlMap: api.entity.entityList.domainTrafficMap,
|
||||
relatedServerIpUrl: api.entity.entityList.domainRelatedIp,
|
||||
relatedServerAppUrl: api.entity.entityList.domainRelatedApp,
|
||||
basicProperties: api.entityDomainDetailBasic,
|
||||
chartData: null,
|
||||
listMode: 'list',
|
||||
@@ -308,34 +291,34 @@ export default {
|
||||
i18n: 'entities.pktRetransPercent'
|
||||
}
|
||||
],
|
||||
chartDatas: [null, null, null, null, null],
|
||||
loadingTraffic: false,
|
||||
loadingRelationshipOne: false,
|
||||
loadingRelationshipTwo: false,
|
||||
loadingNetworkQuality: false,
|
||||
loadingOut: false,
|
||||
loadingIn: false,
|
||||
loadingAlert: false,
|
||||
loadingSecurityEvents: false,
|
||||
loadingMap: false
|
||||
}
|
||||
chartDatas: [null, null, null, null, null]
|
||||
},
|
||||
loadingTraffic: false,
|
||||
loadingRelationshipOne: false,
|
||||
loadingRelationshipTwo: false,
|
||||
loadingNetworkQuality: false,
|
||||
loadingOut: false,
|
||||
loadingIn: false,
|
||||
loadingAlert: false,
|
||||
loadingSecurityEvents: false,
|
||||
loadingMap: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getMillisecond,
|
||||
dateFormatByAppearance,
|
||||
getQueryParams () {
|
||||
const queryParams = {
|
||||
return {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
domain: this.entity.domainName
|
||||
resource: this.entity.entityValue,
|
||||
domain: this.entity.entityValue
|
||||
}
|
||||
return queryParams
|
||||
},
|
||||
getPerformanceQueryParams () {
|
||||
const queryParams = {
|
||||
domain: this.entity.domainName
|
||||
return {
|
||||
domain: this.entity.entityValue
|
||||
}
|
||||
return queryParams
|
||||
},
|
||||
handleRelationData (result) {
|
||||
this.entityData.appCount = result.appCount
|
||||
@@ -383,9 +366,10 @@ export default {
|
||||
})
|
||||
},
|
||||
setup (props) {
|
||||
const entityData = ref({ ...props.entity })
|
||||
const entityCopy = {
|
||||
..._.cloneDeep(props.entity),
|
||||
domain: props.entity.domainName
|
||||
domain: props.entity.entityValue
|
||||
}
|
||||
return {
|
||||
chart: {
|
||||
@@ -398,7 +382,8 @@ export default {
|
||||
},
|
||||
entityCopy,
|
||||
unitTypes,
|
||||
unitConvert
|
||||
unitConvert,
|
||||
entityData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,15 @@
|
||||
<div class="overview__content">
|
||||
<div class="overview__row">
|
||||
<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 class="overview__row">
|
||||
<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>
|
||||
@@ -44,7 +48,7 @@
|
||||
<!-- 曲线-->
|
||||
<div class="row__content-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>
|
||||
@@ -70,103 +74,77 @@
|
||||
<div class="row__charts-msg">{{$t('overall.sent')}}:{{unitConvert(entityData.bytesSentRate, unitTypes.byte).join(' ')}}ps</div>
|
||||
<!-- 曲线-->
|
||||
<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 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__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 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 class="overview-item">
|
||||
<div class="overview__title">{{$t('overall.relationship')}}</div>
|
||||
<div class="overview__content domain__content">
|
||||
<div class="overview__tags domain__tags" ref="relationship">
|
||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="overview__domain-tab">
|
||||
<div class="overview__tag domain__tag">
|
||||
<span class="tag__value">{{relationshipDataOne.length}}</span>
|
||||
<span class="tag__desc">{{$t('entities.relatedDomains')}}</span>
|
||||
</div>
|
||||
<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 class="overview__tags domain__tags" ref="relationship"></div>
|
||||
<div class="overview__row overview__row-related">
|
||||
<div class="row__label row__label--width130">{{$t('entities.tab.relatedApp')}}</div>
|
||||
|
||||
<loading :loading="loadingRelationshipOne" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="row__content">
|
||||
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataOne" :key="index">
|
||||
{{item.value}}
|
||||
</div>
|
||||
<div class="overview__domain-btn">
|
||||
<div class="overview__domain-more" @click="more(relationshipDataOne, 1)" v-if="relationshipShowOne">...</div>
|
||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreOne" v-ele-click-outside="mouseout">
|
||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataOne" :key="item">
|
||||
<span v-if="item.domain" :title="item.domain">{{item.domain}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="relationshipShowOne">
|
||||
<el-popover placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||
<template #reference>
|
||||
<div class="data-item show-more-related">...</div>
|
||||
</template>
|
||||
<div class="popover-content" v-for="(item, index) in relationshipDataOne" :key="index">{{item.value}}</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview__domain-tabs overview__domain-tabs-loading">
|
||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="overview__domain-tab">
|
||||
<div class="overview__tag domain__tag">
|
||||
<span class="tag__value">{{relationshipDataTwo.length}}</span>
|
||||
<span class="tag__desc">{{$t('entities.relatedApp')}}</span>
|
||||
</div>
|
||||
<div class="overview__tag domain__tag-list" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||
<span class="tag__desc">{{item.appName}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="overview__row overview__row-related">
|
||||
<div class="row__label row__label--width130">{{$t('entities.relatedDomain')}}</div>
|
||||
|
||||
<loading :loading="loadingRelationshipTwo" size="small" inner-style="left: 1rem;" style="width: 50%;"></loading>
|
||||
<div class="row__content">
|
||||
<div class="data-item" v-show="item.show" v-for="(item, index) in relationshipDataTwo" :key="index">
|
||||
{{item.value}}
|
||||
</div>
|
||||
<div class="overview__domain-btn">
|
||||
<div class="overview__domain-more" @click="more(relationshipDataTwo, 2)" v-if="relationshipShowTwo">...</div>
|
||||
<div class="overview__domain-more-tabs show-more-list" v-if="relationshipShowMoreTwo" v-ele-click-outside="mouseout">
|
||||
<div class="domain-more-tab" v-for="item in relationshipMoreDataTwo" :key="item">
|
||||
<span v-if="item.appName" :title="item.appName">{{item.appName}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="relationshipShowTwo">
|
||||
<el-popover class="entity-expand-detail" placement="right-end" trigger="click" show-arrow="false" offset="20">
|
||||
<template #reference>
|
||||
<div class="data-item show-more-related">...</div>
|
||||
</template>
|
||||
<div v-for="(item, index) in relationshipDataTwo" :key="index">{{item.value}}</div>
|
||||
</el-popover>
|
||||
</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__title">{{$t('overall.alert')}}</div>
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
<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__content">
|
||||
<div class="row__label row__label--width130">{{dateFormatByAppearance(performance.startTime) || '-'}}</div>
|
||||
<div class="row__content row__content--width90">
|
||||
<div class="alert-level-tag alert-level-tag--high" :class="iconClass(performance)">{{performance.eventSeverity}}</div>
|
||||
<div>{{performance.eventType}}</div>
|
||||
</div>
|
||||
<div class="row__content-loading" style="position: relative; padding-left: 10px;">
|
||||
<loading :loading="!loadingAlert && loadingPerformance[index]?loadingPerformance[index]:false" :id="`loading${entity.ipAddr}_${index}`" size="small"></loading>
|
||||
<div class="row__charts" :id="`entityPerformanceChart${entity.ipAddr}_${index}`"></div>
|
||||
<div class="row__content-loading" style="position: relative;">
|
||||
<div class="performance-event-remark">{{performance.eventType}}</div>
|
||||
</div>
|
||||
<div class="row__desc"></div>
|
||||
</div>
|
||||
@@ -203,15 +179,26 @@
|
||||
<span class="no-recent-alerts"><i class="el-icon-success"></i>{{$t('relationShip.noRecentAlerts')}}</span>
|
||||
</div>
|
||||
<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>
|
||||
|
||||
<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__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>{{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 class="row__desc"></div>
|
||||
</div>
|
||||
<div class="overview__row overview__row--small-font" v-if="securityData && securityData.length > 5">
|
||||
@@ -234,7 +221,6 @@
|
||||
|
||||
<script>
|
||||
import entityDetailMixin from './entityDetailMixin'
|
||||
import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
|
||||
import { api } from '@/utils/api'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
@@ -242,30 +228,35 @@ import Chart from '@/views/charts/Chart'
|
||||
import _ from 'lodash'
|
||||
import { get } from '@/utils/http'
|
||||
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 axios from 'axios'
|
||||
|
||||
export default {
|
||||
name: 'Ip',
|
||||
mixins: [entityDetailMixin, relatedServer],
|
||||
components: {
|
||||
Loading,
|
||||
Chart,
|
||||
ChartSingleValue
|
||||
Chart
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
entityType: 'ip',
|
||||
trafficUrl: api.entityIpDetailTraffic,
|
||||
trafficUrlMap: api.entityIpDetailTrafficMap,
|
||||
// trafficUrl: api.entityIpDetailTraffic,
|
||||
trafficUrl: api.entity.entityList.ipThroughput,
|
||||
// trafficUrlMap: api.entityIpDetailTrafficMap,
|
||||
trafficUrlMap: api.entity.entityList.ipTrafficMap,
|
||||
relationUrl: api.entityIpDetailRelation,
|
||||
networkQuantityUrl: api.entityIpDetailNetworkQuantity,
|
||||
// networkQuantityUrl: api.entityIpDetailNetworkQuantity,
|
||||
networkQuantityUrl: api.entity.entityList.ipPerformance,
|
||||
linkInUrl: api.entityIpDetailLinkIn,
|
||||
linkOutUrl: api.entityIpDetailLinkOut,
|
||||
performanceUrl: api.entityIpDetailPerformance,
|
||||
securityUrl: api.entityIpDetailSecurity,
|
||||
relatedServerDomainUrl: api.entityIpRelatedServerDomain,
|
||||
relatedServerAppUrl: api.entityIpRelatedServerApp,
|
||||
performanceUrl: api.entity.entityList.ipEventPerformance,
|
||||
// performanceUrl: api.entityIpDetailPerformance,
|
||||
// securityUrl: api.entityIpDetailSecurity,
|
||||
securityUrl: api.entity.entityList.ipSecurity,
|
||||
relatedServerDomainUrl: api.entity.entityList.ipRelatedDomain,
|
||||
relatedServerAppUrl: api.entity.entityList.ipRelatedApp,
|
||||
entityDetectionsIpUrl: api.entityDetectionsIp,
|
||||
entityDetectionsIpQueryRateUrl: api.entityDetectionsIpQueryRate,
|
||||
listMode: 'list',
|
||||
@@ -336,21 +327,22 @@ export default {
|
||||
loadingIn: false,
|
||||
loadingAlert: false,
|
||||
loadingSecurityEvents: false,
|
||||
loadingMap: false
|
||||
loadingMap: false,
|
||||
openPort: '-'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
ipLocationRegion () {
|
||||
return function (entityData) {
|
||||
let result = ''
|
||||
if (entityData.ipLocationCountry) {
|
||||
result += `${entityData.ipLocationCountry},`
|
||||
if (entityData.country) {
|
||||
result += `${entityData.country},`
|
||||
}
|
||||
if (entityData.ipLocationProvince) {
|
||||
result += `${entityData.ipLocationProvince},`
|
||||
if (entityData.province) {
|
||||
result += `${entityData.province},`
|
||||
}
|
||||
if (entityData.ipLocationCity) {
|
||||
result += `${entityData.ipLocationCity},`
|
||||
if (entityData.city) {
|
||||
result += `${entityData.city},`
|
||||
}
|
||||
result = result.substr(0, result.length - 1)
|
||||
if (!result) {
|
||||
@@ -381,19 +373,19 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getMillisecond,
|
||||
dateFormatByAppearance,
|
||||
getQueryParams () {
|
||||
const queryParams = {
|
||||
return {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
ip: this.entity.ipAddr
|
||||
resource: this.entity.entityValue,
|
||||
ip: this.entity.entityValue
|
||||
}
|
||||
return queryParams
|
||||
},
|
||||
getPerformanceQueryParams () {
|
||||
const queryParams = {
|
||||
serverIp: this.entity.ipAddr
|
||||
return {
|
||||
serverIp: this.entity.entityValue
|
||||
}
|
||||
return queryParams
|
||||
},
|
||||
handleRelationData (result) {
|
||||
this.entityData.appCount = result.appCount
|
||||
@@ -411,11 +403,29 @@ export default {
|
||||
queryRelated () {
|
||||
this.getRelatedServerDataOne(this.relatedServerDomainUrl)
|
||||
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 () {
|
||||
this.queryParams = this.getQueryParams()
|
||||
this.chartGetMap()
|
||||
this.getOpenPort()
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.queryRelated()
|
||||
@@ -425,7 +435,7 @@ export default {
|
||||
setup (props) {
|
||||
const entityCopy = {
|
||||
..._.cloneDeep(props.entity),
|
||||
ip: props.entity.ipAddr
|
||||
ip: props.entity.entityValue
|
||||
}
|
||||
return {
|
||||
chart: {
|
||||
@@ -434,7 +444,7 @@ export default {
|
||||
unitType: 'number',
|
||||
valueColumn: 'sessions'
|
||||
},
|
||||
id: props.entity.ipAddr,
|
||||
id: props.entity.entityValue,
|
||||
type: 2
|
||||
},
|
||||
entityCopy,
|
||||
@@ -444,3 +454,110 @@ export default {
|
||||
}
|
||||
}
|
||||
</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 { shallowRef, markRaw } from 'vue'
|
||||
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 { api } from '@/utils/api'
|
||||
|
||||
@@ -45,29 +45,13 @@ export default {
|
||||
metricChart: null,
|
||||
performanceChartList: [],
|
||||
loadingPerformance: [],
|
||||
|
||||
score: '-', // 网络质量评分
|
||||
performanceMetricEndTimeInterval: 3600 // 服务质量事件指标的结束时间与开始时间的秒间隔
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
entityName () {
|
||||
let name
|
||||
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
|
||||
return this.entity.entityValue
|
||||
},
|
||||
appRisk () {
|
||||
return function (level) {
|
||||
@@ -234,7 +218,7 @@ export default {
|
||||
this.performanceChartList.push(metricChart)
|
||||
this.echartsArray.push(shallowRef(metricChart))
|
||||
} 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>'
|
||||
}
|
||||
})
|
||||
@@ -272,6 +256,14 @@ export default {
|
||||
if (this.networkQuantityUrl) {
|
||||
get(this.networkQuantityUrl, this.getQueryParams()).then(response => {
|
||||
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.establishLatencyP50 = response.data.result.establishLatencyP50
|
||||
this.entityData.establishLatencyP90 = response.data.result.establishLatencyP90
|
||||
@@ -389,11 +381,6 @@ export default {
|
||||
this.entityData.performanceNum = response.data.result.length
|
||||
this.performanceData = response.data.result
|
||||
this.entityData.performanceList = this.getTargetPageData(1, this.showMore.performancePageSize, this.performanceData)
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.queryEntityDetailPerformanceChart(this.entityData.performanceList, 0)
|
||||
}, 200)
|
||||
})
|
||||
}
|
||||
this.loadingAlert = false
|
||||
})
|
||||
@@ -412,16 +399,16 @@ export default {
|
||||
},
|
||||
|
||||
performanceShowMore (num) {
|
||||
const startIndex = this.showMore.performancePageSize
|
||||
// const startIndex = this.showMore.performancePageSize
|
||||
this.showMore.performancePageSize += num
|
||||
this.entityData.performanceList = this.getTargetPageData(this.showMore.pageNo, this.showMore.performancePageSize, this.performanceData)
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
if (this.entityData.performanceList && this.entityData.performanceList.length > 0) {
|
||||
this.queryEntityDetailPerformanceChart(this.entityData.performanceList.slice(startIndex, this.entityData.performanceList.length), startIndex)
|
||||
}
|
||||
}, 200)
|
||||
})
|
||||
// this.$nextTick(() => {
|
||||
// setTimeout(() => lltext
|
||||
// if (this.entityData.performanceList && this.entityData.performanceList.length > 0) {
|
||||
// this.queryEntityDetailPerformanceChart(this.entityData.performanceList.slice(startIndex, this.entityData.performanceList.length), startIndex)
|
||||
// }
|
||||
// }, 200)
|
||||
// })
|
||||
},
|
||||
|
||||
securityShowMore (num) {
|
||||
@@ -520,6 +507,7 @@ export default {
|
||||
this.chartOption = _.cloneDeep(entityListLineOption)
|
||||
setTimeout(() => { this.queryEntityDetail() })
|
||||
const _this = this
|
||||
this.entityData = { ...this.entityData, ...this.entity }
|
||||
this.emitter.on('switch-collapse', function () {
|
||||
setTimeout(() => { _this.queryEntityDetail() }, 200)
|
||||
})
|
||||
|
||||
@@ -45,43 +45,10 @@ export default {
|
||||
return className
|
||||
},
|
||||
entityType () {
|
||||
let type
|
||||
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
|
||||
return this.entity.entityValue
|
||||
},
|
||||
entityName () {
|
||||
let name
|
||||
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
|
||||
return this.entity.entityValue
|
||||
},
|
||||
appRisk () {
|
||||
return function (level) {
|
||||
@@ -94,32 +61,11 @@ export default {
|
||||
queryParams () {
|
||||
let params
|
||||
const now = window.$dayJs.tz().valueOf()
|
||||
switch (this.entityData.entityType) {
|
||||
case ('ip'): {
|
||||
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),
|
||||
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
|
||||
// eslint-disable-next-line prefer-const
|
||||
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),
|
||||
resource: this.entityData.entityValue
|
||||
}
|
||||
return params
|
||||
}
|
||||
@@ -130,7 +76,7 @@ export default {
|
||||
path: '/entityDetail',
|
||||
query: {
|
||||
entityType: this.entityData.entityType,
|
||||
entityName: this.entityData.ipAddr || this.entityData.domainName || this.entityData.appName
|
||||
entityName: this.entityData.entityValue
|
||||
}
|
||||
})
|
||||
window.open(href, '_blank')
|
||||
@@ -140,7 +86,7 @@ export default {
|
||||
path: '/entityGraph',
|
||||
query: {
|
||||
entityType: this.entityData.entityType,
|
||||
entityName: this.entityData.ipAddr || this.entityData.domainName || this.entityData.appName
|
||||
entityName: this.entityData.entityValue
|
||||
}
|
||||
})
|
||||
window.open(href, '_blank')
|
||||
@@ -209,9 +155,7 @@ export default {
|
||||
return {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
appName: this.entityType,
|
||||
domain: this.entityType,
|
||||
ip: this.entityType
|
||||
resource: this.entityType
|
||||
}
|
||||
},
|
||||
queryEntityDetailTraffic () {
|
||||
@@ -295,30 +239,36 @@ export default {
|
||||
},
|
||||
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: {
|
||||
entityData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (n.entityType) {
|
||||
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
|
||||
}
|
||||
}
|
||||
this.initUrl()
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -326,7 +276,9 @@ export default {
|
||||
this.debounceFunc = this.$_.debounce(this.resize, 200)
|
||||
window.addEventListener('resize', this.debounceFunc)
|
||||
this.chartOption = _.cloneDeep(entityListLineOption)
|
||||
this.entityData = _.cloneDeep(this.entity)
|
||||
// this.entityData = _.cloneDeep(this.entity)
|
||||
this.entityData = { ...this.entityData, ...this.entity }
|
||||
this.initUrl()
|
||||
setTimeout(() => {
|
||||
this.querySecurity()
|
||||
this.queryEntityDetailTraffic()
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
<div class="explorer-search">
|
||||
<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">
|
||||
<!--新版实体列表改版,后续记得解开-->
|
||||
<!--<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
|
||||
ref="search"
|
||||
:column-list="columnList"
|
||||
|
||||
Reference in New Issue
Block a user