CN-1265 fix: 修复实体搜索时的一些问题
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
<!-- 删除按钮 -->
|
||||
<div class="condition__delete" @click="removeCondition(index)"><i class="el-icon-error"></i></div>
|
||||
<!-- 字段选择 -->
|
||||
<div class="condition__column">
|
||||
<div v-if="meta.column.show" class="condition__column">
|
||||
<div v-show="meta.column.isEditing">
|
||||
<el-select
|
||||
allow-create
|
||||
@@ -29,12 +29,14 @@
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<span v-if="!meta.column.isEditing && meta.operator.value !== 'has'" @click="columnClick(meta)">{{meta.column.label}}</span>
|
||||
<span v-if="!meta.column.isEditing && meta.operator.value !== 'has'" @click="columnClick(meta)">
|
||||
<span v-if="meta.column.show">{{meta.column.label}}</span>
|
||||
</span>
|
||||
<!--操作符是has时,has需前置-->
|
||||
<span v-else class="condition__operator">{{ meta.operator.value }}</span>
|
||||
<span v-if="!meta.column.isEditing && meta.operator.value === 'has'" class="condition__operator">{{ meta.operator.value }}</span>
|
||||
</div>
|
||||
<!-- 已选操作符显示 -->
|
||||
<div class="condition__operator" @click="operatorClick(meta)" v-if="meta.operator.show && meta.operator.value !== 'has'">{{meta.operator.value}}</div>
|
||||
<div class="condition__operator" @click="operatorClick(meta)" v-if="meta.operator.show && meta.operator.value !== 'has'">{{meta.operator.value}}00</div>
|
||||
<div v-if="meta.operator.value === 'has'" class="condition__operator" style="color: #000C18">({{meta.column.label}},</div>
|
||||
<!-- 值 -->
|
||||
<div class="condition__value">
|
||||
@@ -48,7 +50,9 @@
|
||||
@focus="valueFocus(meta)"
|
||||
@keyup.enter="valueBlur(meta)"></el-input>
|
||||
</div>
|
||||
<span v-else @click="valueClick(meta)">{{meta.value.label}}</span>
|
||||
<div v-if="!meta.value.isEditing && meta.value.label" @click="valueClick(meta)" style="padding-right: 6px;">
|
||||
{{ changeLabel(meta.value.label) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="condition__value" style="margin-left: -5px;" v-if="meta.operator.show && meta.operator.value === 'has'">)</div>
|
||||
|
||||
@@ -114,7 +118,7 @@ import _ from 'lodash'
|
||||
import { handleErrorTip } from '@/components/advancedSearch/meta/error'
|
||||
import Parser, { handleMetaListToStr, stringInQuot } from '@/components/advancedSearch/meta/parser'
|
||||
import {
|
||||
comparedEntityKey,
|
||||
getEntityTypeByValue,
|
||||
handleEntityTypeByStr,
|
||||
overwriteUrl,
|
||||
urlParamsHandler
|
||||
@@ -188,7 +192,7 @@ export default {
|
||||
const parser = new Parser(this.columnList)
|
||||
const errorList = parser.validateMeta(this.metaList)
|
||||
if (_.isEmpty(errorList)) {
|
||||
this.reloadUrl({ q: parser.parseMeta(this.metaList).q })
|
||||
this.reloadUrl({ q: encodeURI(parser.parseMeta(this.metaList).q) })
|
||||
}
|
||||
} else {
|
||||
const routeQuery = this.$route.query
|
||||
@@ -244,6 +248,26 @@ export default {
|
||||
// 根据所选label在columnList中匹配label来确定操作符,一般为=,IN,tags操作符为has
|
||||
const obj = this.columnList.find(t => t.label === meta.column.label)
|
||||
this.operatorList = obj ? obj.doc.constraints.operator_functions.split(',') : ['=', 'IN']
|
||||
if (meta.column && meta.column.type === 'fullText') {
|
||||
meta.operator.value = '='
|
||||
meta.column.show = false
|
||||
meta.operator.show = false
|
||||
const label = JSON.parse(JSON.stringify(meta.column.label))
|
||||
meta.column.label = getEntityTypeByValue(meta.column.label)
|
||||
meta.value.value = label
|
||||
meta.value.label = label
|
||||
|
||||
if (meta.column.label === 'domain') {
|
||||
meta.operator.value = 'like'
|
||||
meta.value.value = `%${this.delSingleQuote(label)}`
|
||||
meta.value.label = `${this.delSingleQuote(label)}`
|
||||
} else if (meta.column.label === 'app') {
|
||||
meta.operator.value = 'like'
|
||||
meta.value.value = `%${this.delSingleQuote(label)}%`
|
||||
meta.value.label = `${this.delSingleQuote(label)}`
|
||||
}
|
||||
meta.column.type = 'string'
|
||||
}
|
||||
}, 200)
|
||||
},
|
||||
connectionClick (meta) {
|
||||
@@ -321,6 +345,12 @@ export default {
|
||||
if (str.indexOf("'") > -1 && str.indexOf("''") === -1) {
|
||||
str = str.replace(/'/g, "''")
|
||||
}
|
||||
if (str[0] === '%') {
|
||||
str = str.substring(1, str.length)
|
||||
}
|
||||
if (str[str.length - 1] === '%') {
|
||||
str = str.substring(0, str.length - 1)
|
||||
}
|
||||
meta.value.value = str
|
||||
}
|
||||
meta.value.label = meta.value.value // label是显示,value是实际值
|
||||
@@ -373,7 +403,25 @@ export default {
|
||||
if (str.indexOf("'") > -1 && str.indexOf("''") === -1) {
|
||||
str = str.replace(/'/g, "''")
|
||||
}
|
||||
// meta.value.value = str
|
||||
|
||||
// domain和app选择like时,添加%
|
||||
if (meta.operator.value.toLowerCase() === 'like') {
|
||||
if (meta.column.label.toLowerCase() === 'domain') {
|
||||
if (str[0] === '%') {
|
||||
str = str.substring(1, str.length)
|
||||
}
|
||||
str = `%${str}`
|
||||
}
|
||||
|
||||
if (meta.column.label.toLowerCase() === 'app') {
|
||||
if (str[0] === '%' && str[str.length - 1] === '%') {
|
||||
str = str.substring(1, str.length)
|
||||
str = str.substring(0, str.length - 1)
|
||||
}
|
||||
str = `%${str}%`
|
||||
}
|
||||
}
|
||||
|
||||
if (!isWrapped) {
|
||||
meta.value.value = `'${str}'`
|
||||
}
|
||||
@@ -405,9 +453,9 @@ export default {
|
||||
const parser = new Parser(this.columnList)
|
||||
const errorList = parser.validateMeta(this.metaList)
|
||||
if (_.isEmpty(errorList)) {
|
||||
const str = handleMetaListToStr(this.metaList)
|
||||
const key = handleEntityTypeByStr(str)
|
||||
this.$emit('search', { ...parser.parseStr(key), str: str })
|
||||
const strObj = handleMetaListToStr(this.metaList)
|
||||
const key = handleEntityTypeByStr(strObj.str)
|
||||
this.$emit('search', { ...parser.parseStr(key), str: strObj.str2 })
|
||||
} else {
|
||||
this.$message.error(handleErrorTip(errorList[0]))
|
||||
}
|
||||
@@ -420,7 +468,7 @@ export default {
|
||||
const errorList = parser.validateMeta(this.metaList)
|
||||
if (_.isEmpty(errorList)) {
|
||||
this.reloadUrl({ mode: 'text' })
|
||||
this.$emit('changeMode', 'text', parser.parseMeta(this.metaList))
|
||||
this.$emit('changeMode', 'text', handleMetaListToStr(this.metaList).str2)
|
||||
} else {
|
||||
this.reloadUrl({ mode: 'text' })
|
||||
this.$emit('changeMode', 'text', { metaList: [], str: '' })
|
||||
@@ -515,6 +563,34 @@ export default {
|
||||
const routeQuery = this.$route.query
|
||||
delete routeQuery.q
|
||||
this.reloadUrl(routeQuery, 'cleanOldParams')
|
||||
},
|
||||
isSingleQuoteWrapping (str) {
|
||||
const regex = /^'[^']*'$/
|
||||
return regex.test(str)
|
||||
},
|
||||
delSingleQuote (str) {
|
||||
if (str[0] === "'" && str[str.length - 1] === "'") {
|
||||
str = str.substring(1, str.length)
|
||||
str = str.substring(0, str.length - 1)
|
||||
}
|
||||
return str
|
||||
},
|
||||
changeLabel (label) {
|
||||
// 用户输入'baidu',实际搜索的值为app like '%baidu%'
|
||||
// 此时展示的值为'%baidu%',为展示用户输入的值,则将添加的%删除
|
||||
let str = JSON.parse(JSON.stringify(label))
|
||||
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 () {
|
||||
@@ -522,8 +598,10 @@ export default {
|
||||
// 如果地址栏包含参数q,则匹配出metaList到搜索栏回显使用
|
||||
let { q } = this.$route.query
|
||||
if (q) {
|
||||
q = comparedEntityKey(handleEntityTypeByStr(q)).key
|
||||
const parser = new Parser(this.columnList)
|
||||
if (q.indexOf('%20') > -1) {
|
||||
q = decodeURI(q)
|
||||
}
|
||||
this.metaList = parser.parseStr(q).metaList
|
||||
}
|
||||
|
||||
@@ -538,6 +616,29 @@ export default {
|
||||
handler (n) {
|
||||
if (!_.isEmpty(n)) {
|
||||
this.metaList = n
|
||||
// 从text模式的模糊搜索转换过来时,需要添加属性
|
||||
this.metaList.forEach(item => {
|
||||
if (item.column && item.column.type === 'fullText') {
|
||||
item.operator.value = '='
|
||||
item.column.show = false
|
||||
item.operator.show = false
|
||||
const label = JSON.parse(JSON.stringify(item.column.label))
|
||||
item.column.label = getEntityTypeByValue(item.column.label)
|
||||
item.value.value = label
|
||||
item.value.label = label
|
||||
|
||||
if (item.column.label === 'domain') {
|
||||
item.operator.value = 'like'
|
||||
item.value.value = `%${this.delSingleQuote(label)}`
|
||||
item.value.label = `%${this.delSingleQuote(label)}`
|
||||
} else if (item.column.label === 'app') {
|
||||
item.operator.value = 'like'
|
||||
item.value.value = `%${this.delSingleQuote(label)}%`
|
||||
item.value.label = `%${this.delSingleQuote(label)}%`
|
||||
}
|
||||
item.column.type = 'string'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,9 +115,8 @@ export default {
|
||||
this.codeMirror.focus()
|
||||
},
|
||||
changeMode () {
|
||||
let str = this.codeMirror.getValue().trim()
|
||||
const str = this.codeMirror.getValue().trim()
|
||||
if (str) {
|
||||
str = comparedEntityKey(handleEntityTypeByStr(str)).key
|
||||
const parser = new Parser(this.columnList)
|
||||
const errorList = parser.validateStr(str)
|
||||
if (_.isEmpty(errorList)) {
|
||||
@@ -221,6 +220,9 @@ export default {
|
||||
let { q } = this.$route.query
|
||||
this.initCodeMirror()
|
||||
if (q) {
|
||||
if (q.indexOf('%20') > -1) {
|
||||
q = decodeURI(q)
|
||||
}
|
||||
// 为避免地址栏任意输入导致全查询的q带QUERY,解析时不识别导致的语法错误
|
||||
// 如地址栏输入116.178.222.171,此时的q很长,刷新界面时需要把q里的116.178.222.171拿出来进行搜索
|
||||
if (q.indexOf('QUERY') > -1) {
|
||||
|
||||
@@ -46,7 +46,8 @@ export default class Meta {
|
||||
name: '',
|
||||
type: '', // fullText | string | long ...
|
||||
label: '',
|
||||
isEditing: false
|
||||
isEditing: false,
|
||||
show: true
|
||||
}
|
||||
this.operator = {
|
||||
value: '',
|
||||
|
||||
@@ -3,7 +3,7 @@ import Token, { types } from './token'
|
||||
import ParserError, { errorDesc, errorTypes } from '@/components/advancedSearch/meta/error'
|
||||
import _ from 'lodash'
|
||||
import { columnList } from '@/utils/static-data'
|
||||
import { getEntityTypeByValue } from '@/utils/tools'
|
||||
import { comparedEntityKey, getEntityTypeByValue, handleEntityTypeByStr } from '@/utils/tools'
|
||||
|
||||
const strReg = {
|
||||
all: /^[\da-zA-Z\s.'><!=-_(),%]$/,
|
||||
@@ -82,7 +82,7 @@ export default class Parser {
|
||||
str += `${meta.value.toUpperCase()} `
|
||||
} else if (meta.meta === condition) {
|
||||
if (meta.column.type === columnType.fullText) {
|
||||
str += `'${meta.column.label}' `
|
||||
str += isSingleQuoteWrapping(meta.column.label) ? `${meta.column.label} ` : `'${meta.column.label}' `
|
||||
} else if (meta.column.type === columnType.array) {
|
||||
str += `${meta.column.label} ${meta.operator.value} (`
|
||||
meta.value.value.forEach((s, j) => {
|
||||
@@ -94,30 +94,35 @@ export default class Parser {
|
||||
str = str.substring(0, str.length - 1)
|
||||
str += ') '
|
||||
} else if (meta.column.type === columnType.string) {
|
||||
if (meta.operator.value.toLowerCase().indexOf('like') > -1 || meta.operator.value.toLowerCase().indexOf('in') > -1) {
|
||||
const isWrapped = isSingleQuoteWrapping(meta.value.value)
|
||||
if (isWrapped || meta.value.value.indexOf("''") > -1) {
|
||||
// 如xi''an这种情况,不需要再添加单引号
|
||||
str += `${meta.column.label} ${meta.operator.value} ${meta.value.value} `
|
||||
} else {
|
||||
str += `${meta.column.label} ${meta.operator.value} '${meta.value.value}' `
|
||||
}
|
||||
} else if (meta.operator.value.toLowerCase().indexOf('has') > -1) {
|
||||
const isWrapped = isSingleQuoteWrapping(meta.value.value)
|
||||
// 如果值被单引号包裹,则不需要再添加单引号包裹,true为单引号包裹
|
||||
if (isWrapped) {
|
||||
// 操作符为has时,has函数需要提前,格式为has(label,value)
|
||||
str += `${meta.operator.value}(${meta.column.label},${meta.value.value}) `
|
||||
} else {
|
||||
str += `${meta.operator.value}(${meta.column.label},'${meta.value.value}') `
|
||||
}
|
||||
// 此处show为false,即tag模式下模糊搜索的值,str不进行转换,q会进行转换,str用于回显
|
||||
if (!meta.column.show) {
|
||||
str += isSingleQuoteWrapping(meta.value.value) ? `${meta.value.value} ` : `'${meta.value.value}' `
|
||||
} else {
|
||||
const isWrapped = isSingleQuoteWrapping(meta.value.value)
|
||||
// 如果值被单引号包裹,则不需要再添加单引号包裹,true为单引号包裹
|
||||
if (isWrapped || meta.value.value.indexOf("''") > -1) {
|
||||
str += `${meta.column.label}${meta.operator.value}${meta.value.value} `
|
||||
if (meta.operator.value.toLowerCase().indexOf('like') > -1 || meta.operator.value.toLowerCase().indexOf('in') > -1) {
|
||||
const isWrapped = isSingleQuoteWrapping(meta.value.value)
|
||||
if (isWrapped || meta.value.value.indexOf("''") > -1) {
|
||||
// 如xi''an这种情况,不需要再添加单引号
|
||||
str += `${meta.column.label} ${meta.operator.value} ${meta.value.value} `
|
||||
} else {
|
||||
str += `${meta.column.label} ${meta.operator.value} '${meta.value.value}' `
|
||||
}
|
||||
} else if (meta.operator.value.toLowerCase().indexOf('has') > -1) {
|
||||
const isWrapped = isSingleQuoteWrapping(meta.value.value)
|
||||
// 如果值被单引号包裹,则不需要再添加单引号包裹,true为单引号包裹
|
||||
if (isWrapped) {
|
||||
// 操作符为has时,has函数需要提前,格式为has(label,value)
|
||||
str += `${meta.operator.value}(${meta.column.label},${meta.value.value}) `
|
||||
} else {
|
||||
str += `${meta.operator.value}(${meta.column.label},'${meta.value.value}') `
|
||||
}
|
||||
} else {
|
||||
str += `${meta.column.label}${meta.operator.value}'${meta.value.value}' `
|
||||
const isWrapped = isSingleQuoteWrapping(meta.value.value)
|
||||
// 如果值被单引号包裹,则不需要再添加单引号包裹,true为单引号包裹
|
||||
if (isWrapped || meta.value.value.indexOf("''") > -1) {
|
||||
str += `${meta.column.label}${meta.operator.value}${meta.value.value} `
|
||||
} else {
|
||||
str += `${meta.column.label}${meta.operator.value}'${meta.value.value}' `
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (meta.column.type === columnType.number) {
|
||||
@@ -146,11 +151,12 @@ export default class Parser {
|
||||
str += `${meta.value.toUpperCase()} `
|
||||
} else if (meta.meta === condition) {
|
||||
if (meta.column.type === columnType.fullText) {
|
||||
str += "QUERY('"
|
||||
this.columnList.forEach(column => {
|
||||
str += `${column.label}:${meta.column.label} `
|
||||
})
|
||||
str += "') "
|
||||
// str += "QUERY('"
|
||||
// this.columnList.forEach(column => {
|
||||
// str += `${column.label}:${meta.column.label} `
|
||||
// })
|
||||
// str += "') "
|
||||
str = comparedEntityKey(handleEntityTypeByStr(meta.column.label)).key
|
||||
} else if (meta.column.type === columnType.array) {
|
||||
str += `${meta.column.label} ${meta.operator.value} (`
|
||||
meta.value.value.forEach((s, j) => {
|
||||
@@ -617,7 +623,7 @@ export default class Parser {
|
||||
meta.column.type = columnType.string
|
||||
} else {
|
||||
meta.column.type = columnType.fullText
|
||||
meta.column.label = token.value
|
||||
meta.column.label = isSingleQuoteWrapping(token.value) ? token.value : `'${token.value}'`
|
||||
}
|
||||
} else {
|
||||
let isColumn = true
|
||||
@@ -836,10 +842,21 @@ export function handleMetaListToStr (metaList) {
|
||||
metaList.forEach(item => {
|
||||
if (item.column && item.column.type === 'fullText') {
|
||||
item.operator.value = '='
|
||||
item.operator.show = true
|
||||
item.value.value = item.column.label
|
||||
item.value.label = item.column.label
|
||||
item.operator.show = false
|
||||
item.column.show = false
|
||||
const label = JSON.parse(JSON.stringify(item.column.label))
|
||||
item.column.label = getEntityTypeByValue(item.column.label)
|
||||
item.value.value = label
|
||||
item.value.label = label
|
||||
if (item.column.label === 'domain') {
|
||||
item.operator.value = 'like'
|
||||
item.value.value = `%${delSingleQuote(label)}`
|
||||
item.value.label = `%${delSingleQuote(label)}`
|
||||
} else if (item.column.label === 'app') {
|
||||
item.operator.value = 'like'
|
||||
item.value.value = `%${delSingleQuote(label)}%`
|
||||
item.value.label = `%${delSingleQuote(label)}%`
|
||||
}
|
||||
item.column.type = 'string'
|
||||
}
|
||||
})
|
||||
@@ -896,54 +913,41 @@ export function handleMetaListToStr (metaList) {
|
||||
// 此为按语法搜索,将metaList转为字符串
|
||||
const newMetaList = []
|
||||
let hasStr = ''
|
||||
let fullTextStr = ''
|
||||
let fullTextStr2 = ''
|
||||
// 去除metaList的AND项
|
||||
metaList.forEach(item => {
|
||||
if (item.value !== 'AND') {
|
||||
if (item.column.label.toLowerCase() === 'tag') {
|
||||
hasStr += `${item.operator.value}(${item.column.label},${item.value.value}) AND `
|
||||
} else if (!item.column.show && item.operator.value.toLowerCase() === 'like') {
|
||||
fullTextStr += `${item.column.label} ${item.operator.value} ${item.value.value} AND `
|
||||
fullTextStr2 += `'${delPercent(delSingleQuote(item.value.value))}' AND `
|
||||
} else {
|
||||
newMetaList.push(item)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const newObj = combineLabel(newMetaList)
|
||||
const lastObj = {}
|
||||
for (const i in newObj) {
|
||||
if (newObj[i].indexOf('(') > -1) {
|
||||
// 原来为IN ()格式的直接保留
|
||||
lastObj[i] = `${i} IN ${newObj[i]}`
|
||||
} else if (newObj[i].indexOf(',') > -1) {
|
||||
// 格式为IP: '1.1.1.1,2.2.2.2'的,改成IP: "'1.1.1.1','2.2.2.2'",然后再()括号包裹
|
||||
let str = newObj[i]
|
||||
str = str.replace(/(\d+\.\d+\.\d+\.\d+),(\d+\.\d+\.\d+\.\d+)/g, "'$1','$2'")
|
||||
lastObj[i] = `${i} IN (${str})`
|
||||
} else if (i.toLowerCase() === 'tag') {
|
||||
// lastObj[i] = `${i} = '${newObj[i]}'`
|
||||
lastObj[i] = `has(${i},${newObj[i]})`
|
||||
} else {
|
||||
const isWrapped = isSingleQuoteWrapping(newObj[i])
|
||||
// 如果值被单引号包裹,则不需要再添加单引号包裹,true为单引号包裹
|
||||
if (isWrapped || newObj[i].indexOf("''") > -1) {
|
||||
// 操作符为has时,has函数需要提前,格式为has(label,value)
|
||||
lastObj[i] = `${i} = ${newObj[i]}`
|
||||
} else {
|
||||
lastObj[i] = `${i} = '${newObj[i]}'`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const newObj = combineLabel(newMetaList) // 合并相同的label
|
||||
const lastObj = mergeSameEntityType(newObj) // 合并相同的实体类型,用in包裹
|
||||
let str = ''
|
||||
|
||||
for (const i in lastObj) {
|
||||
str += lastObj[i] + ' AND '
|
||||
}
|
||||
if (hasStr !== '') {
|
||||
str = str + hasStr.slice(0, -5)
|
||||
} else {
|
||||
str = str.slice(0, -5)
|
||||
str = str + hasStr
|
||||
}
|
||||
let str2 = str
|
||||
if (fullTextStr !== '') {
|
||||
str = str + fullTextStr
|
||||
str2 = str2 + fullTextStr2
|
||||
}
|
||||
str = str.slice(0, -5)
|
||||
str2 = str2.slice(0, -5)
|
||||
|
||||
return str
|
||||
return { str: str, str2: str2 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -969,3 +973,62 @@ const isSingleQuoteWrapping = (str) => {
|
||||
const regex = /^'[^']*'$/
|
||||
return regex.test(str)
|
||||
}
|
||||
/**
|
||||
* 合并相同的实体类型,转为in包裹的数据
|
||||
* @param obj
|
||||
* @returns {{}}
|
||||
*/
|
||||
const mergeSameEntityType = (obj) => {
|
||||
const lastObj = {}
|
||||
if (obj) {
|
||||
for (const i in obj) {
|
||||
if (obj[i].indexOf('(') > -1) {
|
||||
// 原来为IN ()格式的直接保留
|
||||
lastObj[i] = `${i} IN ${obj[i]}`
|
||||
if (obj[i].indexOf('),') > -1) {
|
||||
// 此时为ip;"('1.1.1.1','2.2.2.2'), '3.3.3.3'",in后面还有同类型数据,也放到in里
|
||||
lastObj[i] = lastObj[i].replace('),', ',') + ')'
|
||||
}
|
||||
} else if (obj[i].indexOf(',') > -1) {
|
||||
// 格式为IP: '1.1.1.1,2.2.2.2'的,改成IP: "'1.1.1.1','2.2.2.2'",然后再()括号包裹
|
||||
let str = obj[i]
|
||||
str = str.replace(/(\d+\.\d+\.\d+\.\d+),(\d+\.\d+\.\d+\.\d+)/g, "'$1','$2'")
|
||||
lastObj[i] = `${i} IN (${str})`
|
||||
} else if (i.toLowerCase() === 'tag') {
|
||||
lastObj[i] = `has(${i},${obj[i]})`
|
||||
} else {
|
||||
const isWrapped = isSingleQuoteWrapping(obj[i])
|
||||
// 如果值被单引号包裹,则不需要再添加单引号包裹,true为单引号包裹
|
||||
if (isWrapped || obj[i].indexOf("''") > -1) {
|
||||
// 操作符为has时,has函数需要提前,格式为has(label,value)
|
||||
lastObj[i] = `${i} = ${obj[i]}`
|
||||
} else {
|
||||
lastObj[i] = `${i} = '${obj[i]}'`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lastObj
|
||||
}
|
||||
const delSingleQuote = (str) => {
|
||||
if (str) {
|
||||
if (str[0] === "'" && str[str.length - 1] === "'") {
|
||||
str = str.substring(1, str.length)
|
||||
str = str.substring(0, str.length - 1)
|
||||
}
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
const delPercent = (str) => {
|
||||
if (str) {
|
||||
if (str[0] === '%') {
|
||||
str = str.substring(1, str.length)
|
||||
}
|
||||
if (str[str.length - 1] === '%') {
|
||||
str = str.substring(0, str.length - 1)
|
||||
}
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
@@ -1399,53 +1399,42 @@ export function comparedEntityKey (str) {
|
||||
const regex = /\ = | =|= /g
|
||||
q = q.replace(regex, '=')
|
||||
|
||||
if (q.indexOf('AND') > -1 && checkStrIncludeAnd(q)) {
|
||||
q = q.replace(/ and /g, ' AND ').replace(/ in /g, ' IN ')
|
||||
const arr = q.split(' AND ')
|
||||
let newQ = ''
|
||||
let errorQ = ''
|
||||
const returnObj = {
|
||||
key: '',
|
||||
isKey: true
|
||||
if (q.indexOf(' AND ') > -1 || q.indexOf(' and ') > -1) {
|
||||
if (checkStrIncludeAnd(q)) {
|
||||
q = q.replace(/ and /g, ' AND ')
|
||||
}
|
||||
|
||||
const arr = q.split(' AND ')
|
||||
const returnObj = { key: '', isKey: false }
|
||||
arr.forEach(item => {
|
||||
// 判断是否包含=或者in
|
||||
const keyEqual = item.substring(0, item.indexOf('='))
|
||||
const keyIn = item.substring(0, item.indexOf(' IN '))
|
||||
const keyLike = item.substring(0, item.indexOf(' LIKE '))
|
||||
|
||||
let keyHas // 目前只有Tag操作符为has函数,避免以后会增加其他实体使用has,故不单独将has作为tag使用
|
||||
let objHas
|
||||
if (item.toLowerCase().indexOf('has(') > -1) {
|
||||
keyHas = item.match(/[()]([^,]+)/)[1] // 例:has(Tag,'111'),截取Tag
|
||||
objHas = columnList.find(t => t.label.toLowerCase() === keyHas.toLowerCase())
|
||||
let label = ''
|
||||
let key = ''
|
||||
if (item.indexOf('=') > -1) {
|
||||
label = item.substring(0, item.indexOf('='))
|
||||
key = '='
|
||||
} else if (item.toLowerCase().indexOf(' like ') > -1) {
|
||||
label = item.substring(0, item.toLowerCase().indexOf(' like '))
|
||||
key = 'like'
|
||||
} else if (item.toLowerCase().indexOf(' in ') > -1) {
|
||||
label = item.substring(0, item.toLowerCase().indexOf(' in '))
|
||||
key = 'in'
|
||||
} else if (item.toLowerCase().indexOf('has(') > -1) {
|
||||
label = item.substring(item.toLowerCase().indexOf('(') + 1, item.indexOf(','))
|
||||
key = 'has'
|
||||
}
|
||||
|
||||
const objEqual = columnList.find(t => t.label.toLowerCase() === keyEqual.toLowerCase())
|
||||
const objIn = columnList.find(t => t.label.toLowerCase() === keyIn.toLowerCase())
|
||||
const objLike = columnList.find(t => t.label.toLowerCase() === keyLike.toLowerCase())
|
||||
if (objEqual) {
|
||||
newQ += objEqual.label + item.substring(item.indexOf('='), item.length) + ' AND '
|
||||
} else if (objIn) {
|
||||
newQ += objIn.label + item.substring(item.indexOf(' IN '), item.length) + ' AND '
|
||||
} else if (objLike) {
|
||||
newQ += objLike.label + item.substring(item.indexOf(' LIKE '), item.length) + ' AND '
|
||||
} else if (objHas) {
|
||||
newQ += item.substring(item.indexOf(' has'), item.length) + ' AND '
|
||||
const obj = columnList.find(t => t.label.toLowerCase() === label.toLowerCase())
|
||||
if (obj) {
|
||||
if (key === 'has') {
|
||||
returnObj.key += 'has(' + obj.label + item.substring(item.indexOf(','), item.length) + ' AND '
|
||||
} else {
|
||||
returnObj.key += obj.label + ' ' + item.substring(item.toLowerCase().indexOf(key.toLowerCase()), item.length) + ' AND '
|
||||
}
|
||||
returnObj.isKey = true
|
||||
} else {
|
||||
errorQ += '[' + keyEqual + ']' + '、'
|
||||
returnObj.isKey = false
|
||||
return { key: '[' + key + ']', isKey: false }
|
||||
}
|
||||
})
|
||||
newQ = newQ.substring(0, newQ.length - 5)
|
||||
returnObj.key = newQ
|
||||
if (!returnObj.isKey) {
|
||||
errorQ = errorQ.substring(0, errorQ.length - 1)
|
||||
returnObj.key = errorQ
|
||||
} else {
|
||||
returnObj.key = handleStrToUniteStr(newQ)
|
||||
}
|
||||
returnObj.key = returnObj.key.substring(0, returnObj.key.length - 5)
|
||||
|
||||
return returnObj
|
||||
} else if (q.indexOf(' LIKE ') > -1 || q.indexOf(' like ') > -1) {
|
||||
@@ -1460,7 +1449,6 @@ export function comparedEntityKey (str) {
|
||||
}
|
||||
} else {
|
||||
const key = q.substring(0, q.indexOf('='))
|
||||
q = q.replace(/ AND /g, ' and ')
|
||||
const obj = columnList.find(t => t.label.toLowerCase() === key.toLowerCase())
|
||||
if (obj) {
|
||||
return { key: obj.label + q.substring(q.indexOf('='), q.length), isKey: true }
|
||||
@@ -1548,6 +1536,7 @@ export const handleEntityTypeByStr = (str) => {
|
||||
})
|
||||
|
||||
newStr = newArr.join(' AND ')
|
||||
newStr = handleStrToUniteStr(newStr)
|
||||
return newStr
|
||||
} else if (result) {
|
||||
// 不区分大小写,用columnList里的label
|
||||
@@ -1572,6 +1561,17 @@ export const handleEntityTypeByStr = (str) => {
|
||||
* 校验字符串格式,如ip、domain、app
|
||||
*/
|
||||
const checkFormatByStr = (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.length - 1] === '%') {
|
||||
str = str.substring(1, str.length)
|
||||
str = str.substring(0, str.length - 1)
|
||||
}
|
||||
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校验
|
||||
@@ -1592,6 +1592,10 @@ const checkFormatByStr = (str) => {
|
||||
}
|
||||
}
|
||||
export const 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校验
|
||||
@@ -1663,10 +1667,16 @@ const handleStrToUniteStr = (str) => {
|
||||
if (commonObj[i].indexOf('(') > -1) {
|
||||
// 原来为IN ()格式的直接保留
|
||||
lastObj[i] = `${i} IN ${commonObj[i]}`
|
||||
if (commonObj[i].indexOf('),') > -1) {
|
||||
// 此时为ip;"('1.1.1.1','2.2.2.2'), '3.3.3.3'",in后面还有同类型数据,也放到in里
|
||||
lastObj[i] = lastObj[i].replace('),', ',') + ')'
|
||||
}
|
||||
} else if (commonObj[i].indexOf(',') > -1) {
|
||||
let str = commonObj[i]
|
||||
str = str.replace(/(\d+\.\d+\.\d+\.\d+),(\d+\.\d+\.\d+\.\d+)/g, "'$1','$2'")
|
||||
lastObj[i] = `${i} IN (${str})`
|
||||
} else if (i.toLowerCase() === 'tag') {
|
||||
lastObj[i] = `has(${i},${commonObj[i]})`
|
||||
} else {
|
||||
// 单独存在的,直接保留
|
||||
lastObj[i] = `${i} = '${commonObj[i]}'`
|
||||
@@ -1706,7 +1716,10 @@ const combineLabel1 = (list) => {
|
||||
* @param str
|
||||
*/
|
||||
const checkStrIncludeAnd = (str) => {
|
||||
const arr = str.split(' and ')
|
||||
let arr = []
|
||||
if (str.indexOf(' and ')) {
|
||||
arr = str.split(' and ')
|
||||
}
|
||||
let label = ''
|
||||
|
||||
arr.forEach((item, index) => {
|
||||
|
||||
@@ -369,7 +369,7 @@ export default {
|
||||
|
||||
this.reloadUrl({
|
||||
listMode: this.listMode,
|
||||
q: param.str || '',
|
||||
q: encodeURI(param.str) || '',
|
||||
mode: mode,
|
||||
pageNo: this.pageObj.pageNo,
|
||||
pageSize: this.pageObj.pageSize
|
||||
@@ -381,7 +381,7 @@ export default {
|
||||
path: '/entityExplorer',
|
||||
query: {
|
||||
listMode: this.listMode,
|
||||
q: param.str || '',
|
||||
q: encodeURI(param.str) || '',
|
||||
mode: mode,
|
||||
range: this.timeFilter.dateRangeValue,
|
||||
pageNo: this.pageObj.pageNo,
|
||||
|
||||
Reference in New Issue
Block a user