diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/assets/css/components/views/entityExplorer/entity-filter.scss | 1 | ||||
| -rw-r--r-- | src/assets/css/components/views/entityExplorer/entityList/entity-list.scss | 2 | ||||
| -rw-r--r-- | src/components/common/Pagination.vue | 31 | ||||
| -rw-r--r-- | src/components/layout/Header.vue | 4 | ||||
| -rw-r--r-- | src/views/entityExplorer/EntityExplorer.vue | 140 | ||||
| -rw-r--r-- | src/views/entityExplorer/EntityFilter.vue | 87 | ||||
| -rw-r--r-- | src/views/entityExplorer/entityList/EntityList.vue | 6 |
7 files changed, 172 insertions, 99 deletions
diff --git a/src/assets/css/components/views/entityExplorer/entity-filter.scss b/src/assets/css/components/views/entityExplorer/entity-filter.scss index 11b71e9e..6d65ccb8 100644 --- a/src/assets/css/components/views/entityExplorer/entity-filter.scss +++ b/src/assets/css/components/views/entityExplorer/entity-filter.scss @@ -32,6 +32,7 @@ width: calc(100% - 30px); margin: 0 10px 0 20px; max-height: 265px; + min-height: 40px; overflow-y: scroll; overflow-x: hidden; diff --git a/src/assets/css/components/views/entityExplorer/entityList/entity-list.scss b/src/assets/css/components/views/entityExplorer/entityList/entity-list.scss index 8542d855..1df06a41 100644 --- a/src/assets/css/components/views/entityExplorer/entityList/entity-list.scss +++ b/src/assets/css/components/views/entityExplorer/entityList/entity-list.scss @@ -21,7 +21,7 @@ .entity-list--list { display: flex; flex-direction: column; - height: 100%; + height: auto; /*overflow: visible;/*overflow: auto;*/ .cn-entity__shadow { diff --git a/src/components/common/Pagination.vue b/src/components/common/Pagination.vue index 9e898ca1..0f03cadd 100644 --- a/src/components/common/Pagination.vue +++ b/src/components/common/Pagination.vue @@ -58,13 +58,24 @@ export default { */ setup (props) { const { query } = useRoute() - const pageSize = ref(defaultPageSize) + // pageSize取值顺序:1.url;2.缓存;3.pageObj;4.默认值 + const urlPageSize = parseInt(query.pageSize) + const cachePageSize = parseInt(localStorage.getItem(storageKey.pageSize + '-' + localStorage.getItem(storageKey.username) + '-' + props.tableId)) + const pageObjPageSize = props.pageObj.pageSize + const pageSize = ref(urlPageSize || cachePageSize || pageObjPageSize || defaultPageSize) const currentPageNo = ref(props.storePageNoOnUrl ? (query.pageNo || (props.pageObj.pageNo || 1)) : (props.pageObj.pageNo || 1)) return { pageSize, currentPageNo } }, + mounted () { + if (this.postPageSizes && this.postPageSizes.length > 0) { + this.resetPageSizes() + } + this.currentPageNo = parseInt(this.currentPageNo) + this.current(this.currentPageNo) + }, data () { return { // pageSize: defaultPageSize, @@ -147,6 +158,7 @@ export default { size (val) { // eslint-disable-next-line vue/no-mutating-props // this.pageObj.pageNo = 1 + this.$emit('scrollbarToTop') this.$emit('pageSize', val) this.backgroundColor() @@ -163,11 +175,12 @@ export default { wrap.scrollTop = 0 } }) + this.$emit('scrollbarToTop') }) }, resetPageSizes: function () { if (this.postPageSizes) { - this.pageSizes = this.postPageSizes.map((item) => { + this.pageSizes = this.postPageSizes.map(item => { return { label: item + this.$t('pageSize'), value: item @@ -183,20 +196,6 @@ export default { // } } }, - mounted () { - if (this.postPageSizes && this.postPageSizes.length > 0) { - this.pageSize = this.postPageSizes[0] - this.resetPageSizes() - } else { - const pageSize = localStorage.getItem(storageKey.pageSize + '-' + localStorage.getItem(storageKey.username) + '-' + this.tableId) - if (pageSize != 'undefined' && pageSize != null) { - this.pageSize = parseInt(pageSize) - } - } - - this.currentPageNo = parseInt(this.currentPageNo) - this.current(this.currentPageNo) - }, watch: { postPageSizes: { immediate: true, diff --git a/src/components/layout/Header.vue b/src/components/layout/Header.vue index d35603f5..541e3d48 100644 --- a/src/components/layout/Header.vue +++ b/src/components/layout/Header.vue @@ -804,10 +804,10 @@ export default { } }) } - if (route === this.route) { + /* if (route === this.route) { this.refresh() return - } + } */ if (route) { this.$router.push({ path: route, diff --git a/src/views/entityExplorer/EntityExplorer.vue b/src/views/entityExplorer/EntityExplorer.vue index 5b58ae20..262deee5 100644 --- a/src/views/entityExplorer/EntityExplorer.vue +++ b/src/views/entityExplorer/EntityExplorer.vue @@ -185,7 +185,6 @@ export default { }, data () { return { - showList: false, listMode: 'list', // entity列表的模式,list|block entityAppTotal: '-', @@ -213,28 +212,36 @@ export default { title: this.$t('entity.topCountries'), topColumn: 'ip.country', totalCount: 0, - data: [] + data: [], + loading: false, + firstLoad: true }, { icon: 'cn-icon cn-icon-city', title: this.$t('entity.topCities'), topColumn: 'ip.city', totalCount: 0, - data: [] + data: [], + loading: false, + firstLoad: true }, { icon: 'cn-icon cn-icon-as', title: this.$t('entity.topASNs'), topColumn: 'ip.asn', totalCount: 0, - data: [] + data: [], + loading: false, + firstLoad: true }, { icon: 'cn-icon cn-icon-operator', title: this.$t('entity.topISPs'), topColumn: 'ip.isp', totalCount: 0, - data: [] + data: [], + loading: false, + firstLoad: true }, { icon: 'cn-icon cn-icon-open-port', @@ -242,28 +249,36 @@ export default { topColumn: 'ip.port', topColumn1: 'ip.protocol', totalCount: 0, - data: [] + data: [], + loading: false, + firstLoad: true }, { icon: 'cn-icon cn-icon-FQDN', title: this.$t('entity.topFQDNCategories'), topColumn: 'domain.category', totalCount: 0, - data: [] + data: [], + loading: false, + firstLoad: true }, { icon: 'cn-icon cn-icon-category2', title: this.$t('entity.topAppCategories'), topColumn: 'app.category', totalCount: 0, - data: [] + data: [], + loading: false, + firstLoad: true }, { icon: 'cn-icon cn-icon-tag1', title: this.$t('entity.topTags'), topColumn: 'tag', totalCount: 0, - data: [] + data: [], + loading: false, + firstLoad: true } ], listData: [], @@ -396,16 +411,17 @@ export default { mode: mode, range: this.timeFilter.dateRangeValue, pageNo: this.pageObj.pageNo, - pageSize: this.pageObj.pageSize + pageSize: this.pageObj.pageSize, + showList: true } }) - this.showList = true + // this.showList = true // 跳转页面,则不执行搜索功能 return true } - this.queryFilterNew({ q: this.q, ...this.pageObj, ...this.timeFilter }) this.queryList({ q: this.q, ...this.pageObj, ...this.timeFilter }) + this.queryFilterNew({ q: this.q, ...this.pageObj, ...this.timeFilter }) this.queryCount({ q: this.q, ...this.pageObj, ...this.timeFilter }) // 延时一秒,避免初始化时pageSize为20,pageNo为1也会调用“搜索”的情况 @@ -489,8 +505,8 @@ export default { /** 新版查询filter数据 */ queryFilterNew (params) { const queryParams = { - // startTime: getSecond(params.startTime), - // endTime: getSecond(params.endTime), + startTime: getSecond(params.startTime), + endTime: getSecond(params.endTime), resource: params.q || '' } this.loadingLeft = true @@ -502,8 +518,48 @@ export default { const aggDomain = axios.get(api.entity.entityList.aggDomain, { params: queryParams }) const aggAppCategory = axios.get(api.entity.entityList.aggAppCategory, { params: queryParams }) const aggTag = axios.get(api.entity.entityList.aggTag, { params: queryParams }) - - Promise.all([aggCountry, aggCity, aggIPAsn, aggIPIsp, aggPort, aggDomain, aggAppCategory, aggTag]).then(response => { + const requests = [aggCountry, aggCity, aggIPAsn, aggIPIsp, aggPort, aggDomain, aggAppCategory, aggTag] + requests.forEach((req, index) => { + this.newFilterData[index].loading = true + req.then(response => { + if (response.status === 200 && response.data.data.list) { + if (response.data.data.list.length >= 5) { + this.newFilterData[index].showNum = 5 + } else { + this.newFilterData[index].showNum = response.data.data.list.length + } + this.newFilterData[index].data = [] + response.data.data.list.forEach((item, i) => { + let obj = { + label: item.value, + topColumn: this.newFilterData[index].topColumn, + value: item.uniqueEntities, + showNum: 5 + } + if (index === 0) { + obj.flag = item.value // 接口字段名称为'China',svg名称为'CN',通过countryNameIdMapping进行转换 + } + if (index === 4) { + obj = { + topColumn: this.newFilterData[index].topColumn, + topColumn1: this.newFilterData[index].topColumn1, + port: item.port, + l7Protocol: item.l7Protocol, + value: item.uniqueEntities, + showNum: 5 + } + } + this.newFilterData[index].data.push(obj) + }) + } + }).catch(e => { + this.$message.error(e.response.data.message) + }).finally(() => { + this.newFilterData[index].loading = false + this.newFilterData[index].firstLoad = false + }) + }) + /*Promise.all([aggCountry, aggCity, aggIPAsn, aggIPIsp, aggPort, aggDomain, aggAppCategory, aggTag]).then(response => { response.forEach((item1, index) => { if (item1.status === 200 && item1.data.data.list) { if (item1.data.data.list.length >= 5) { @@ -540,7 +596,7 @@ export default { this.$message.error(e.response.data.message) }).finally(() => { this.loadingLeft = false - }) + })*/ }, /** 实体列表查询 */ queryList (params) { @@ -548,8 +604,8 @@ export default { const queryParams = { pageSize: params.pageSize, pageNo: params.pageNo, - // startTime: getSecond(params.startTime), - // endTime: getSecond(params.endTime), + startTime: getSecond(params.startTime), + endTime: getSecond(params.endTime), resource: params.q || '' } axios.get(api.entity.entityList.list, { params: queryParams }).then(response => { @@ -570,8 +626,8 @@ export default { queryCount (params) { this.loadingCount = true const queryParams = { - // startTime: getSecond(params.startTime), - // endTime: getSecond(params.endTime), + startTime: getSecond(params.startTime), + endTime: getSecond(params.endTime), resource: params.q || '' } axios.get(api.entity.entityList.summaryCount, { params: queryParams }).then(response => { @@ -692,23 +748,25 @@ export default { } }, mounted () { - this.getEntityIndexData() - let { q, listMode } = this.$route.query + if (!this.showList) { + this.getEntityIndexData() + } else { + let { q, listMode } = this.$route.query - // 如果地址栏有listMode,即列表页,并非首页,则开始搜索 - if (listMode) { - this.showList = true - // %位置为0是输入中文时能解码,%20,25%分别是空格和%的情况 - if (q && (q.indexOf('%') === 0 || q.indexOf('%20') > -1 || q.indexOf('%25') > -1)) { - q = decodeURI(q) - } - // %位置不为0,即内容包含非英文时 - const str1 = q.substring(q.indexOf('%'), q.indexOf('%') + 3) - if (q && q.indexOf('%') > 0 && (str1 !== '%20' || str1 === '%25')) { - q = decodeURI(q) + // 如果地址栏有listMode,即列表页,并非首页,则开始搜索 + if (listMode) { + // %位置为0是输入中文时能解码,%20,25%分别是空格和%的情况 + if (q && (q.indexOf('%') === 0 || q.indexOf('%20') > -1 || q.indexOf('%25') > -1)) { + q = decodeURI(q) + } + // %位置不为0,即内容包含非英文时 + const str1 = q.substring(q.indexOf('%'), q.indexOf('%') + 3) + if (q && q.indexOf('%') > 0 && (str1 !== '%20' || str1 === '%25')) { + q = decodeURI(q) + } + this.initSearch(q) + this.listMode = listMode } - this.initSearch(q) - this.listMode = listMode } }, watch: { @@ -722,11 +780,12 @@ export default { const rangeParam = query.range const startTimeParam = query.startTime const endTimeParam = query.endTime + const showList = ref(Boolean(query.showList)) // 若url携带了,使用携带的值,否则使用默认值。 - const dateRangeValue = rangeParam ? parseInt(query.range) : 60 + const dateRangeValue = rangeParam ? parseInt(query.range) : 60 * 24 const timeFilter = ref({ dateRangeValue }) if (!startTimeParam || !endTimeParam) { - const { startTime, endTime } = getNowTime(60) + const { startTime, endTime } = getNowTime(60 * 24) timeFilter.value.startTime = startTime timeFilter.value.endTime = endTime } else { @@ -737,12 +796,13 @@ export default { pageNo: query.pageNo ? parseInt(query.pageNo) : 1, // 是否重置pageNo,在执行新搜索时是true resetPageNo: true, - pageSize: query.pageSize ? parseInt(query.pageSize) : defaultPageSize, + pageSize: query.pageSize ? parseInt(query.pageSize) : 10, // TODO 23-10-14 默认暂时改为10 total: 0 }) return { timeFilter, - pageObj + pageObj, + showList } }, beforeUnmount () { diff --git a/src/views/entityExplorer/EntityFilter.vue b/src/views/entityExplorer/EntityFilter.vue index 0200c592..b29b765e 100644 --- a/src/views/entityExplorer/EntityFilter.vue +++ b/src/views/entityExplorer/EntityFilter.vue @@ -2,51 +2,49 @@ <div class="entity-filter-case" style="position: relative"> <div class="filter-case__header">{{ $t('entities.filter1') }}</div> - <div v-if="filterDataLength>0"> + <div v-if="filterDataLength > 0"> <div class="entity-filter" v-for="(item, index) in myFilterData" :key="index"> - <div v-if="item.data.length>0"> - <div class="filter__header"> - <i :class="item.icon"></i> - {{ item.title }} - </div> + <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" style="position: relative"> + <loading :loading="item.loading" style="top: -5px;"></loading> - <div class="filter__body-item" - v-for="(data, i) in item.data.slice(0, item.showNum)" - :key="i" - @click="filter(data.label, data)"> - <div class="filter__body-item-left"> - <div v-if="data.flag"> - <img v-if="data.flag===countryNameIdMapping.Unknown || !countryNameIdMapping[data.flag]" src="../../../public/images/flag/Unknown.svg" class="filter-country-flag"> - <img v-else :src="require(`../../../public/images/flag/${countryNameIdMapping[data.flag]}.png`)" class="filter-country-flag"/> - </div> - <div v-else 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}`"> - <span v-if="item.topColumn==='ip.port'"> - {{ data.port }}/{{ data.l7Protocol }} - </span> - <span v-else>{{ data.label }}</span> + <div class="filter__body-item" + v-for="(data, i) in item.data.slice(0, item.showNum)" + :key="i" + @click="filter(data.label, data)"> + <div class="filter__body-item-left"> + <div v-if="data.flag"> + <img v-if="data.flag===countryNameIdMapping.Unknown || !countryNameIdMapping[data.flag]" src="../../../public/images/flag/Unknown.svg" class="filter-country-flag"> + <img v-else :src="require(`../../../public/images/flag/${countryNameIdMapping[data.flag]}.png`)" class="filter-country-flag"/> + </div> + <div v-else 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}`"> + <span v-if="item.topColumn==='ip.port'"> + {{ data.port }}/{{ data.l7Protocol }} </span> - </el-tooltip> - </div> + <span v-else>{{ data.label }}</span> + </span> + </el-tooltip> </div> - <div class="filter__body-item-right">{{ data.value }}</div> </div> + <div class="filter__body-item-right">{{ data.value }}</div> </div> - <div @click="showMoreFilter(item, index)" - :class="item.showNum === item.data.length ? 'filter-no-show-more' : 'filter-show-more'"> - {{ $t('entity.showMore') }} - </div> - <div class="filter-hr"></div> </div> + <div @click="showMoreFilter(item, index)" + :class="item.showNum >= item.data.length || item.data.length <= 5 ? 'filter-no-show-more' : 'filter-show-more'"> + {{ $t('entity.showMore') }} + </div> + <div class="filter-hr"></div> </div> </div> + <loading v-else-if="isFirstLoad" :loading="isFirstLoad"></loading> <chart-no-data v-else style="padding-top: 40px"></chart-no-data> - </div> </template> @@ -54,6 +52,7 @@ import Loading from '@/components/common/Loading' import ChartNoData from '@/views/charts/charts/ChartNoData' import { countryNameIdMapping } from '@/utils/constants' +import _ from 'lodash' export default { name: 'EntityFilter', components: { ChartNoData, Loading }, @@ -73,6 +72,9 @@ export default { }) return length + }, + isFirstLoad () { + return this.myFilterData.some(d => d.firstLoad) } }, data () { @@ -85,6 +87,14 @@ export default { mounted () { this.myFilterData = this.filterData }, + watch: { + filterData: { + deep: true, + handler (n) { + this.myFilterData = _.cloneDeep(n) + } + } + }, methods: { /** * 判断文字是否溢出,超出则鼠标移入tooltip显示,否则鼠标移入不显示 @@ -103,17 +113,14 @@ export default { this.$emit('filter', name, data) }, showMoreFilter (item, index) { - if ((item.data.length - item.showNum) >= 5) { + this.myFilterData[index].showNum = item.data.length + /*if ((item.data.length - item.showNum) >= 5) { item.shouNum += 5 this.myFilterData[index].showNum += 5 } else { this.myFilterData[index].showNum += (item.data.length - item.showNum) - } + }*/ } } } </script> - -<style lang="scss" scoped> - -</style> diff --git a/src/views/entityExplorer/entityList/EntityList.vue b/src/views/entityExplorer/entityList/EntityList.vue index 20dc36ea..830beb24 100644 --- a/src/views/entityExplorer/entityList/EntityList.vue +++ b/src/views/entityExplorer/entityList/EntityList.vue @@ -38,11 +38,13 @@ <Pagination ref="pagination" :page-obj="pageObj" + :post-page-sizes="[10, 20, 50]" @pageNo='pageNo' @pageSize='pageSize' @size-change="pageSize" @prev-click="prev" @next-click="next" + @scrollbarToTop="scrollbarToTop" > </Pagination> </div> @@ -124,6 +126,10 @@ export default { const container = document.getElementById('cnContainer') container.scrollTop += e.deltaY / 2 } + }, + scrollbarToTop () { + const container = document.getElementById('cnContainer') + container.scrollTop = 0 } }, mounted () { |
