feat: 搜索框(部分内容)

This commit is contained in:
chenjinsong
2022-01-25 17:16:56 +08:00
parent d2d38c2d8c
commit f8d780cba6
13 changed files with 410 additions and 123 deletions

View File

@@ -1,90 +0,0 @@
<template>
<el-input
class="advanced-search"
:class="{'advanced-search--show-list': showList}"
v-model="searchContentTemp"
@keyup.enter="enter"
>
<template #suffix>
<div class="search__suffixes" v-if="!showList">
<div class="search__suffix">
<i class="cn-icon cn-icon-search-advance"></i>
</div>
<div class="search__suffix" @click="enter">
<i class="el-icon-search"></i>
</div>
</div>
<div class="search__suffixes--show-list" v-else>
<div class="search__suffix">
<i class="cn-icon cn-icon-search-advance"></i>
</div>
<div class="search__suffix" @click="enter">
<i class="el-icon-search"></i>
</div>
</div>
</template>
</el-input>
<!-- <div class="advanced-search"></div>-->
</template>
<script>
import { objToStr, strToObj } from '@/utils/tools'
export default {
name: 'AdvancedSearch',
props: {
showList: {
type: Boolean,
default: true
}
},
data () {
return {
searchContentTemp: '', // 搜索框内的文本内容按回车键后为searchContent赋值
searchContent: '', // 查询语句
searchParams: null // 搜索参数,格式为[{ name: xxx, value: xxx }, ...]
}
},
methods: {
search () {
this.$emit('search', this.searchParams)
},
reset () {
this.searchParams = null
this.searchParams = []
},
addParams (params) {
if (params) {
const newParams = { ...this.searchParams, ...params }
this.searchContentTemp = objToStr(newParams)
this.enter()
}
},
enter () {
if (!this.searchContentTemp) {
this.reset()
} else {
this.searchContent = this.searchContentTemp
}
}
},
watch: {
searchContent (n) {
if (n) {
this.searchParams = strToObj(n)
} else {
this.reset()
}
this.searchContentTemp !== n && (this.searchContentTemp = n)
},
searchParams: {
deep: true,
handler (n) {
if (n) {
// 请求接口获取左侧过滤条件和右侧entity列表
this.search()
}
}
}
}
}
</script>

View File

