feat: 搜索历史
This commit is contained in:
@@ -35,14 +35,21 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
overflow: auto hidden;
|
||||||
border: 1px solid #CECECE;
|
border: 1px solid #CECECE;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 80px;
|
padding-right: 80px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.tag-search__meta, .tag-search__add {
|
.tag-search__meta, .tag-search__add {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-search__add {
|
.tag-search__add {
|
||||||
|
|||||||
@@ -160,12 +160,15 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
|
|||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: white;
|
background: white;
|
||||||
|
width: 100%;
|
||||||
|
padding-right: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CodeMirror-scroll {
|
.CodeMirror-scroll {
|
||||||
// overflow: scroll !important; /* Things will break if this is overridden */
|
// overflow: scroll !important; /* Things will break if this is overridden */
|
||||||
/* 50px is the magic margin used to hide the element's real scrollbars */
|
/* 50px is the magic margin used to hide the element's real scrollbars */
|
||||||
/* See overflow: hidden in .CodeMirror */
|
/* See overflow: hidden in .CodeMirror */
|
||||||
|
overflow: hidden;
|
||||||
margin-bottom: -50px; margin-right: -50px;
|
margin-bottom: -50px; margin-right: -50px;
|
||||||
padding-bottom: 50px;
|
padding-bottom: 50px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
padding-top: 18px;
|
padding-top: 18px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
|
position: relative;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
@@ -64,9 +65,68 @@
|
|||||||
background-color: #3976CB;
|
background-color: #3976CB;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
i, span {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
transition: all linear .1s;
|
||||||
|
transform: rotate(0) translate(0, 0);
|
||||||
|
}
|
||||||
|
i.arrow-rotate {
|
||||||
|
transform: rotate(90deg) translate(2px, 3px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search__history {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
padding: 10px 0;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1000px;
|
||||||
|
top: 47px;
|
||||||
|
border: 1px solid rgba(206,206,206,0.20);
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
.history__item {
|
||||||
|
height: 35px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 30px;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
&.clear-all span {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.item-date {
|
||||||
|
color: #bbb;
|
||||||
|
padding: 0 20px 0 0;
|
||||||
|
}
|
||||||
|
.item-value {
|
||||||
|
flex-basis: calc(100% - 200px);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
word-break: break-all;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.history__item:not(.clear-all) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.history__item:hover:not(.clear-all) {
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
color: #66b1ff;
|
||||||
|
}
|
||||||
|
.history__item.clear-all {
|
||||||
|
color: #3976CB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import TextMode from '@/components/advancedSearch/TextMode'
|
|||||||
import { defaultOperatorList, defaultConnectionList } from '@/components/advancedSearch/meta/meta'
|
import { defaultOperatorList, defaultConnectionList } from '@/components/advancedSearch/meta/meta'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import SqlParser from "@/components/advancedSearch/meta/sql-parser";
|
||||||
export default {
|
export default {
|
||||||
name: 'Index',
|
name: 'Index',
|
||||||
components: {
|
components: {
|
||||||
@@ -74,6 +75,18 @@ export default {
|
|||||||
addParams (params) {
|
addParams (params) {
|
||||||
this.$refs.tagMode && this.$refs.tagMode.addParams(params)
|
this.$refs.tagMode && this.$refs.tagMode.addParams(params)
|
||||||
this.$refs.textMode && this.$refs.textMode.addParams(params)
|
this.$refs.textMode && this.$refs.textMode.addParams(params)
|
||||||
|
},
|
||||||
|
setSql (sql) {
|
||||||
|
if (this.searchMode === 'text') {
|
||||||
|
this.sql = sql
|
||||||
|
} else if (this.searchMode === 'tag') {
|
||||||
|
const parser = new SqlParser(sql, this.columnList)
|
||||||
|
const errorList = parser.validate()
|
||||||
|
if (this.$_.isEmpty(errorList)) {
|
||||||
|
const { metaList } = parser.formatSql()
|
||||||
|
this.metaList = metaList
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup (props) {
|
setup (props) {
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ export const storageKey = {
|
|||||||
tableTitlePrefix: 'cn-table-title',
|
tableTitlePrefix: 'cn-table-title',
|
||||||
tablePageSizePrefix: 'cn-page-size',
|
tablePageSizePrefix: 'cn-page-size',
|
||||||
leftMenuShrink: 'cn-left-menu-shrink',
|
leftMenuShrink: 'cn-left-menu-shrink',
|
||||||
unsavedChange: 'cn-unsaved-change'
|
unsavedChange: 'cn-unsaved-change',
|
||||||
|
entitySearchHistory: 'cn-entity-search-history'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 统一定义跳转来源
|
// 统一定义跳转来源
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
<i class="cn-icon cn-icon-help"></i>
|
<i class="cn-icon cn-icon-help"></i>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="explorer-search__foot">
|
<div v-else class="explorer-search__foot">
|
||||||
<div class="foot__item">
|
<div class="foot__item" @click="triggerHistory">
|
||||||
<i class="el-icon-arrow-right" style="padding-right: 5px;"></i>
|
<i class="el-icon-arrow-right" :class="{ 'arrow-rotate': showHistory }" style="padding-right: 5px;"></i>
|
||||||
<span>{{$t('search.searchHistory')}}</span>
|
<span>{{$t('search.searchHistory')}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="foot__item">
|
<div class="foot__item">
|
||||||
@@ -26,6 +26,18 @@
|
|||||||
<el-divider direction="vertical"></el-divider>
|
<el-divider direction="vertical"></el-divider>
|
||||||
<span>{{$t('overall.help')}}</span>
|
<span>{{$t('overall.help')}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<transition name="el-zoom-in-top">
|
||||||
|
<div class="search__history" v-show="showHistory" v-ele-click-outside="esc">
|
||||||
|
<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 class="history__item clear-all">
|
||||||
|
<span @click="clearHistory" v-if="!$_.isEmpty(history)">{{$t('overall.clear')}}</span>
|
||||||
|
<div v-else>暂无记录</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,6 +47,7 @@
|
|||||||
import AdvancedSearch from '@/components/advancedSearch/Index'
|
import AdvancedSearch from '@/components/advancedSearch/Index'
|
||||||
import { columnType } from '@/components/advancedSearch/meta/meta'
|
import { columnType } from '@/components/advancedSearch/meta/meta'
|
||||||
import SqlParser from '@/components/advancedSearch/meta/sql-parser'
|
import SqlParser from '@/components/advancedSearch/meta/sql-parser'
|
||||||
|
import {storageKey} from "@/utils/constants";
|
||||||
export default {
|
export default {
|
||||||
name: 'CnSearch',
|
name: 'CnSearch',
|
||||||
components: {
|
components: {
|
||||||
@@ -175,7 +188,9 @@ export default {
|
|||||||
value: 'OR',
|
value: 'OR',
|
||||||
label: 'OR'
|
label: 'OR'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
showHistory: false,
|
||||||
|
history: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -192,9 +207,43 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.$emit('search', metaList, sql)
|
this.$emit('search', metaList, sql)
|
||||||
|
// 加入搜索记录
|
||||||
|
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]
|
||||||
|
} else {
|
||||||
|
arr.push(newItem)
|
||||||
|
}
|
||||||
|
localStorage.setItem(storageKey.entitySearchHistory, JSON.stringify(arr))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
addParams (params) {
|
addParams (params) {
|
||||||
this.$refs.search.addParams(params)
|
this.$refs.search.addParams(params)
|
||||||
|
},
|
||||||
|
selectHistory (sql) {
|
||||||
|
this.$refs.search.setSql(sql)
|
||||||
|
this.showHistory = false
|
||||||
|
},
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user