CN-1238: 实体查询语法逻辑
This commit is contained in:
@@ -54,22 +54,22 @@
|
|||||||
<!-- 条件连接符 -->
|
<!-- 条件连接符 -->
|
||||||
<template v-else-if="meta.meta === connection">
|
<template v-else-if="meta.meta === connection">
|
||||||
<div class="connection__value">
|
<div class="connection__value">
|
||||||
<div v-show="meta.isEditing">
|
<!-- <div v-show="meta.isEditing">-->
|
||||||
<el-select
|
<!-- <el-select-->
|
||||||
:placeholder="meta.value"
|
<!-- :placeholder="meta.value"-->
|
||||||
v-model="meta.value"
|
<!-- v-model="meta.value"-->
|
||||||
size="mini"
|
<!-- size="mini"-->
|
||||||
@change="(value) => selectConnection(value, meta)"
|
<!-- @change="(value) => selectConnection(value, meta)"-->
|
||||||
>
|
<!-- >-->
|
||||||
<el-option
|
<!-- <el-option-->
|
||||||
v-for="(connection, index) in connectionList"
|
<!-- v-for="(connection, index) in connectionList"-->
|
||||||
:key="index"
|
<!-- :key="index"-->
|
||||||
:label="connection.label"
|
<!-- :label="connection.label"-->
|
||||||
:value="connection.value"
|
<!-- :value="connection.value"-->
|
||||||
></el-option>
|
<!-- ></el-option>-->
|
||||||
</el-select>
|
<!-- </el-select>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<span v-show="!meta.isEditing" @click="connectionClick(meta)">{{meta.value}}</span>
|
<span v-show="!meta.isEditing">{{meta.value}}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -79,7 +79,6 @@
|
|||||||
<el-popover
|
<el-popover
|
||||||
popper-class="my-popper-class"
|
popper-class="my-popper-class"
|
||||||
placement="top"
|
placement="top"
|
||||||
:popper-style="{border: '1px red solid'}"
|
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
:content="$t('entity.switchToBasicSearch')"
|
:content="$t('entity.switchToBasicSearch')"
|
||||||
>
|
>
|
||||||
@@ -88,6 +87,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-show="metaList.length>0" class="search__suffix-close" @click="cleanMetaList">
|
||||||
|
<i class="el-icon-error"></i>
|
||||||
|
</div>
|
||||||
<div class="search__suffix" :class="showList ? 'new-search__suffix' : 'entity-explorer-search'" @click="search">
|
<div class="search__suffix" :class="showList ? 'new-search__suffix' : 'entity-explorer-search'" @click="search">
|
||||||
<i class="el-icon-search"></i>
|
<i class="el-icon-search"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,8 +101,8 @@
|
|||||||
import Meta, { connection, condition, columnType } from './meta/meta'
|
import Meta, { connection, condition, columnType } from './meta/meta'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { handleErrorTip } from '@/components/advancedSearch/meta/error'
|
import { handleErrorTip } from '@/components/advancedSearch/meta/error'
|
||||||
import Parser, { stringInQuot } from '@/components/advancedSearch/meta/parser'
|
import Parser, { handleMetaListToStr, stringInQuot } from '@/components/advancedSearch/meta/parser'
|
||||||
import { comparedEntityKey, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
import { comparedEntityKey, handleEntityTypeByStr, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
export default {
|
export default {
|
||||||
name: 'TagMode',
|
name: 'TagMode',
|
||||||
props: {
|
props: {
|
||||||
@@ -329,7 +331,9 @@ export default {
|
|||||||
const parser = new Parser(this.columnList)
|
const parser = new Parser(this.columnList)
|
||||||
const errorList = parser.validateMeta(this.metaList)
|
const errorList = parser.validateMeta(this.metaList)
|
||||||
if (_.isEmpty(errorList)) {
|
if (_.isEmpty(errorList)) {
|
||||||
this.$emit('search', parser.parseMeta(this.metaList))
|
const str = handleMetaListToStr(this.metaList)
|
||||||
|
const keyInfo = comparedEntityKey(handleEntityTypeByStr(str))
|
||||||
|
this.$emit('search', { ...parser.parseStr(keyInfo.key), str: str })
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(handleErrorTip(errorList[0]))
|
this.$message.error(handleErrorTip(errorList[0]))
|
||||||
}
|
}
|
||||||
@@ -431,6 +435,9 @@ export default {
|
|||||||
newUrl = urlParamsHandler(window.location.href, query, newParam, clean)
|
newUrl = urlParamsHandler(window.location.href, query, newParam, clean)
|
||||||
}
|
}
|
||||||
overwriteUrl(newUrl)
|
overwriteUrl(newUrl)
|
||||||
|
},
|
||||||
|
cleanMetaList () {
|
||||||
|
this.metaList = []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import { toRaw } from 'vue'
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { columnType } from '@/components/advancedSearch/meta/meta'
|
import { columnType } from '@/components/advancedSearch/meta/meta'
|
||||||
import { handleErrorTip } from '@/components/advancedSearch/meta/error'
|
import { handleErrorTip } from '@/components/advancedSearch/meta/error'
|
||||||
import { comparedEntityKey, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
import { comparedEntityKey, handleEntityTypeByStr, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TextMode',
|
name: 'TextMode',
|
||||||
@@ -57,6 +57,8 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
cleanParams () {
|
cleanParams () {
|
||||||
toRaw(this.codeMirror).setValue('')
|
toRaw(this.codeMirror).setValue('')
|
||||||
|
this.isEdit = false
|
||||||
|
this.isCloseIcon = false
|
||||||
const routeQuery = this.$route.query
|
const routeQuery = this.$route.query
|
||||||
delete routeQuery.q
|
delete routeQuery.q
|
||||||
this.reloadUrl(routeQuery, 'cleanOldParams')
|
this.reloadUrl(routeQuery, 'cleanOldParams')
|
||||||
@@ -72,9 +74,8 @@ export default {
|
|||||||
this.codeMirror.setOption('extraKeys', {
|
this.codeMirror.setOption('extraKeys', {
|
||||||
Enter: (cm) => {}
|
Enter: (cm) => {}
|
||||||
})
|
})
|
||||||
const str = this.codeMirror.getValue().trim()
|
|
||||||
this.codeMirror.on('focus', () => {
|
this.codeMirror.on('focus', () => {
|
||||||
if (str !== '') {
|
if (this.codeMirror.getValue().trim() !== '') {
|
||||||
this.isEdit = true
|
this.isEdit = true
|
||||||
this.isCloseIcon = true
|
this.isCloseIcon = true
|
||||||
}
|
}
|
||||||
@@ -95,7 +96,7 @@ export default {
|
|||||||
const str = this.codeMirror.getValue().trim()
|
const str = this.codeMirror.getValue().trim()
|
||||||
if (str) {
|
if (str) {
|
||||||
const parser = new Parser(this.columnList)
|
const parser = new Parser(this.columnList)
|
||||||
const keyInfo = comparedEntityKey(str)
|
const keyInfo = comparedEntityKey(handleEntityTypeByStr(str))
|
||||||
if (keyInfo.isKey) {
|
if (keyInfo.isKey) {
|
||||||
const errorList = parser.validateStr(keyInfo.key)
|
const errorList = parser.validateStr(keyInfo.key)
|
||||||
if (_.isEmpty(errorList)) {
|
if (_.isEmpty(errorList)) {
|
||||||
@@ -104,7 +105,7 @@ export default {
|
|||||||
this.$message.error(handleErrorTip(errorList[0]))
|
this.$message.error(handleErrorTip(errorList[0]))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(this.$t('tip.invalidQueryField') + keyInfo.key)
|
this.$message.error(this.$t('tip.invalidQueryField') + ' ' + keyInfo.key)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.$emit('search', { q: '', str: '', metaList: [] })
|
this.$emit('search', { q: '', str: '', metaList: [] })
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ export const defaultConnectionList = [
|
|||||||
{
|
{
|
||||||
value: 'AND',
|
value: 'AND',
|
||||||
label: 'AND'
|
label: 'AND'
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'OR',
|
|
||||||
label: 'OR'
|
|
||||||
}
|
}
|
||||||
|
// {
|
||||||
|
// value: 'OR',
|
||||||
|
// label: 'OR'
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
export default class Meta {
|
export default class Meta {
|
||||||
// meta元数据有两种,一是condition,表示字段、操作符、值的组合,二是connection,是condition之间的连接符,AND | OR
|
// meta元数据有两种,一是condition,表示字段、操作符、值的组合,二是connection,是condition之间的连接符,AND | OR
|
||||||
|
|||||||
@@ -348,8 +348,10 @@ export default class Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (['o', 'a'].indexOf(s.toLowerCase()) > -1) {
|
// } else if (['o', 'a'].indexOf(s.toLowerCase()) > -1) {
|
||||||
|
} else if (['a'].indexOf(s.toLowerCase()) > -1) {
|
||||||
// 前一位是否是空格,否则视为普通字符串
|
// 前一位是否是空格,否则视为普通字符串
|
||||||
|
// 处理连接符为or的情况
|
||||||
if (s.toLowerCase() === 'o') {
|
if (s.toLowerCase() === 'o') {
|
||||||
if (strArr[i + 1] && strArr[i + 1].toLowerCase() === 'r' && strArr[i + 2] && strArr[i + 2] === ' ') {
|
if (strArr[i + 1] && strArr[i + 1].toLowerCase() === 'r' && strArr[i + 2] && strArr[i + 2] === ' ') {
|
||||||
token = new Token(types.connection, 'OR')
|
token = new Token(types.connection, 'OR')
|
||||||
@@ -763,3 +765,65 @@ export function stringInQuot (value) {
|
|||||||
export function handleOperatorSpace (operator) {
|
export function handleOperatorSpace (operator) {
|
||||||
return ['IN', 'NOT IN', 'LIKE', 'NOT LIKE'].indexOf(operator) > -1 ? ` ${operator} ` : operator
|
return ['IN', 'NOT IN', 'LIKE', 'NOT LIKE'].indexOf(operator) > -1 ? ` ${operator} ` : operator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将metaList转为字符串
|
||||||
|
* @param metaList
|
||||||
|
* @returns {string|*}
|
||||||
|
*/
|
||||||
|
export function handleMetaListToStr (metaList) {
|
||||||
|
// 长度为1时,即模糊搜索,例如搜索框值为1.1.1.1,则直接返回1.1.1.1
|
||||||
|
if (metaList && metaList.length === 1) {
|
||||||
|
return metaList[0].column.label
|
||||||
|
} else if (metaList && metaList.length > 1) {
|
||||||
|
// 此为按语法搜索,将metaList转为字符串
|
||||||
|
const newMetaList = []
|
||||||
|
// 去除metaList的AND项
|
||||||
|
metaList.forEach(item => {
|
||||||
|
if (item.value !== 'AND') {
|
||||||
|
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 {
|
||||||
|
// 单独存在的,直接保留
|
||||||
|
lastObj[i] = `${i} = ${newObj[i]}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let str = ''
|
||||||
|
for (const i in lastObj) {
|
||||||
|
str += lastObj[i] + ' AND '
|
||||||
|
}
|
||||||
|
str = str.slice(0, -5)
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将相同属性的label组合到一起,即IP='1.1.1.1' AND IP='2.2.2.2'组合成IP: '1.1.1.1,2.2.2.2'
|
||||||
|
* @param list
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
const combineLabel = (list) => {
|
||||||
|
return list.reduce((acc, cur) => {
|
||||||
|
if (acc[cur.column.label]) {
|
||||||
|
acc[cur.column.label] += `,${cur.value.label}`
|
||||||
|
} else {
|
||||||
|
acc[cur.column.label] = cur.value.label
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
}
|
||||||
|
|||||||
@@ -116,6 +116,11 @@ const user = {
|
|||||||
localStorage.setItem(storageKey.linkInfo, res.page.list[0].cvalue)
|
localStorage.setItem(storageKey.linkInfo, res.page.list[0].cvalue)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
get(api.config, { ckey: 'schema_entity_explore' }).then(res => {
|
||||||
|
if (res.code === 200 && res.page.list && res.page.list.length > 0) {
|
||||||
|
localStorage.setItem(storageKey.schemaEntityExplore, res.page.list[0].cvalue)
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
logoutSuccess (store, res) {
|
logoutSuccess (store, res) {
|
||||||
localStorage.removeItem(storageKey.username)
|
localStorage.removeItem(storageKey.username)
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ export const storageKey = {
|
|||||||
drillDownTableConfig: 'drilldownTableConfig',
|
drillDownTableConfig: 'drilldownTableConfig',
|
||||||
userCustomizationConfig: 'userCustomizationConfig',
|
userCustomizationConfig: 'userCustomizationConfig',
|
||||||
linkInfo: 'cn-link-info',
|
linkInfo: 'cn-link-info',
|
||||||
history: 'cn-history'
|
history: 'cn-history',
|
||||||
|
schemaEntityExplore: 'schema_entity_explore'
|
||||||
}
|
}
|
||||||
export const largeCountryList = ['CN', 'US', 'RU', 'AU', 'CA', 'KZ', 'IN', 'BR']
|
export const largeCountryList = ['CN', 'US', 'RU', 'AU', 'CA', 'KZ', 'IN', 'BR']
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
// 如有使用this的
|
// 如有使用this的
|
||||||
import i18n from '@/i18n'
|
import i18n from '@/i18n'
|
||||||
import { unitTypes } from '@/utils/constants'
|
import { storageKey, unitTypes } from '@/utils/constants'
|
||||||
const _this = i18n.global
|
const _this = i18n.global
|
||||||
_this.$t = _this.t
|
_this.$t = _this.t
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ export const dataForNpmNetworkQuantity = {
|
|||||||
{ name: 'overall.packetRetrans' }
|
{ name: 'overall.packetRetrans' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
export const columnList = [
|
export const columnList1 = [
|
||||||
{
|
{
|
||||||
name: 'ip',
|
name: 'ip',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -334,14 +334,20 @@ export const columnList = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
let schemaEntityExplore = localStorage.getItem(storageKey.schemaEntityExplore)
|
||||||
|
// todo enityMetadata字段后续可能会改
|
||||||
|
schemaEntityExplore = schemaEntityExplore ? JSON.parse(schemaEntityExplore).enityMetadata : columnList1
|
||||||
|
export const columnList = schemaEntityExplore
|
||||||
|
|
||||||
export const operatorList = ['=', '!=', /* '>', '<', '>=', '<=', */'IN', 'NOT IN', 'LIKE', 'NOT LIKE']
|
export const operatorList = ['=', '!=', /* '>', '<', '>=', '<=', */'IN', 'NOT IN', 'LIKE', 'NOT LIKE']
|
||||||
export const connectionList = [
|
export const connectionList = [
|
||||||
{
|
{
|
||||||
value: 'AND',
|
value: 'AND',
|
||||||
label: 'AND'
|
label: 'AND'
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'OR',
|
|
||||||
label: 'OR'
|
|
||||||
}
|
}
|
||||||
|
// {
|
||||||
|
// value: 'OR',
|
||||||
|
// label: 'OR'
|
||||||
|
// }
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import router from '@/router'
|
|||||||
import indexedDBUtils from '@/indexedDB'
|
import indexedDBUtils from '@/indexedDB'
|
||||||
|
|
||||||
// columnList从'@/utils/static-data'引入的话,会导致国际化i18n出错
|
// columnList从'@/utils/static-data'引入的话,会导致国际化i18n出错
|
||||||
const columnList = [
|
const columnList1 = [
|
||||||
{
|
{
|
||||||
name: 'ip',
|
name: 'ip',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -72,6 +72,10 @@ const columnList = [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
let schemaEntityExplore = localStorage.getItem(storageKey.schemaEntityExplore)
|
||||||
|
// todo enityMetadata字段后续可能会改
|
||||||
|
schemaEntityExplore = schemaEntityExplore ? JSON.parse(schemaEntityExplore).enityMetadata : columnList1
|
||||||
|
export const columnList = schemaEntityExplore
|
||||||
|
|
||||||
export const tableSort = {
|
export const tableSort = {
|
||||||
// 是否需要排序
|
// 是否需要排序
|
||||||
@@ -1387,6 +1391,10 @@ export function switchStatus (status) {
|
|||||||
*/
|
*/
|
||||||
export function comparedEntityKey (q) {
|
export function comparedEntityKey (q) {
|
||||||
if (q && q.indexOf('=') > -1) {
|
if (q && q.indexOf('=') > -1) {
|
||||||
|
// =周围有空格,则去除空格
|
||||||
|
const regex = /\ = | =|= /g
|
||||||
|
q = q.replace(regex, '=')
|
||||||
|
|
||||||
if (q.indexOf('AND') > -1) {
|
if (q.indexOf('AND') > -1) {
|
||||||
const arr = q.split(' AND ')
|
const arr = q.split(' AND ')
|
||||||
let newQ = ''
|
let newQ = ''
|
||||||
@@ -1414,6 +1422,11 @@ export function comparedEntityKey (q) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return returnObj
|
return returnObj
|
||||||
|
} else if (q.indexOf('LIKE') > -1) {
|
||||||
|
return {
|
||||||
|
key: q,
|
||||||
|
isKey: true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const key = q.substring(0, q.indexOf('='))
|
const key = q.substring(0, q.indexOf('='))
|
||||||
const obj = columnList.find(t => t.label.toLowerCase() === key.toLowerCase())
|
const obj = columnList.find(t => t.label.toLowerCase() === key.toLowerCase())
|
||||||
@@ -1423,6 +1436,11 @@ export function comparedEntityKey (q) {
|
|||||||
return { key: '[' + key + ']', isKey: false }
|
return { key: '[' + key + ']', isKey: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (q && q.indexOf(' IN ') > -1) {
|
||||||
|
return {
|
||||||
|
key: q,
|
||||||
|
isKey: true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
key: q,
|
key: q,
|
||||||
@@ -1430,3 +1448,48 @@ export function comparedEntityKey (q) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将模糊查询传过来的str转换为对应的实体类型,不满足ip和domain格式的当成app
|
||||||
|
* @param str
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const handleEntityTypeByStr = (str) => {
|
||||||
|
if (str) {
|
||||||
|
const regex = /^["']|["']$/
|
||||||
|
// 去除两侧引号,如'1.1.1.1',避免校验时被当作app
|
||||||
|
console.log('模糊查询', str, regex.test(str))
|
||||||
|
if (regex.test(str)) {
|
||||||
|
str = str.replace(/^['"]+|['"]+$/g, '')
|
||||||
|
}
|
||||||
|
console.log('模糊查询222', str, str.trim())
|
||||||
|
|
||||||
|
const arr = ['IP'.toLowerCase(), 'Domain'.toLowerCase(), 'App'.toLowerCase(), 'City'.toLowerCase(), 'Country'.toLowerCase(), 'ASN'.toLowerCase()]
|
||||||
|
let newStr = JSON.parse(JSON.stringify(str.toLowerCase()))
|
||||||
|
// 将str中的IP、Domain等替换为数组arr中的元素
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
newStr = newStr.replace(new RegExp(arr[i], 'g'), arr[i])
|
||||||
|
}
|
||||||
|
// 检查str字段在arr中是否出现
|
||||||
|
const result = arr.some(item => newStr.includes(item))
|
||||||
|
if (result) {
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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+)*$/
|
||||||
|
|
||||||
|
console.log('ip校验', regexIPv4.test(str), regexIPv6.test(str))
|
||||||
|
if (regexIPv4.test(str) || regexIPv6.test(str)) {
|
||||||
|
return `IP='${str}'`
|
||||||
|
} else if (reg.test(str)) {
|
||||||
|
return `Domain LIKE '%${str}'`
|
||||||
|
} else {
|
||||||
|
return `App LIKE '%${str}'%`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -254,9 +254,9 @@ export default {
|
|||||||
// networkOverviewBeforeTab是dashboard点击下钻标识,dimensionType是详情页到下钻页标识
|
// networkOverviewBeforeTab是dashboard点击下钻标识,dimensionType是详情页到下钻页标识
|
||||||
const tab = query.networkOverviewBeforeTab || query.dimensionType
|
const tab = query.networkOverviewBeforeTab || query.dimensionType
|
||||||
const value = query.fourthMenu
|
const value = query.fourthMenu
|
||||||
const ipList = ['ip', 'clientIp', 'serverIp', 'dnsServer', 'a', 'aaaa']
|
const ipList = ['ip', 'clientIp', 'serverIp', 'a', 'aaaa']
|
||||||
const appList = ['appLabel']
|
const appList = ['appLabel']
|
||||||
const domainList = ['sslSni'] // domain暂定,先加入snis
|
const domainList = ['sslSni', 'domain']
|
||||||
|
|
||||||
if (ipList.indexOf(tab) > -1) {
|
if (ipList.indexOf(tab) > -1) {
|
||||||
entityType.value = 'ip'
|
entityType.value = 'ip'
|
||||||
|
|||||||
@@ -168,7 +168,13 @@ import { getNowTime, getSecond } from '@/utils/date-util'
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import Loading from '@/components/common/Loading'
|
import Loading from '@/components/common/Loading'
|
||||||
import { overwriteUrl, urlParamsHandler, numberWithCommas, comparedEntityKey } from '@/utils/tools'
|
import {
|
||||||
|
overwriteUrl,
|
||||||
|
urlParamsHandler,
|
||||||
|
numberWithCommas,
|
||||||
|
comparedEntityKey,
|
||||||
|
handleEntityTypeByStr
|
||||||
|
} from '@/utils/tools'
|
||||||
import Parser from '@/components/advancedSearch/meta/parser'
|
import Parser from '@/components/advancedSearch/meta/parser'
|
||||||
import { handleErrorTip } from '@/components/advancedSearch/meta/error'
|
import { handleErrorTip } from '@/components/advancedSearch/meta/error'
|
||||||
import { columnList } from '@/utils/static-data'
|
import { columnList } from '@/utils/static-data'
|
||||||
@@ -863,7 +869,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const parser = new Parser(columnList)
|
const parser = new Parser(columnList)
|
||||||
const keyInfo = comparedEntityKey(str)
|
const keyInfo = comparedEntityKey(handleEntityTypeByStr(str))
|
||||||
if (keyInfo.isKey) {
|
if (keyInfo.isKey) {
|
||||||
const errorList = parser.validateStr(keyInfo.key)
|
const errorList = parser.validateStr(keyInfo.key)
|
||||||
if (_.isEmpty(errorList)) {
|
if (_.isEmpty(errorList)) {
|
||||||
@@ -872,7 +878,7 @@ export default {
|
|||||||
this.$message.error(handleErrorTip(errorList[0]))
|
this.$message.error(handleErrorTip(errorList[0]))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(this.$t('tip.invalidQueryField') + keyInfo.key)
|
this.$message.error(this.$t('tip.invalidQueryField') + ' ' + keyInfo.key)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.search({ q: '', str: '', metaList: [] })
|
this.search({ q: '', str: '', metaList: [] })
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
<i class="cn-icon cn-icon-position"></i>
|
<i class="cn-icon cn-icon-position"></i>
|
||||||
<span class="row-item-label">{{ $t('overall.region') }} : </span>
|
<span class="row-item-label">{{ $t('overall.city') }} : </span>
|
||||||
<span class="row-item-value">{{ entityData.location ? ipLocationRegion(entityData.location) : '-' }}</span>
|
<span class="row-item-value">{{ entityData.location ? ipLocationRegion(entityData.location) : '-' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info__item">
|
<div class="basic-info__item">
|
||||||
|
|||||||
@@ -74,11 +74,11 @@ export default {
|
|||||||
{
|
{
|
||||||
value: 'AND',
|
value: 'AND',
|
||||||
label: 'AND'
|
label: 'AND'
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'OR',
|
|
||||||
label: 'OR'
|
|
||||||
}
|
}
|
||||||
|
// {
|
||||||
|
// value: 'OR',
|
||||||
|
// label: 'OR'
|
||||||
|
// }
|
||||||
],
|
],
|
||||||
showHistory: false,
|
showHistory: false,
|
||||||
history: []
|
history: []
|
||||||
|
|||||||
Reference in New Issue
Block a user