增加查询过滤器及通知消息弹窗图标

This commit is contained in:
YUN-PC5\user 2023-11-24 16:29:50 +08:00
parent 195ebe2b73
commit ac25a1ffda
2 changed files with 220 additions and 0 deletions

View File

@ -0,0 +1,211 @@
<template>
<div>
<el-form inline>
<el-form-item class="search-form-item" :label="currFilter.label" v-for="(currFilter, index) in currFilters" :key="index">
<template #label>
<div class="search-form-item-label-wrapper">
<span class="search-form-item-label">{{ currFilter.label }}</span>
<el-icon class="search-form-item-remove-btn" @click="remove(index)">
<CircleClose />
</el-icon>
</div>
</template>
<!-- 单选 -->
<el-select v-if="currFilter.type === 'singleSelect'" v-model="currFilter.value" placeholder="请选择" filterable clearable>
<el-option v-for="item in currFilter.options" :key="item.value" :label="item.label" :value="item.value">
<span class="text-left">
{{ item.label }}
</span>
<span class="text-right">
{{ item.name }}
</span>
</el-option>
</el-select>
<!-- 多选 -->
<el-select
v-else-if="currFilter.type === 'multipleSelect'"
v-model="currFilter.value"
placeholder="请选择"
multiple
collapse-tags
filterable
clearable>
<el-option v-for="item in currFilter.options" :key="item.value" :label="item.label" :value="item.value">
<span class="text-left">
{{ item.label }}
</span>
<span class="text-right">
{{ item.name }}
</span>
</el-option>
</el-select>
<!-- 日期 -->
<el-date-picker
v-else-if="currFilter.type === ('date' || 'daterange')"
:type="currFilter.type"
v-model="currFilter.value"
start-placeholder="开始日期"
end-placeholder="结束日期" />
<!-- 数字 -->
<el-input-number v-else-if="currFilter.type === 'number'" v-model="currFilter.value" />
<!-- 文本 -->
<el-input v-else v-model="currFilter.value" placeholder="请输入" clearable />
</el-form-item>
<el-form-item class="add-condition-wrapper">
<template v-if="currFilters.length !== searchableItems.length">
<div v-if="showHeadSelect">
<el-select
ref="tableHeaderSelect"
v-model="conditionValue"
placeholder="请选择筛选条件"
@change="selectFilterItem"
@visible-change="(val) => (showHeadSelect = val)">
<el-option
v-for="item in searchableItems"
:key="item.key"
:label="item.label"
:value="item.key"
:disabled="!!currFilters.find((c) => c.key === item.key)" />
</el-select>
</div>
<template v-else>
<div @click="handleAddCondition" class="dashed-wrapper">
<el-icon>
<Plus />
</el-icon>
添加筛选条件
</div>
</template>
</template>
<el-button plain type="success" style="margin-left: 15px" @click="handleSearch()">搜索</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup name="AdvancedFilter" lang="ts">
import type { PropType } from 'vue'
interface searchableItemOption {
label: string
value: string
name?: string
}
export interface searchableItem {
//
type: 'string' | 'number' | 'date' | 'singleSelect' | 'multipleSelect' | 'daterange'
//
label: string
//
key: string | Array<string>
//
value?: any
//
options?: searchableItemOption[]
}
const props = defineProps({
searchableItems: {
type: Array as PropType<searchableItem[]>,
default: () => [],
require: true
}
})
const emit = defineEmits()
const tableHeaderSelect = ref()
const showHeadSelect = ref(false)
const currFilters = ref<searchableItem[]>([])
const conditionValue = ref()
//
function handleAddCondition() {
showHeadSelect.value = true
nextTick(() => {
tableHeaderSelect.value.toggleMenu()
})
}
//
function selectFilterItem(val) {
const item: searchableItem | undefined = props.searchableItems.find((v) => v.key === val)
if (item) {
item.value = null //
currFilters.value.push(item)
}
conditionValue.value = null //
showHeadSelect.value = false
}
//
function remove(index) {
currFilters.value.splice(index, 1)
}
//
function handleSearch() {
let params = {}
currFilters.value.map((v) => {
if (Array.isArray(v.key)) {
//
params[v.key[0]] = v.value[0]
params[v.key[1]] = v.value[1]
} else {
params[v.key] = v.value
}
})
emit('query', params)
}
function initFilterValue() {
currFilters.value = []
props.searchableItems.map((v) => {
if (v.value) {
currFilters.value.push(v)
}
})
}
onMounted(() => {
initFilterValue()
})
defineExpose({
handleSearch
})
</script>
<style lang="scss" scoped>
.dashed-wrapper {
border: 1px dashed #ccc;
border-radius: 4px;
display: inline-block;
color: var(--el-text-color-placeholder);
width: 220px;
height: 33px;
text-align: center;
cursor: pointer;
&:hover {
background-color: rgba(222, 222, 222, 0.2);
}
}
.search-form-item-label-wrapper {
position: relative;
cursor: pointer;
.search-form-item-label {
margin-right: 10px;
}
.search-form-item-remove-btn {
position: absolute;
top: 5px;
right: 0;
margin-right: -5px;
margin-top: -5px;
font-size: 16px;
color: var(--el-text-color-placeholder);
display: none;
&:hover {
color: var(--el-color-danger);
}
&:active {
transform: scale(0.8);
}
}
}
.search-form-item {
&:hover .search-form-item-remove-btn {
display: inline-block;
}
}
.add-condition-wrapper {
min-width: 340px;
}
</style>

View File

@ -0,0 +1,9 @@
<template>
<div>
<el-icon color="#409EFC"><Bell /></el-icon>
</div>
</template>
<script setup lang="ts"></script>
<style scoped></style>