fix: 简化部分代码,添加注释,添加是否需要高亮指令noHighlight

This commit is contained in:
刘洪洪
2023-12-14 16:20:33 +08:00
parent a3c8baea5c
commit d2cb42687e
8 changed files with 62 additions and 44 deletions

View File

@@ -475,7 +475,7 @@ span.CodeMirror-selectedtext { background: none; }
z-index: 2;
.hint__block-filter {
width: 326px;
width: 319px;
background: #fff;
border-right: 1px solid #DEDEDE;
padding: 12px;
@@ -483,7 +483,7 @@ span.CodeMirror-selectedtext { background: none; }
}
.hint__block-helper {
width: calc(100% - 326px);
width: calc(100% - 319px);
background: #fff;
z-index: 2;
}

View File

@@ -48,6 +48,11 @@ export default {
showCloseIcon: false
}
},
provide () {
return {
myHighLight: !this.noHighlight
}
},
props: {
// 默认模式tag | text
defaultMode: String,
@@ -69,6 +74,10 @@ export default {
showHint: {
type: Boolean,
default: false
},
noHighlight: {
type: Boolean,
default: false
}
},
emits: ['search'],

View File

@@ -147,7 +147,7 @@
popper-class="my-popper-class"
placement="top"
trigger="hover"
:content="$t('entity.switchToBasicSearch')"
:content="$t('overall.switchToText')"
>
<template #reference>
<i class="cn-icon cn-icon-search-normal" @click="changeMode"></i>
@@ -190,6 +190,7 @@ export default {
}
},
emits: ['changeMode', 'search'],
inject: ['myHighLight'],
methods: {
// 新增条件
addCondition (meta) {
@@ -599,14 +600,7 @@ 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 })
}
})
const keywordList = this.myHighLight ? parser.getKeywordList(this.metaList) : [] // 搜索高亮的关键字
if (_.isEmpty(errorList)) {
const strObj = parser.handleMetaListToStr(this.metaList)
const str = strObj.str ? strObj.str : strObj

View File

@@ -6,26 +6,30 @@
ref="textSearch"
></textarea>
<div class="search__suffixes search__suffixes--text-mode" :class="showList ? '' : 'entity-explorer-home'" style="padding-left: 1px">
<!--切换texttag模式图标-->
<span class="search__suffix">
<el-popover
popper-class="my-popper-class"
placement="top"
trigger="hover"
:content="$t('entity.switchToAdvancedSearch')"
:content="$t('overall.switchToTag')"
>
<template #reference>
<i class="cn-icon cn-icon-filter" @click="changeMode"></i>
</template>
</el-popover>
</span>
<!--删除图标-->
<span v-show="isCloseIcon" class="search__suffix search__suffix-close" @click="cleanParams">
<i class="el-icon-error"></i>
</span>
<!--搜索图标-->
<span class="search__suffix" @click.stop="search">
<i class="el-icon-search"></i>
</span>
</div>
<!--showHint弹窗部分-->
<el-popover
placement="bottom"
width="100%"
@@ -82,6 +86,7 @@ export default {
}
},
emits: ['changeMode', 'search'],
inject: ['myHighLight'],
created () {
if (this.isShowHint) {
this._initComponent()
@@ -167,23 +172,16 @@ export default {
const str = this.codeMirror.getValue().trim()
if (str) {
const parser = new Parser(this.columnList)
const keyInfo = parser.comparedEntityKey(parser.handleEntityTypeByStr(str))
const keyInfo = parser.comparedEntityKey(parser.handleEntityTypeByStr(str)) // 校验输入str字段是schema内的字段并将语句进行规范
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 keywordList = this.myHighLight ? parser.getKeywordList(metaList) : [] // 搜索高亮所需的关键字
if (keyInfo.isKey) {
// 检查是否包含枚举字段,包含的话进行替换
const enumKey = parser.conversionEnum(keyInfo.key)
const errorList = parser.validateStr(enumKey)
const enumKey = parser.conversionEnum(keyInfo.key) // 检查是否包含枚举字段,包含的话进行替换
const errorList = parser.validateStr(enumKey) // 检查语句是否有错误
if (_.isEmpty(errorList)) {
// 补全模糊搜索
toRaw(this.codeMirror).setValue(parser.handleEntityTypeByStr(str))
// 注参数str1.是用户搜索框的内容在补全模糊搜索后的内容2.部分参数是用户主观可见但格式不符合接口原则的如status='Active'接口需要status=0
this.$emit('search', { ...parser.parseStr(enumKey), str: parser.handleEntityTypeByStr(str), keywordList: keywordList })
} else {
this.$message.error(handleErrorTip(errorList[0]))

View File

@@ -14,6 +14,13 @@ const strReg = {
const operatorList = ['=', ' in ', ' IN ', ' like ', ' LIKE ', 'HAS(', 'has(']
const enumList = ['status', 'eventType', 'severity']
// ipv4校验
const regexIPv4 = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
// ipv6校验
const regexIPv6 = /^(?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,7}:|(?:[0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,5}(?::[0-9A-Fa-f]{1,4}){1,2}|(?:[0-9A-Fa-f]{1,4}:){1,4}(?::[0-9A-Fa-f]{1,4}){1,3}|(?:[0-9A-Fa-f]{1,4}:){1,3}(?::[0-9A-Fa-f]{1,4}){1,4}|(?:[0-9A-Fa-f]{1,4}:){1,2}(?::[0-9A-Fa-f]{1,4}){1,5}|[0-9A-Fa-f]{1,4}:(?:(?::[0-9A-Fa-f]{1,4}){1,6})|:(?:(?::[0-9A-Fa-f]{1,4}){1,7}|:)|fe80:(?::[0-9A-Fa-f]{0,4}){0,4}%\w+|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])|(?:[0-9A-Fa-f]{1,4}:){1,4}:192\.88\.99\.(\d{1,3})|(?:[0-9A-Fa-f]{1,4}:){1,4}:192\.0\.2\.(\d{1,3})|(?:[0-9A-Fa-f]{1,4}:){1,4}:(?:[0-9A-Fa-f]{1,4}:){0,1}192\.0\.0\.(\d{1,3})|ff00:(?::[0-9A-Fa-f]{0,4}){0,4}|(?:[0-9A-Fa-f]{1,4}:){1,4}:255\.255\.255\.255)$/
// domain校验
const regexDomain = /^(?=^.{3,255}$)(http(s)?:\/\/)?(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+\.\w+)*$/
export default class Parser {
constructor (columnList) {
this.columnList = columnList
@@ -861,7 +868,7 @@ export default class Parser {
item.value.label = isWrapped ? `'${this.delSingleQuote(label)}'` : `${this.delSingleQuote(label)}`
item.value.label1 = isWrapped ? `'%${this.delSingleQuote(label)}%'` : `%${this.delSingleQuote(label)}%`
}
item.column.type = 'string'
item.column.type = columnType.string
}
})
// 长度为1时即模糊搜索例如搜索框值为1.1.1.1则直接返回1.1.1.1
@@ -1274,12 +1281,6 @@ export default class Parser {
if (str[0] === '%' && str[str.length - 1] !== '%') {
str = str.substring(1, str.length)
}
// ipv4校验
const regexIPv4 = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
// ipv6校验
const regexIPv6 = /^(?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,7}:|(?:[0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,5}(?::[0-9A-Fa-f]{1,4}){1,2}|(?:[0-9A-Fa-f]{1,4}:){1,4}(?::[0-9A-Fa-f]{1,4}){1,3}|(?:[0-9A-Fa-f]{1,4}:){1,3}(?::[0-9A-Fa-f]{1,4}){1,4}|(?:[0-9A-Fa-f]{1,4}:){1,2}(?::[0-9A-Fa-f]{1,4}){1,5}|[0-9A-Fa-f]{1,4}:(?:(?::[0-9A-Fa-f]{1,4}){1,6})|:(?:(?::[0-9A-Fa-f]{1,4}){1,7}|:)|fe80:(?::[0-9A-Fa-f]{0,4}){0,4}%\w+|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])|(?:[0-9A-Fa-f]{1,4}:){1,4}:192\.88\.99\.(\d{1,3})|(?:[0-9A-Fa-f]{1,4}:){1,4}:192\.0\.2\.(\d{1,3})|(?:[0-9A-Fa-f]{1,4}:){1,4}:(?:[0-9A-Fa-f]{1,4}:){0,1}192\.0\.0\.(\d{1,3})|ff00:(?::[0-9A-Fa-f]{0,4}){0,4}|(?:[0-9A-Fa-f]{1,4}:){1,4}:255\.255\.255\.255)$/
// domain校验
const reg = /^(?=^.{3,255}$)(http(s)?:\/\/)?(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+\.\w+)*$/
if (regexIPv4.test(str) || regexIPv6.test(str)) {
const obj = this.columnList.find(t => t.label.toLowerCase() === 'ip')
@@ -1291,7 +1292,7 @@ export default class Parser {
}
return str
}
} else if (reg.test(str)) {
} else if (regexDomain.test(str)) {
// 只写作domain即可schema字段更改几次避免后续再更改直接拿this.columnList的label进行替换
const obj = this.columnList.find(t => t.label.toLowerCase() === 'domain')
if (obj) {
@@ -1315,18 +1316,14 @@ export default class Parser {
}
}
/**
* 判断传过来值的实体类型仅限于ip、domain、app
*/
getEntityTypeByValue (str) {
if (str[0] === "'" && str[str.length - 1] === "'") {
str = str.substring(1, str.length)
str = str.substring(0, str.length - 1)
}
// ipv4校验
const regexIPv4 = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
// ipv6校验
const regexIPv6 = /^(?:(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,7}:|(?:[0-9A-Fa-f]{1,4}:){1,6}:[0-9A-Fa-f]{1,4}|(?:[0-9A-Fa-f]{1,4}:){1,5}(?::[0-9A-Fa-f]{1,4}){1,2}|(?:[0-9A-Fa-f]{1,4}:){1,4}(?::[0-9A-Fa-f]{1,4}){1,3}|(?:[0-9A-Fa-f]{1,4}:){1,3}(?::[0-9A-Fa-f]{1,4}){1,4}|(?:[0-9A-Fa-f]{1,4}:){1,2}(?::[0-9A-Fa-f]{1,4}){1,5}|[0-9A-Fa-f]{1,4}:(?:(?::[0-9A-Fa-f]{1,4}){1,6})|:(?:(?::[0-9A-Fa-f]{1,4}){1,7}|:)|fe80:(?::[0-9A-Fa-f]{0,4}){0,4}%\w+|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])\.(?:(?:2[0-4]|1\d|[1-9])?\d|25[0-5])|(?:[0-9A-Fa-f]{1,4}:){1,4}:192\.88\.99\.(\d{1,3})|(?:[0-9A-Fa-f]{1,4}:){1,4}:192\.0\.2\.(\d{1,3})|(?:[0-9A-Fa-f]{1,4}:){1,4}:(?:[0-9A-Fa-f]{1,4}:){0,1}192\.0\.0\.(\d{1,3})|ff00:(?::[0-9A-Fa-f]{0,4}){0,4}|(?:[0-9A-Fa-f]{1,4}:){1,4}:255\.255\.255\.255)$/
// domain校验
const reg = /^(?=^.{3,255}$)(http(s)?:\/\/)?(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+\.\w+)*$/
if (regexIPv4.test(str) || regexIPv6.test(str)) {
const obj = this.columnList.find(t => t.label.toLowerCase() === 'ip')
if (obj) {
@@ -1334,7 +1331,7 @@ export default class Parser {
} else {
return str
}
} else if (reg.test(str)) {
} else if (regexDomain.test(str)) {
const obj = this.columnList.find(t => t.label.toLowerCase() === 'domain')
if (obj) {
return obj.label
@@ -1518,6 +1515,26 @@ export default class Parser {
return str
}
}
/**
* 获取关键字列表,即高亮字段
* @param metaList
* @returns {*[]}
*/
getKeywordList (metaList) {
const keywordList = []
if (metaList && metaList.length > 0) {
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.column.label })
}
})
}
return keywordList
}
}
// 使用单引号包裹

