增加查询过滤器及通知消息弹窗图标
This commit is contained in:
parent
195ebe2b73
commit
ac25a1ffda
211
src/components/AdvancedFilter/index.vue
Normal file
211
src/components/AdvancedFilter/index.vue
Normal 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>
|
||||||
9
src/components/Notice/bellIcon/index.vue
Normal file
9
src/components/Notice/bellIcon/index.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-icon color="#409EFC"><Bell /></el-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
Loading…
x
Reference in New Issue
Block a user