This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
cyber-narrator-cn-ui/src/views/entityExplorer/search/ExplorerSearch.vue

273 lines
7.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="explorer-search">
<div class="explorer-search__title" v-show="!showList">{{$t('search.title')}}</div>
<div class="explorer-search__input-case" :class="{'explorer-search__input-case--question-mark-in-line': showList}">
<div class="explorer-search__input">
<advanced-search
ref="search"
:column-list="columnList"
:operator-list="operatorList"
:connection-list="connectionList"
:full-text="true"
:class="{'advanced-search--show-list': showList}"
@search="search"
></advanced-search>
</div>
<div class="search-symbol-inline" v-if="showList">
<i class="cn-icon cn-icon-help"></i>
</div>
<div v-else class="explorer-search__foot" v-ele-click-outside="esc">
<div class="foot__item" @click="triggerHistory">
<i class="el-icon-arrow-right" :class="{ 'arrow-rotate': showHistory }" style="padding-right: 5px;"></i>
<span>{{$t('search.searchHistory')}}</span>
</div>
<div class="foot__item">
<span @click="search">{{$t('overall.explore')}}</span>
<el-divider direction="vertical"></el-divider>
<span>{{$t('overall.help')}}</span>
</div>
<transition name="el-zoom-in-top">
<div class="search__history" v-show="showHistory">
<div class="history__items">
<div class="history__item" v-for="(h, i) in history" :key="i" @click="selectHistory(h.sql)">
<span class="item-date">{{h.date}}</span>
<div class="item-value" :title="h.sql">{{h.sql}}</div>
</div>
</div>
<div class="clear-all">
<span @click="clearHistory" v-if="!$_.isEmpty(history)">{{$t('overall.clear')}}</span>
<div v-else>暂无记录</div>
</div>
</div>
</transition>
</div>
</div>
</div>
</template>
<script>
import AdvancedSearch from '@/components/advancedSearch/Index'
import { columnType } from '@/components/advancedSearch/meta/meta'
import SqlParser from '@/components/advancedSearch/meta/sql-parser'
import {storageKey} from "@/utils/constants";
export default {
name: 'CnSearch',
components: {
AdvancedSearch
},
props: {
showList: {
type: Boolean,
default: true
}
},
data () {
return {
columnList: [
{
name: 'entity_type',
type: 'string',
// label: this.$t('overall.type')
label: 'Type'
},
{
name: 'ip_addr',
type: 'string',
label: 'IP'
},
{
name: 'ip_location_country',
type: 'string',
// label: this.$t('overall.country')
label: 'Country'
},
{
name: 'ip_location_province',
type: 'string',
// label: this.$t('overall.province')
label: 'Province'
},
{
name: 'ip_location_city',
type: 'string',
// label: this.$t('overall.city')
label: 'City'
},
{
name: 'ip_asn',
type: 'string',
// label: this.$t('entities.asn')
label: 'ASN'
},
{
name: 'ip_os',
type: 'string',
label: 'OS'
},
{
name: 'domain_name',
type: 'string',
label: 'Domain'
},
{
name: 'domain_category',
type: 'string',
// label: this.$t('entities.domainCategory')
label: 'Domain category'
},
{
name: 'domain_category_group',
type: 'string',
// label: this.$t('entities.domainDetail.categoryGroup')
label: 'Domain category group'
},
{
name: 'domain_reputation_score',
type: 'long',
// label: this.$t('entities.domainDetail.reputationValue')
label: 'Domain reputation score'
},
{
name: 'domain_reputation_level',
type: 'string',
// label: this.$t('entities.reputationLevel')
label: 'Domain reputation level'
},
{
name: 'domain_whois_email',
type: 'string',
label: 'Domain whois email'
},
{
name: 'domain_whois_name_servers',
type: 'string',
label: 'Domain whois ns'
},
{
name: 'domain_whois_registrar',
type: 'string',
label: 'Domain whois registrar'
},
{
name: 'domain_whois_org',
type: 'string',
label: 'Domain whois organization'
},
{
name: 'domain_whois_city',
type: 'string',
label: 'Domain whois city'
},
{
name: 'domain_whois_state',
type: 'string',
label: 'Domain whois state'
},
{
name: 'domain_whois_country',
type: 'string',
label: 'Domain whois country'
},
{
name: 'app_name',
type: 'string',
label: 'APP'
},
{
name: 'app_category',
type: 'string',
// label: this.$t('trafficSummary.appCategory')
label: 'APP category'
},
{
name: 'app_subcategory',
type: 'string',
// label: this.$t('entities.domainDetail.appSubcategory')
label: 'APP subcategory'
},
{
name: 'app_risk',
type: 'string',
// label: this.$t('trafficSummary.appRisk')
label: 'APP risk'
}
],
operatorList: ['=', '!=', '>', '<', '>=', '<='/*, 'IN', 'NOT IN', 'LIKE', 'NOT LIKE'*/],
connectionList: [
{
value: 'AND',
label: 'AND'
},
{
value: 'OR',
label: 'OR'
}
],
showHistory: false,
history: []
}
},
methods: {
search (metaList, formatSql) {
let sql = formatSql
// 加入搜索记录将记录数量控制在30以内
if (sql) {
const oldHistory = localStorage.getItem(storageKey.entitySearchHistory)
let arr = []
const newItem = { sql, date: window.$dayJs.tz(new Date().getTime()).format('YYYY-MM-DD HH:mm:ss') }
if (!this.$_.isEmpty(oldHistory)) {
const oldArr = JSON.parse(oldHistory)
oldArr.unshift(newItem)
arr = [...oldArr]
if (arr.length > 30) {
arr = arr.slice(0, 30)
}
} else {
arr.push(newItem)
}
localStorage.setItem(storageKey.entitySearchHistory, JSON.stringify(arr))
}
if (metaList && this.$_.isArray(metaList)) {
// 全文搜索处理
const hasFullText = metaList.some(meta => {
return meta.column && meta.column.type === columnType.fullText
})
if (hasFullText) {
const parser = new SqlParser(metaList, this.columnList)
sql = parser.parseMetaToSql(metaList, true)
}
}
this.$emit('search', metaList, sql)
},
addParams (params) {
this.$refs.search.addParams(params)
},
selectHistory (sql) {
this.$refs.search.setSql(sql)
this.showHistory = false
this.$nextTick(() => {
if (this.$refs.search.$refs.textMode) {
this.$refs.search.$refs.textMode.focus()
}
})
},
clearHistory () {
localStorage.setItem(storageKey.entitySearchHistory, '')
this.history = []
},
triggerHistory () {
this.showHistory = !this.showHistory
if (this.showHistory) {
const history = localStorage.getItem(storageKey.entitySearchHistory)
if (!this.$_.isEmpty(history)) {
this.history = JSON.parse(history)
}
}
},
esc () {
this.showHistory = false
}
}
}
</script>