View File

@@ -1,6 +1,6 @@
<template>
<div class="HintInfo">
<ul style="padding-left: 0;margin: -10px 0 0 0;">
<ul style="padding-left: 0;margin: -10px 0 0 0;min-width: calc(100% - 12px)">
<template v-for="(item,index) in hintList" :key="index">
<li :ref="'hint_'+index" class="relative-item CodeMirror-hint"
@click="handleSelect(item,index,hintList)"

View File

@@ -13,7 +13,7 @@ export default {
<p class='show-hint-tips__p'>Strings containing spaces must be enclosed in single quotes ('). Such as:</p>
<code>ip=192.168.10.53</code>
<code>ip.country='United States'</code>
<p class='show-hint-tips__p'>Keyword - Keywords are specific words in the SQL. You can specify the AND and OR to create more complex query conditions. Currently only support AND.</p>
<p class='show-hint-tips__p'>Keyword - Keywords are specific words in the query. You can specify the AND and OR to create more complex query conditions. Currently only support AND.</p>
<p class='show-hint-tips__p'>There are two input modes, which can be switched by clicking the button on the right side of the input box.</p>
<div class='default-tips-title'> 1. Text Mode</div>
@@ -38,7 +38,7 @@ export default {
<p class='show-hint-tips__p'>包含空格的字符串必须用单引号(')括住例如</p>
<code>ip=192.168.10.53</code>
<code>ip.country='United States'</code>
<p class='show-hint-tips__p'>关键字 - 关键字是 SQL 中的特定单词您可以指定 AND OR 来创建更复杂的查询条件暂时只支持AND</p>
<p class='show-hint-tips__p'>关键字 - 关键字是查询中的特定单词您可以指定 AND OR 来创建更复杂的查询条件暂时只支持AND</p>
<p class='show-hint-tips__p'>有两种输入模式通过点击输入框右侧的按钮进行切换</p>
<div class='default-tips-title'> 1. 文本模式</div>

View File

@@ -78,7 +78,7 @@ export class Dataset {
// text: item.name,
// displayText: `${item.label}(${item.name})`,
text: item.label,
displayText: `${item.name}(${item.label})`,
displayText: `${item.label}`,
className: 'filter-item el-dropdown-menu__item relative-item'
}
})