@@ -4,14 +4,19 @@
>
<text-mode
v-if="searchMode === 'text'"
ref="textMode"
:column-list="columnList"
:sql="sql"
@changeMode="changeMode"
@search="search"
></text-mode>
<tag-mode
v-if="searchMode === 'tag'"
ref="tagMode"
:column-list="columnList"
:operator-list="showOperatorList"
:connection-list="showConnectionList"
:convert-meta-list="metaList"
@changeMode="changeMode"
@search="search"
></tag-mode>
@@ -30,6 +35,12 @@ export default {
TagMode,
TextMode
},
data () {
return {
sql: null,
metaList: null
}
},
props: {
// 默认模式tag | text
defaultMode: String,
@@ -49,11 +60,20 @@ export default {
connectionList: Array
},
methods: {
search () {
search (metaList, formatSql) {
this.$emit('search', formatSql)
},
changeMode (mode) {
changeMode (mode, data) {
this.searchMode = mode
if (mode === 'text') {
this.sql = data
} else if (mode === 'tag') {
this.metaList = data
}
},
addParams (params) {
this.$refs.tagMode && this.$refs.tagMode.addParams(params)
this.$refs.textMode && this.$refs.textMode.addParams(params)
}
},
setup (props) {

View File

@@ -75,7 +75,7 @@
<div class="tag-search__add" @click="addCondition">{{$t('entities.advancedSearch.add')}}</div>
<div class="search__suffixes search__suffixes--tag-mode">
<div class="search__suffix" @click="changeMode">
<i class="cn-icon cn-icon-search-advance"></i>
<i class="cn-icon cn-icon-search-normal"></i>
</div>
<div class="search__suffix" @click="search">
<i class="el-icon-search"></i>
@@ -87,12 +87,14 @@
<script>
import Meta, { connection, condition, columnType } from './meta/meta'
import _ from 'lodash'
import SqlParser, { stringInQuot } from '@/utils/sql-parser'
export default {
name: 'TagMode',
props: {
columnList: Array,
operatorList: Array,
connectionList: Array
connectionList: Array,
convertMetaList: Array
},
data () {
return {
@@ -103,9 +105,9 @@ export default {
},
methods: {
// 新增条件
addCondition () {
this.metaList.forEach(meta => {
meta.cancelEditing()
addCondition (meta) {
this.metaList.forEach(m => {
m.cancelEditing()
})
// 先判断上一个condition是否已填写完整没有则删除之后将当前所有meta的内容的isEditing置为false
if (this.metaList.length > 0) {
@@ -118,14 +120,19 @@ export default {
if (!_.isEmpty(this.metaList)) {
this.addConnection()
}
const newCondition = new Meta(condition)
newCondition.isEditing = true
newCondition.column.isEditing = true
this.metaList.push(newCondition)
if (meta instanceof Meta) {
this.metaList.push(meta)
} else {
const newCondition = new Meta(condition)
newCondition.isEditing = true
newCondition.column.isEditing = true
this.metaList.push(newCondition)
this.$nextTick(() => {
this.$refs.columnSelect.focus()
})
this.$nextTick(() => {
this.$refs.columnSelect.focus()
})
}
console.info(this.metaList)
},
addConnection () {
this.metaList.push(new Meta(connection))
@@ -216,10 +223,44 @@ export default {
})
},
search () {
this.$emit('search', this.metaList)
const parser = new SqlParser(this.metaList, this.columnList)
const { metaList, formatSql } = parser.formatMetaList()
this.metaList = metaList
this.$emit('search', this.metaList, formatSql)
},
changeMode () {
this.$emit('changeMode', 'text')
const parser = new SqlParser(this.metaList, this.columnList)
const { metaList, formatSql } = parser.formatMetaList()
this.metaList = metaList
this.$emit('changeMode', 'text', formatSql)
},
addParams (params) {
Object.keys(params).forEach(key => {
const column = this.columnList.find(column => {
return column.name === key
})
const meta = new Meta()
meta.column.name = key
meta.column.type = column ? column.type : columnType.string
meta.column.label = column ? column.label : key
meta.operator.value = '='
meta.operator.show = true
meta.value.value = meta.column.type === columnType.string ? stringInQuot(params[key]) : params[key]
meta.value.show = true
meta.value.label = meta.value.value
this.addCondition(meta)
})
}
},
watch: {
convertMetaList: {
immediate: true,
deep: true,
handler (n) {
if (!_.isEmpty(n)) {
this.metaList = n
}
}
}
}
}

View File

@@ -6,7 +6,7 @@
<div class="search__suffix" @click="changeMode">
<i class="cn-icon cn-icon-search-advance"></i>
</div>
<div class="search__suffix">
<div class="search__suffix" @click="search">
<i class="el-icon-search"></i>
</div>
</div>
@@ -16,24 +16,77 @@
import 'codemirror/theme/ambiance.css'
import 'codemirror/addon/hint/show-hint'
import 'codemirror/addon/hint/show-hint.css'
import 'codemirror/addon/display/placeholder'
import 'codemirror/mode/sql/sql'
const CodeMirror = require('codemirror')
import SqlParser, { stringInQuot } from '@/utils/sql-parser'
import CodeMirror from 'codemirror'
import { toRaw } from 'vue'
import { columnType } from '@/components/advancedSearch/meta/meta'
export default {
name: 'TextMode',
props: {
columnList: Array,
sql: String
},
data () {
return {
codeMirror: null
}
},
methods: {
initCodeMirror () {
CodeMirror.fromTextArea(this.$refs.textSearch, {
this.codeMirror = CodeMirror.fromTextArea(this.$refs.textSearch, {
mode: {
name: 'sql'
},
placeholder: 'Enter...',
lineNumbers: false
})
},
search () {
this.$emit('search', this.metaList)
const originalSql = this.codeMirror.getValue()
const parser = new SqlParser(originalSql, this.columnList)
const errorList = parser.validate()
if (this.$_.isEmpty(errorList)) {
const { metaList, formatSql } = parser.formatSql()
toRaw(this.codeMirror).setValue(formatSql)
this.$emit('search', metaList, formatSql)
}
},
changeMode () {
this.$emit('changeMode', 'tag')
const originalSql = this.codeMirror.getValue()
const parser = new SqlParser(originalSql, this.columnList)
const errorList = parser.validate()
if (this.$_.isEmpty(errorList)) {
const { metaList, formatSql } = parser.formatSql()
toRaw(this.codeMirror).setValue(formatSql)
this.$emit('changeMode', 'tag', metaList)
} else {
this.$emit('changeMode', 'tag', [])
}
},
addParams (params) {
Object.keys(params).forEach(key => {
const column = this.columnList.find(column => {
return column.name === key
})
let current = this.codeMirror.getValue()
current = `${key}=${(column.type === columnType.string ? stringInQuot(params[key]) : params[key])} ${current ? 'AND' : ''}`
toRaw(this.codeMirror).setValue(current)
})
}
},
watch: {
sql: {
immediate: true,
handler (n) {
if (n) {
setTimeout(() => {
toRaw(this.codeMirror).setValue(n)
})
}
}
}
},
mounted () {

View File

@@ -4,7 +4,9 @@ export const condition = 'condition'
export const columnType = {
fullText: 'fullText',
string: 'string',
long: 'long'
long: 'long',
number: 'number',
array: 'array'
}
export const defaultOperatorList = ['=', '!=', '>', '<', '>=', '<=', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE']
export const defaultConnectionList = [