fix: 简化部分代码,添加注释,添加是否需要高亮指令noHighlight
This commit is contained in:
@@ -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'],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,26 +6,30 @@
|
||||
ref="textSearch"
|
||||
></textarea>
|
||||
<div class="search__suffixes search__suffixes--text-mode" :class="showList ? '' : 'entity-explorer-home'" style="padding-left: 1px">
|
||||
<!--切换text、tag模式图标-->
|
||||
<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))
|
||||
// 注:参数str,1.是用户搜索框的内容在补全模糊搜索后的内容;2.部分参数是用户主观可见,但格式不符合接口原则的,如status='Active',接口需要status=0
|
||||
this.$emit('search', { ...parser.parseStr(enumKey), str: parser.handleEntityTypeByStr(str), keywordList: keywordList })
|
||||
} else {
|
||||
this.$message.error(handleErrorTip(errorList[0]))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
// 使用单引号包裹
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user