diff --git a/src/components/charts/chart-options.js b/src/components/charts/chart-options.js index 8329e981..6c14e628 100644 --- a/src/components/charts/chart-options.js +++ b/src/components/charts/chart-options.js @@ -321,6 +321,54 @@ const singleValueLine = { } ] } +export const entityListLineOption = { + tooltip: { + appendToBody: true, + trigger: 'axis', + textStyle: { + width: '20px', + overflow: 'truncate' + }, + formatter: axiosFormatter, + show: true, + className: 'nz-chart-tooltip', + extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);max-width: 300px !important' + }, + xAxis: { + type: 'time', + show: false + }, + yAxis: { + type: 'value', + show: false + }, + animation: false, + grid: { + left: 0, + bottom: 2, + top: 5, + right: 0 + }, + color: chartColor, + legend: { + show: false + }, + series: [ + { + type: 'line', + legendHoverLink: false, + itemStyle: { + normal: { + lineStyle: { + width: 2 + } + } + }, + data: [], + showSymbol: false + } + ] +} const relationShip = { grid: { left: 0, diff --git a/src/components/charts/chart-table-title.js b/src/components/charts/chart-table-title.js index 8c76fe24..c10eb47b 100644 --- a/src/components/charts/chart-table-title.js +++ b/src/components/charts/chart-table-title.js @@ -8,6 +8,10 @@ export const tableTitleMapping = { label: i18n.global.t('overall.serverIp'), prop: 'serverIp' }, + ip: { + label: 'IP', + prop: 'ip' + }, appId: { label: 'APP ID', prop: 'appId' @@ -37,6 +41,9 @@ export const legendMapping = { bytes_received_rate: i18n.global.t('trafficSummary.throughputPerSecondC2s'), bytes_sent_rate: i18n.global.t('trafficSummary.throughputPerSecondS2c'), bytes_rate: i18n.global.t('trafficSummary.throughputPerSecond'), + ip_bytes_received_rate: i18n.global.t('trafficSummary.receivedPerSecond'), + ip_bytes_sent_rate: i18n.global.t('trafficSummary.sentPerSecond'), + ip_bytes_rate: i18n.global.t('trafficSummary.throughputPerSecond'), session_rate: i18n.global.t('trafficSummary.sessionsPerSecond'), packets_rate: i18n.global.t('trafficSummary.packetsPerSecond'), packets_received_rate: i18n.global.t('trafficSummary.packetsPerSecondC2s'), diff --git a/src/components/charts/panel.scss b/src/components/charts/panel.scss index 5a6dd8db..da79c3a7 100644 --- a/src/components/charts/panel.scss +++ b/src/components/charts/panel.scss @@ -120,7 +120,9 @@ width: 100%; } } - + &>.cn-chart__whois>.cn-chart__body { + overflow: auto; + } &>.cn-chart__echarts, &>.cn-chart__table, &>.cn-chart__map, &>.cn-chart__group, &>.cn-chart__whois, &>.cn-chart__dns-record, &>.cn-chart__app-basic { display: flex; flex-direction: column; diff --git a/src/components/entities/EntityList.vue b/src/components/entities/EntityList.vue index 5c575e5a..a4c698e8 100644 --- a/src/components/entities/EntityList.vue +++ b/src/components/entities/EntityList.vue @@ -1,7 +1,7 @@ @@ -24,7 +24,7 @@ {{d.appName || 'Unknown'}}
- {{$t('entities.risk')}}: + {{$t('entities.risk')}}:  {{d.appRisk || '-'}}
@@ -45,13 +45,13 @@ {{$t('entities.asn')}}:
{{d.asn || '-'}}
- - -
22 bps
-
0 bps
-
{{$t('overall.detail')}}>
- + +
+
+
+
{{d.latestReceived}} bps
+
{{d.latestSent}} bps
+
{{$t('overall.detail')}}>
@@ -110,92 +114,249 @@ \ No newline at end of file + diff --git a/src/components/entities/entities.scss b/src/components/entities/entities.scss index 4bd63240..2019b641 100644 --- a/src/components/entities/entities.scss +++ b/src/components/entities/entities.scss @@ -165,6 +165,20 @@ padding: 5px 0; justify-content: left; } + .body__drawing-box { + position: relative; + height: 100px; + .chart__loading { + top: 0; + height: 100%; + } + } + .body__drawing { + position: absolute; + padding: 10px 30px; + height: 100px; + width: 100%; + } .body__row-label { padding-right: 0px; diff --git a/src/utils/api.js b/src/utils/api.js index 1fa3f5ad..5154d77a 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -21,7 +21,10 @@ export const api = { chart: '/visual/chart', entityList: '/interface/entity/list', entityCount: '/interface/entity/total', - entityFilter: '/interface/entity/filter' + entityFilter: '/interface/entity/filter', + ipThroughput: '/interface/entity/ip/detail/throughput', + domainThroughput: '/interface/entity/domain/detail/throughput', + appThroughput: '/interface/entity/app/detail/throughput' } /* panel */ diff --git a/src/views/charts/Chart.vue b/src/views/charts/Chart.vue index b245377e..23f75562 100644 --- a/src/views/charts/Chart.vue +++ b/src/views/charts/Chart.vue @@ -409,10 +409,10 @@
- {{detailData ? detailData.name : '-'}} - {{detailData ? detailData.allName : '-'}} - {{detailData ? detailData.tech : '-'}} - {{detailData ? detailData.remark : '-'}} + {{detailData.name || '-'}} + {{detailData.allName || '-'}} + {{detailData.tech || '-'}} + {{detailData.description || '-'}}
{{$t('entities.category')}} {{$t('entities.subcategory')}} {{$t('entities.reputationLevel')}}
@@ -725,6 +725,20 @@ export default { this.isError = true this.errorInfo = e }) + } else if (this.isAppBasicInfo) { + const queryParams = { app: this.entity.app } + get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => { + if (response.code === 200) { + this.detailData = response.data.result + } else { + this.isError = true + this.noData = true + this.errorInfo = response.msg || response.message || 'Unknown' + } + }).catch(e => { + this.isError = true + this.errorInfo = e + }) } } catch (e) { console.error(e) @@ -970,7 +984,7 @@ export default { if (data.length > 0) { const dataColumns = Object.keys(data[0]) // 返回数据的字段 const columns = dataColumns.map(c => tableTitleMapping[c]) // 展示字段 - const keys = ['clientIp', 'serverIp', 'appId', 'app', 'domain'] + const keys = ['clientIp', 'serverIp', 'ip', 'appId', 'app', 'domain'] return columns.sort((a, b) => { if (keys.indexOf(a.prop) > -1) { return -1 @@ -1048,7 +1062,7 @@ export default { this.chartOption.series = response.data.result.map(r => { return { ...seriesTemplate, - name: legendMapping[r.legend] ? legendMapping[r.legend] : lineToSpace(r.legend), + name: legendMapping[`${this.entity.ip ? 'ip_' : ''}${r.legend}`] ? legendMapping[`${this.entity.ip ? 'ip_' : ''}${r.legend}`] : lineToSpace(r.legend), data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1]), chartParams.unitType]) } }) @@ -1240,11 +1254,12 @@ export default { ] this.myChart.setOption(this.chartOption) this.myChart2.setOption(this.chartOption) - /* get(replaceUrlPlaceholder(chartParams.url, { app: this.entity.app })).then(response => { + get(replaceUrlPlaceholder(chartParams.url, { app: this.entity.app })).then(response => { if (response.code === 200) { if (this.$_.isEmpty(response.data.result)) { this.noData = true } else { + this.detailData = response.data.result this.noData = false } } @@ -1252,7 +1267,7 @@ export default { setTimeout(() => { this.loading = false }, 250) - }) */ + }) }, initEchartsWithStatistics (chartParams) { const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), ...this.entity } @@ -1640,6 +1655,9 @@ export default { .hosted-domain__list-row, .related-domain__list-row { padding: 5px 30px; color: #3976CB; + i { + color: #B8C1D1; + } } } .hosted-domain__chart, .related-domain__chart { @@ -1671,14 +1689,14 @@ export default { .domain-detail-list__label { display: table-cell; - padding: 15px 30px; + padding: 13px 30px; border-bottom: 1px solid $--content-right-background-color; width: 170px; color: #6B717B; } .domain-detail-list__content { display: table-cell; - padding: 15px 0 ; + padding: 13px 0 ; border-bottom: 1px solid $--content-right-background-color; color: #3976CB; } diff --git a/src/views/entities/EntityExplorer.vue b/src/views/entities/EntityExplorer.vue index 535479e0..01fea448 100644 --- a/src/views/entities/EntityExplorer.vue +++ b/src/views/entities/EntityExplorer.vue @@ -122,7 +122,12 @@ export default { }, async search () { const params = { from: this.from, q: doubleQuotationToSingle(this.searchContent) } - this.listData = await getEntityList({ ...this.pageObjRight, ...params }) + this.listData = (await getEntityList({ ...this.pageObjRight, ...params })).map(d => ({ + ...d, + id: window.btoa(d.ip || d.domainName || d.appId), + latestSent: null, + latestReceived: null + })) this.pageObjRight.total = await getEntityCount(params) const { topFilterData, bottomFilterData } = await this.queryFilterData(params) this.topFilterData = topFilterData @@ -316,7 +321,6 @@ export default { this.search() }, entityDetail (entity, tabs) { - const entityName = entity.domain || entity.ip || entity.appId this.typeName = `${this.from.toLowerCase()}EntityDetail` this.currentEntity = entity this.showDetail = true