From 1c00f568fa1b4ea67b8dd1f93392d040c7debbd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B4=AA=E6=B4=AA?= <2498601771@qq.com> Date: Mon, 6 Nov 2023 19:50:29 +0800 Subject: [PATCH] =?UTF-8?q?CN-1449=20fix:=20=E5=AE=9E=E4=BD=93=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E7=BB=93=E6=9E=9C=E5=AF=B9=E5=91=BD=E4=B8=AD=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E9=AB=98=E4=BA=AE=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/advancedSearch/TagMode.vue | 13 +++++- src/components/advancedSearch/TextMode.vue | 11 ++++- src/main.js | 3 +- src/utils/tools.js | 43 ++++++++++++++++++ src/views/entityExplorer/EntityExplorer.vue | 44 +++++++++++++++++-- .../entityExplorer/entityList/EntityList.vue | 4 +- src/views/entityExplorer/entityList/Row.vue | 19 ++++---- .../entityList/detailOverview/App.vue | 11 +++-- .../detailOverview/DetailOverview.vue | 9 ++-- .../entityList/detailOverview/Domain.vue | 9 ++-- .../entityList/detailOverview/Ip.vue | 9 ++-- .../entityExplorer/search/ExplorerSearch.vue | 4 +- 12 files changed, 148 insertions(+), 31 deletions(-) diff --git a/src/components/advancedSearch/TagMode.vue b/src/components/advancedSearch/TagMode.vue index 447f114a..7fe72c84 100644 --- a/src/components/advancedSearch/TagMode.vue +++ b/src/components/advancedSearch/TagMode.vue @@ -202,6 +202,7 @@ export default { if (this.isCustomized(value)) { meta.column.type = columnType.fullText meta.column.label = value + meta.column.isFullText = true meta.resetOperator() meta.resetValue() } else { @@ -248,6 +249,7 @@ export default { if (meta.column && meta.column.type === 'fullText') { meta.operator.value = '=' meta.column.show = false + meta.column.isFullText = true meta.operator.show = false const label = JSON.parse(JSON.stringify(meta.column.label)) meta.column.label = parser.getEntityTypeByValue(meta.column.label) @@ -461,13 +463,21 @@ export default { if (this.metaList.length > 0) { const parser = new Parser(this.columnList) const errorList = parser.validateMeta(this.metaList) + const keywordList = [] + this.metaList.forEach(item => { + if (item.column && item.column.isFullText) { + keywordList.push({ type: 'fullText', value: item.value.value }) + } else if (item.column && !item.column.isFullText) { + keywordList.push({ type: item.column.type, value: item.value.value }) + } + }) if (_.isEmpty(errorList)) { const strObj = parser.handleMetaListToStr(this.metaList) const str = strObj.str ? strObj.str : strObj const str2 = strObj.str2 ? strObj.str2 : strObj // str为将metaList转成字符串的值,str2为地址栏展示的值 const key = parser.handleEntityTypeByStr(str) - this.$emit('search', { ...parser.parseStr(key), str: str2 }) + this.$emit('search', { ...parser.parseStr(key), str: str2, keywordList: keywordList }) } else { this.$message.error(handleErrorTip(errorList[0])) } @@ -653,6 +663,7 @@ export default { if (item.column && item.column.type === 'fullText') { item.operator.value = '=' item.column.show = false + item.column.isFullText = true item.operator.show = false const label = JSON.parse(JSON.stringify(item.column.label)) item.column.label = parser.getEntityTypeByValue(item.column.label) diff --git a/src/components/advancedSearch/TextMode.vue b/src/components/advancedSearch/TextMode.vue index bb776eea..663f7456 100644 --- a/src/components/advancedSearch/TextMode.vue +++ b/src/components/advancedSearch/TextMode.vue @@ -97,10 +97,19 @@ export default { if (str) { const parser = new Parser(this.columnList) const keyInfo = parser.comparedEntityKey(parser.handleEntityTypeByStr(str)) + const metaList = parser.parseStr(_.cloneDeep(str)).metaList + const keywordList = [] + metaList.forEach(item => { + if (item.column && item.column.type === columnType.fullText) { + keywordList.push({ type: item.column.type, value: item.column.label }) + } else if (item.column && item.column.type === columnType.string) { + keywordList.push({ type: item.column.type, value: item.value.value }) + } + }) if (keyInfo.isKey) { const errorList = parser.validateStr(keyInfo.key) if (_.isEmpty(errorList)) { - this.$emit('search', { ...parser.parseStr(keyInfo.key), str: str }) + this.$emit('search', { ...parser.parseStr(keyInfo.key), str: str, keywordList: keywordList }) } else { this.$message.error(handleErrorTip(errorList[0])) } diff --git a/src/main.js b/src/main.js index d536b1f7..d25841a1 100644 --- a/src/main.js +++ b/src/main.js @@ -7,7 +7,7 @@ import App from '@/App.vue' import '@/utils/http.js' import { hasPermission } from '@/permission' import commonMixin from '@/mixins/common' -import { cancelWithChange, noData } from '@/utils/tools' +import { cancelWithChange, noData, myHighLight } from '@/utils/tools' import { ClickOutside } from 'element-plus/lib/directives' import i18n from '@/i18n' // import '@/mock/index.js' @@ -41,6 +41,7 @@ app.directive('has', hasPermission) // 注册指令 app.directive('ele-click-outside', ClickOutside) app.directive('cancel', cancelWithChange) app.directive('no-data', noData) +app.directive('high-light', myHighLight) app.config.globalProperties.$_ = _ app.mixin(commonMixin) diff --git a/src/utils/tools.js b/src/utils/tools.js index 3c620224..50d5a41e 100644 --- a/src/utils/tools.js +++ b/src/utils/tools.js @@ -7,6 +7,7 @@ import { format } from 'echarts' import router from '@/router' import store from '@/store' import indexedDBUtils from '@/indexedDB' +import { columnType } from '@/components/advancedSearch/meta/meta' export const tableSort = { // 是否需要排序 @@ -1360,3 +1361,45 @@ export function getTagColor (color) { return `color: ${color};border-color: ${color};background-color: ${backgroundColor};` } } + +/** + * 字段高亮 + * 用法: 搜索关键字高亮 + * @type {{updated(*, *): (*|undefined)}} + */ +export const myHighLight = { + updated (el, binding) { + if (el && binding.value) { + const { value } = binding + if (value && value.length > 0) { + const text = JSON.parse(JSON.stringify(el.innerHTML)) + value.forEach(item => { + const regex = new RegExp(item.value, 'gi') + // 一旦高亮后,就不再添加class,不然会一直嵌套span + if (el.getElementsByClassName('highlight__text').length === 0) { + const newText = text.replace(regex, match => `${match}`) + if (item.type === columnType.fullText) { + // el.innerHTML.toLowerCase().indexOf(item.value.toLowerCase()) > -1 + } + if (newText && newText !== '-') { + el.innerHTML = newText + } else { + return newText + } + } + }) + // const myValue = ['China', 'qq'] + // const regex = new RegExp(myValue.join('|'), 'gi') + // // 一旦高亮后,就不再添加class,不然会一直嵌套span + // if (el.getElementsByClassName('highlight__text').length === 0) { + // const newText = text.replace(regex, match => `${match}`) + // if (newText && newText !== '-') { + // el.innerHTML = newText + // } else { + // return newText + // } + // } + } + } + } +} diff --git a/src/views/entityExplorer/EntityExplorer.vue b/src/views/entityExplorer/EntityExplorer.vue index eccd4117..89a0b449 100644 --- a/src/views/entityExplorer/EntityExplorer.vue +++ b/src/views/entityExplorer/EntityExplorer.vue @@ -46,6 +46,7 @@ style="width: 100%;" :list-data="listData" :list-mode="listMode" + :keywordList="keywordList" :pageObj="pageObj" :time-filter="timeFilter" @pageSize="pageSize" @@ -174,6 +175,7 @@ import Parser from '@/components/advancedSearch/meta/parser' import { handleErrorTip } from '@/components/advancedSearch/meta/error' import { columnList } from '@/utils/static-data' import { useRoute } from 'vue-router' +import { columnType } from '@/components/advancedSearch/meta/meta' export default { name: 'entity-explorer', @@ -289,7 +291,8 @@ export default { ipCount: 0, appCount: 0 }, - loadingCount: false // 实体基数统计的loading + loadingCount: false, // 实体基数统计的loading + keywordList: [] } }, methods: { @@ -361,6 +364,7 @@ export default { this.q = '' this.metaList = [] } + this.getKeyword(param.keywordList) // 参数q,避免切换页码时,地址栏参数q为空 let urlQ = '' @@ -581,7 +585,7 @@ export default { this.summaryCount = { total: 0, domainCount: 0, ipCount: 0, appCount: 0 } } }).catch(e => { - console.log(e) + console.error(e) this.summaryCount = { total: 0, domainCount: 0, ipCount: 0, appCount: 0 } }).finally(() => { this.loadingCount = false @@ -675,11 +679,20 @@ export default { } } const parser = new Parser(columnList) + const metaList = parser.parseStr(_.cloneDeep(str)).metaList + const keywordList = [] + metaList.forEach(item => { + if (item.column && item.column.type === columnType.fullText) { + keywordList.push({ type: item.column.type, value: item.column.label }) + } else if (item.column && item.column.type === columnType.string) { + keywordList.push({ type: item.column.type, value: item.value.value }) + } + }) const keyInfo = parser.comparedEntityKey(parser.handleEntityTypeByStr(str)) if (keyInfo.isKey) { const errorList = parser.validateStr(keyInfo.key) if (_.isEmpty(errorList)) { - this.search({ ...parser.parseStr(keyInfo.key), str: str }) + this.search({ ...parser.parseStr(keyInfo.key), str: str, keywordList: keywordList }) } else { this.$message.error(handleErrorTip(errorList[0])) } @@ -727,6 +740,31 @@ export default { }).catch((e) => { }).finally(() => { }) + }, + getKeyword (list) { + if (list) { + const metaList = JSON.parse(JSON.stringify(list)) + const keyList = [] + metaList.forEach(item => { + if (item.value) { + keyList.push({ type: item.type, value: this.getKeyValue(item.value) }) + } + }) + this.keywordList = keyList + } + }, + getKeyValue (str) { + if (str[0] === "'" && str[str.length - 1] === "'") { + str = str.substring(1, str.length) + str = str.substring(0, str.length - 1) + } + if (str[0] === '%') { + str = str.substring(1, str.length) + } + if (str[str.length - 1] === '%') { + str = str.substring(0, str.length - 1) + } + return str } }, mounted () { diff --git a/src/views/entityExplorer/entityList/EntityList.vue b/src/views/entityExplorer/entityList/EntityList.vue index 20dc36ea..87f4222d 100644 --- a/src/views/entityExplorer/entityList/EntityList.vue +++ b/src/views/entityExplorer/entityList/EntityList.vue @@ -11,6 +11,7 @@ v-for="(data, index) in listData" :entity="data" :listMode="listMode" + :keywordList="keywordList" :timeFilter="timeFilter" :key="index" :ref="`entityRow${index}`" @@ -65,7 +66,8 @@ export default { pageObj: Object, loading: Boolean, timeFilter: Object, - listMode: String + listMode: String, + keywordList: Array }, components: { 'entity-card': Card, diff --git a/src/views/entityExplorer/entityList/Row.vue b/src/views/entityExplorer/entityList/Row.vue index b4e24c78..10af8e57 100644 --- a/src/views/entityExplorer/entityList/Row.vue +++ b/src/views/entityExplorer/entityList/Row.vue @@ -11,7 +11,7 @@
- {{ entityData.entityValue || 'Unknown' }} + {{ entityData.entityValue || 'Unknown' }} {{ $t('overall.country') }} :   - {{ $_.get(entityData, 'location.country', '-') || '-' }} + {{ $_.get(entityData, 'location.country', '-') || '-' }}
{{ $t('overall.city') }} :   - {{ entityData.location ? ipLocationRegion(entityData.location) : '-' }} + {{ entityData.location ? ipLocationRegion(entityData.location) : '-' }}
{{ $t('entities.asn') }} :   - {{ $_.get(entityData, 'asn.asn', '-') || '-' }} + {{ $_.get(entityData, 'asn.asn', '-') || '-' }}