diff --git a/src/assets/css/components/components/advancedSearch/advanced-search2.scss b/src/assets/css/components/components/advancedSearch/advanced-search2.scss index 50d1d434..f32d71e1 100644 --- a/src/assets/css/components/components/advancedSearch/advanced-search2.scss +++ b/src/assets/css/components/components/advancedSearch/advanced-search2.scss @@ -224,7 +224,7 @@ .my-popper-class { width: auto !important; - min-width: 120px !important; + min-width: 125px !important; padding: 8px 10px !important; } .el-input__wrapper.is-focus { diff --git a/src/assets/css/components/views/charts2/entityDetailSubscriberMap.scss b/src/assets/css/components/views/charts2/entityDetailSubscriberMap.scss index 23f4fc67..527c60a0 100644 --- a/src/assets/css/components/views/charts2/entityDetailSubscriberMap.scss +++ b/src/assets/css/components/views/charts2/entityDetailSubscriberMap.scss @@ -24,7 +24,7 @@ border-radius: 4px; height: calc(100% - 34px); - .subscriber-map { + .subscriber-map, .entity-subscriber-map { height: 100%; width: calc(100% - 290px); @@ -118,6 +118,9 @@ } } } + .entity-subscriber-map { + width: 100%; + } .panel-chart__no-data { height: calc(100% - 46px); } diff --git a/src/assets/css/components/views/entityExplorer/entity-explorer.scss b/src/assets/css/components/views/entityExplorer/entity-explorer.scss index db3ddfcf..dfaeaa6d 100644 --- a/src/assets/css/components/views/entityExplorer/entity-explorer.scss +++ b/src/assets/css/components/views/entityExplorer/entity-explorer.scss @@ -136,7 +136,7 @@ display: flex; //flex-direction: column; align-items: center; - padding: 0 0 0 30px; + padding: 0 0 0 20px; .overview-left-span { font-size: 16px; diff --git a/src/assets/css/components/views/entityExplorer/entityList/detail-overview.scss b/src/assets/css/components/views/entityExplorer/entityList/detail-overview.scss index a6a06d4b..12e76557 100644 --- a/src/assets/css/components/views/entityExplorer/entityList/detail-overview.scss +++ b/src/assets/css/components/views/entityExplorer/entityList/detail-overview.scss @@ -166,8 +166,11 @@ min-width: 90px !important; } } + .row__content-sent { + margin-right: 39px; + } .row__content-accept { - margin-left: 39px; + //margin-left: 39px; } .row__charts-msg { width: auto; @@ -183,6 +186,11 @@ //padding-left: 5px; } } + .row__contents-subscriber { + display: flex; + width: calc(100% - 688px); // 分辨率过小时换行 + flex-wrap: wrap; + } .row__charts { width:80px; height:20px; diff --git a/src/assets/css/components/views/entityExplorer/entityList/row.scss b/src/assets/css/components/views/entityExplorer/entityList/row.scss index 7186eee6..bde8ba60 100644 --- a/src/assets/css/components/views/entityExplorer/entityList/row.scss +++ b/src/assets/css/components/views/entityExplorer/entityList/row.scss @@ -76,8 +76,8 @@ font-size: 16px; padding-bottom: 3px; color: #333333; - .cn-entity__header-title { - margin-right: 10px; + .cn-entity__header-icon { + margin-left: 10px; } .entity-related-entity { font-size: 12px; @@ -222,7 +222,12 @@ } } + .show-detail__block { + display: flex; + align-items: center; + } .new-show-detail { + height: 52px; flex-shrink: 0; padding: 0 30px; font-size: 12px; diff --git a/src/mock/entity.js b/src/mock/entity.js index 27486afa..0e692a1b 100644 --- a/src/mock/entity.js +++ b/src/mock/entity.js @@ -455,9 +455,10 @@ if (openMock) { const result = { pageNo: 1, pageSize: 10, - total: 3, + total: 4, list: [ - { entityValue: '192.168.12.34', entityType: 'ip' }, + { entityValue: 'test123987', entityType: 'subscriber_id' }, + { entityValue: '172.217.24.66', entityType: 'ip' }, { entityValue: 'gdbzkz.com', entityType: 'domain' }, { entityValue: 'qqvideo', entityType: 'app' } ] @@ -528,6 +529,17 @@ if (openMock) { } break } + case ('subscriber_id'): { + result = { + phone_number: '1568912455', + imei: 'r45ty5454fh', + imsi: 'eere2545t', + apn: 'xxx站点', + subscriber_longitude: 116.370042, + subscriber_latitude: 39.944283 + } + break + } } return { @@ -719,7 +731,7 @@ if (openMock) { } }) Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/overview/active.*`), 'get', function (requestObj) { - const data = { domainCount: 755, ipCount: 8373, appCount: 263 } + const data = { domainCount: 755, ipCount: 8373, appCount: 263, subscriberCount: 263 } return { msg: 'success', @@ -737,7 +749,7 @@ if (openMock) { } }) Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/overview/total.*`), 'get', function (requestObj) { - const data = { domainCount: 7686274, ipCount: 2169957, appCount: 856 } + const data = { domainCount: 7686274, ipCount: 2169957, appCount: 856, subscriberCount: 856 } return { msg: 'success', @@ -745,6 +757,49 @@ if (openMock) { data: data } }) + Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/detail/traffic/throughput/subscriber.*`), 'get', function (requestObj) { + const arr = [{ legend: 'sentRate' }, { legend: 'rate' }, { legend: 'receivedRate' }] + + const endTime = JSON.parse(getQuery(requestObj.url).endTime) + let step = 0 + arr.forEach(item => { + let startTime = JSON.parse(getQuery(requestObj.url).startTime) + step = (endTime - startTime) / 60 // 每条数据的时间间隔 + const max = 2975 + const min = 0 + const values = [] + for (let i = 0; i < step; i++) { + const random = Math.floor(Math.random() * (max - min) + min) + values.push([startTime, random]) + startTime += step + } + item.values = values + item.aggregation = { first: 0, last: 0, avg: '602.64', p50: '0.0', p90: '1852.0', max: '5256.0' } + }) + + const data = { + result: arr, + resultType: 'matrix' + } + + return { + msg: 'success', + code: 200, + data: data + } + }) + Mock.mock(new RegExp(`${urlAndVersion}/entity/explorer/detail/subscriber/relate.*`), 'get', function (requestObj) { + const result = { + total: 5, + result: ['appName1', 'appName2', 'appName3', 'appName4', 'appName5', 'appName6', 'appName7', 'appName1', 'appName2', 'appName3', 'appName4', 'appName5', 'appName6', 'appName7'] + } + + return { + msg: 'success', + code: 200, + data: result + } + }) } const getQuery = (url) => { @@ -773,6 +828,9 @@ const getEntityType = (url) => { if (url.indexOf('/app?') > -1) { entityType = 'app' } + if (url.indexOf('/subscriber_id?') > -1) { + entityType = 'subscriber_id' + } return entityType } @@ -787,5 +845,8 @@ const getRelateType = (url) => { if (url.indexOf('/apps?') > -1) { entityType = 'app' } + if (url.indexOf('/subscriber_id?') > -1) { + entityType = 'subscriber_id' + } return entityType } diff --git a/src/utils/api.js b/src/utils/api.js index 86b0ed06..eb29d9f6 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -313,15 +313,18 @@ export const api = { domainBasicInfo: apiVersion + '/entity/explorer/detail/basic/domain', // Domain实体响应结果 ipBasicInfo: apiVersion + '/entity/explorer/detail/basic/ip', // ip实体响应 appBasicInfo: apiVersion + '/entity/explorer/detail/basic/app', // app实体响应 + subscriberBasicInfo: apiVersion + '/entity/explorer/detail/basic/subscriber', // subscriber实体响应 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', // 实体流量信息 + subscriberThroughput: apiVersion + '/entity/explorer/detail/traffic/throughput/subscriber', // 实体流量信息 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网络质量 + subscriberPerformance: apiVersion + '/entity/explorer/detail/traffic/performance/subscriber', // subscriber网络质量 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相关域名 @@ -349,7 +352,8 @@ export const api = { 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数据概览 + entityTotal: apiVersion + '/entity/explorer/overview/total', // entity首页total数据概览 + subscriberRelatedApp: apiVersion + '/entity/explorer/detail/subscriber/relate/apps' // subscriber相关app } }, location: { diff --git a/src/views/entityExplorer/EntityExplorer.vue b/src/views/entityExplorer/EntityExplorer.vue index 5d92c95b..3430eeae 100644 --- a/src/views/entityExplorer/EntityExplorer.vue +++ b/src/views/entityExplorer/EntityExplorer.vue @@ -46,7 +46,8 @@ {{ summaryCount.totalCount }} {{$t('overall.results')}},IP {{ summaryCount.ipCount }},{{$t('overall.domain')}} {{ summaryCount.domainCount }},APP - {{ summaryCount.appCount }} + {{ summaryCount.appCount }},{{$t('overall.subscriber')}} + {{ summaryCount.subscriberCount }} @@ -172,6 +173,36 @@ +
+
+ + {{ $t('overall.subscriber') }} + +
+
+
+ +
{{ $t('network.total') }}
+
+ +
{{ numberWithCommas(entitySubscriberTotal) }}
+
+
+ +
+ +
{{ $t('entity.active') }}
+
+ +
+ {{ numberWithCommas(entitySubscriberActive) }} + {{ $t('entity.inLastHour') }} +
+
+
+
+
+ @@ -226,6 +257,10 @@ export default { entityIpNew: '-', entityIpActive: '-', + entitySubscriberTotal: '-', + entitySubscriberNew: '-', + entitySubscriberActive: '-', + newFilterData: [ { icon: 'cn-icon cn-icon-registration-country', @@ -310,10 +345,12 @@ export default { loadingApp: false, loadingDomain: false, loadingIp: false, + loadingSubscriber: false, // Active loadingAppActive: false, loadingDomainActive: false, loadingIpActive: false, + loadingSubscriberActive: false, initFlag: true, // 初始化标志,避免初始化时pageSize和pageNo会调用搜索 timer: null, // 初始化标志的延时器,需要销毁 @@ -321,7 +358,8 @@ export default { totalCount: 0, domainCount: 0, ipCount: 0, - appCount: 0 + appCount: 0, + subscriberCount: 0 }, loadingCount: false, // 实体基数统计的loading keywordList: [] @@ -539,6 +577,17 @@ export default { }, /** 新版查询filter数据 */ queryFilterNew (params) { + const subscriberList = ['subscriber.phone_number', 'subscriber.imei', 'subscriber.imsi', 'subscriber.apn'] + let subscriberFlag = false + subscriberList.forEach(item => { + if (params.q.indexOf(item) > -1) { + this.newFilterData = [] + subscriberFlag = true + } + }) + if (subscriberFlag) { + return true + } const queryParams = { startTime: getSecond(params.startTime), endTime: getSecond(params.endTime), @@ -614,13 +663,15 @@ export default { this.listData = [] this.$nextTick(() => { this.listData = response.data.data.list - /*if (this.listData.length === 0) { + /* if (this.listData.length === 0) { this.isHideRelatedEntities = false - }*/ + } */ }) } else { this.$message.error(response.data.message) } + }).catch((e) => { + this.listData = [] }).finally(() => { this.listLoading = false }) @@ -639,11 +690,11 @@ export default { this.summaryCount = response.data.data this.pageObj.total = response.data.data.totalCount } else { - this.summaryCount = { totalCount: 0, domainCount: 0, ipCount: 0, appCount: 0 } + this.summaryCount = { totalCount: 0, domainCount: 0, ipCount: 0, appCount: 0, subscriberCount: 0 } } }).catch(e => { console.error(e) - this.summaryCount = { totalCount: 0, domainCount: 0, ipCount: 0, appCount: 0 } + this.summaryCount = { totalCount: 0, domainCount: 0, ipCount: 0, appCount: 0, subscriberCount: 0 } }).finally(() => { this.loadingCount = false }) @@ -672,20 +723,27 @@ export default { this.loadingApp = true this.loadingDomain = true this.loadingIp = true + this.loadingSubscriber = true // Active this.loadingAppActive = true this.loadingDomainActive = true this.loadingIpActive = true + this.loadingSubscriberActive = true axios.get(api.entity.entityList.entityTotal).then(response => { if (response.status === 200) { this.entityDomainTotal = response.data.data.domainCount this.entityIpTotal = response.data.data.ipCount this.entityAppTotal = response.data.data.appCount + this.entitySubscriberTotal = response.data.data.subscriberCount } + }).catch((e) => { + this.$message.error(e.response.data.message) + }).finally(() => { this.loadingDomain = false this.loadingIp = false this.loadingApp = false + this.loadingSubscriber = false }) // Active axios.get(api.entity.entityList.entityActive).then(response => { @@ -693,10 +751,15 @@ export default { this.entityDomainActive = response.data.data.domainCount this.entityIpActive = response.data.data.ipCount this.entityAppActive = response.data.data.appCount + this.entitySubscriberActive = response.data.data.subscriberCount } + }).catch((e) => { + this.$message.error(e.response.data.message) + }).finally(() => { this.loadingDomainActive = false this.loadingIpActive = false this.loadingAppActive = false + this.loadingSubscriberActive = false }) }, setListMode (mode) { diff --git a/src/views/entityExplorer/entityList/Row.vue b/src/views/entityExplorer/entityList/Row.vue index d92a94be..e4634e3f 100644 --- a/src/views/entityExplorer/entityList/Row.vue +++ b/src/views/entityExplorer/entityList/Row.vue @@ -11,8 +11,11 @@
- {{ entityData.entityValue || 'Unknown' }} - + + {{ entityData.category ? appRisk(entityData.category.appRisk) : '-' }}
+
@@ -102,21 +117,7 @@
-
-
-
-
-
-
+
@@ -130,27 +131,13 @@
-
-
-
-
-
-
+
-
+
{{ $t('network.score') }} :   @@ -181,9 +168,11 @@
-
-
{{ $t('overall.detail') }} >
-
{{ $t('entities.graph') }} >
+
+
+
{{ $t('overall.detail') }} >
+
{{ $t('entities.graph') }} >
+
@@ -277,6 +266,10 @@ export default { url = api.entity.entityList.appBasicInfo break } + case ('subscriber_id'): { + url = api.entity.entityList.subscriberBasicInfo + break + } } axios.get(`${url}?resource=${this.entity.entityValue}`).then(response => { this.$nextTick(() => { diff --git a/src/views/entityExplorer/entityList/detailOverview/App.vue b/src/views/entityExplorer/entityList/detailOverview/App.vue index 4dbb3e0c..332336ff 100644 --- a/src/views/entityExplorer/entityList/detailOverview/App.vue +++ b/src/views/entityExplorer/entityList/detailOverview/App.vue @@ -45,7 +45,7 @@
{{$t('overall.throughput')}}
-
+
{{$t('overall.sent')}}: {{valueToRangeValue(entityData.bytesSentRate, unitTypes.bps).join(' ') !== '- ' ? valueToRangeValue(entityData.bytesSentRate, unitTypes.bps).join(' ') : '-'}}
diff --git a/src/views/entityExplorer/entityList/detailOverview/DetailOverview.vue b/src/views/entityExplorer/entityList/detailOverview/DetailOverview.vue index 3bbb1893..69dfa45e 100644 --- a/src/views/entityExplorer/entityList/detailOverview/DetailOverview.vue +++ b/src/views/entityExplorer/entityList/detailOverview/DetailOverview.vue @@ -9,6 +9,9 @@ +
@@ -16,6 +19,7 @@ import App from './App' import Domain from './Domain' import Ip from './Ip' +import Subscriber from './Subscriber' export default { /* 详情概览 */ @@ -28,7 +32,8 @@ export default { components: { 'domain-overview': Domain, 'app-overview': App, - 'ip-overview': Ip + 'ip-overview': Ip, + 'subscriber-overview': Subscriber }, methods: { getEntity (data) { diff --git a/src/views/entityExplorer/entityList/detailOverview/Domain.vue b/src/views/entityExplorer/entityList/detailOverview/Domain.vue index 70de563b..935b2922 100644 --- a/src/views/entityExplorer/entityList/detailOverview/Domain.vue +++ b/src/views/entityExplorer/entityList/detailOverview/Domain.vue @@ -51,7 +51,7 @@
{{$t('overall.throughput')}}
-
+
{{$t('overall.sent')}}: {{valueToRangeValue(entityData.bytesSentRate, unitTypes.bps).join(' ') !== '- ' ? valueToRangeValue(entityData.bytesSentRate, unitTypes.bps).join(' ') : '-'}}
diff --git a/src/views/entityExplorer/entityList/detailOverview/Ip.vue b/src/views/entityExplorer/entityList/detailOverview/Ip.vue index 139c889f..6f0fd43c 100644 --- a/src/views/entityExplorer/entityList/detailOverview/Ip.vue +++ b/src/views/entityExplorer/entityList/detailOverview/Ip.vue @@ -87,7 +87,7 @@
{{$t('overall.throughput')}}
-
+
{{$t('overall.sent')}}: {{valueToRangeValue(entityData.bytesSentRate, unitTypes.bps).join(' ') !== '- ' ? valueToRangeValue(entityData.bytesSentRate, unitTypes.bps).join(' ') : '-'}}
diff --git a/src/views/entityExplorer/entityList/detailOverview/Subscriber.vue b/src/views/entityExplorer/entityList/detailOverview/Subscriber.vue new file mode 100644 index 00000000..32deb3b8 --- /dev/null +++ b/src/views/entityExplorer/entityList/detailOverview/Subscriber.vue @@ -0,0 +1,261 @@ + + + diff --git a/src/views/entityExplorer/entityList/detailOverview/SubscriberMap.vue b/src/views/entityExplorer/entityList/detailOverview/SubscriberMap.vue new file mode 100644 index 00000000..46223dff --- /dev/null +++ b/src/views/entityExplorer/entityList/detailOverview/SubscriberMap.vue @@ -0,0 +1,713 @@ + + + diff --git a/src/views/entityExplorer/entityList/entityListMixin.js b/src/views/entityExplorer/entityList/entityListMixin.js index 8173749a..51b63ecc 100644 --- a/src/views/entityExplorer/entityList/entityListMixin.js +++ b/src/views/entityExplorer/entityList/entityListMixin.js @@ -51,6 +51,10 @@ export default { className = 'cn-icon cn-icon-app2' break } + case ('subscriber_id'): { + className = 'cn-icon cn-icon-pedestrian' + break + } default: break } return className @@ -264,6 +268,10 @@ export default { this.performanceEventUrl = api.entity.entityList.appEventPerformance break } + case 'subscriber_id': { + this.trafficUrl = api.entity.entityList.subscriberThroughput + break + } default: break } @@ -348,8 +356,10 @@ export default { this.initUrl() setTimeout(() => { this.queryEntityDetailTraffic() - this.queryNetworkQuantity() - this.queryEventNum() + if (this.entity.entityType !== 'subscriber_id') { + this.queryNetworkQuantity() + this.queryEventNum() + } }) }, beforeUnmount () {