|
|
|
@ -1,13 +1,13 @@
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import { favorite, getConditionList, unfavorite } from '@/api/home/filter'
|
|
|
|
|
import { asideMap } from '@/config/aside'
|
|
|
|
|
import { useInfiniteScroll } from '@vueuse/core'
|
|
|
|
|
import { debounce } from 'lodash-es'
|
|
|
|
|
import { onMounted, reactive, ref } from 'vue'
|
|
|
|
|
import type { FilterSearchParam } from '/#/api'
|
|
|
|
|
import type { Filter, FilterEntity } from '/#/home'
|
|
|
|
|
import { favorite, getConditionList, unfavorite } from "@/api/home/filter";
|
|
|
|
|
import { asideMap } from "@/config/aside";
|
|
|
|
|
import { useInfiniteScroll } from "@vueuse/core";
|
|
|
|
|
import { debounce } from "lodash-es";
|
|
|
|
|
import { onMounted, reactive, ref,watch } from "vue";
|
|
|
|
|
import type { FilterSearchParam } from "/#/api";
|
|
|
|
|
import type { Filter, FilterEntity } from "/#/home";
|
|
|
|
|
|
|
|
|
|
defineOptions({ name: 'AdvanceFilter' })
|
|
|
|
|
defineOptions({ name: "AdvanceFilter" });
|
|
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
type: {
|
|
|
|
@ -15,109 +15,115 @@ const props = defineProps({
|
|
|
|
|
default: 0,
|
|
|
|
|
required: true,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
(e: 'show-filter'): void
|
|
|
|
|
(e: 'show-custom'): void
|
|
|
|
|
(e: 'update:search'): void
|
|
|
|
|
(e: 'select', id: string)
|
|
|
|
|
}>()
|
|
|
|
|
|
|
|
|
|
const data = ref<FilterEntity[]>([])
|
|
|
|
|
let loading = false
|
|
|
|
|
const canloadMore = true
|
|
|
|
|
const el = ref<HTMLDivElement | null>(null)
|
|
|
|
|
const popover = ref<ComponentRef | null>(null)
|
|
|
|
|
(e: "show-filter"): void;
|
|
|
|
|
(e: "show-custom"): void;
|
|
|
|
|
(e: "update:search"): void;
|
|
|
|
|
(e: "select", id: string);
|
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
const data = ref<FilterEntity[]>([]);
|
|
|
|
|
let loading = false;
|
|
|
|
|
const canloadMore = true;
|
|
|
|
|
const el = ref<HTMLDivElement | null>(null);
|
|
|
|
|
const popover = ref<ComponentRef | null>(null);
|
|
|
|
|
const pagination = reactive({
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
pageSize: 300,
|
|
|
|
|
})
|
|
|
|
|
const keyword = ref('')
|
|
|
|
|
});
|
|
|
|
|
const keyword = ref("");
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
// data.value = generateDefaultConfig()
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 默认的过滤配置
|
|
|
|
|
function generateDefaultConfig(): FilterEntity[] {
|
|
|
|
|
return Object.keys(asideMap).reduce((acc, key) => {
|
|
|
|
|
const { label, defaultValue, isDefaultFilter } = asideMap[key]
|
|
|
|
|
const { label, defaultValue, isDefaultFilter } = asideMap[key];
|
|
|
|
|
|
|
|
|
|
if (isDefaultFilter === true) {
|
|
|
|
|
const config = {
|
|
|
|
|
id: '',
|
|
|
|
|
id: "",
|
|
|
|
|
name: label,
|
|
|
|
|
favorite: false,
|
|
|
|
|
isDefaultFilter,
|
|
|
|
|
filterList: [{
|
|
|
|
|
filterList: [
|
|
|
|
|
{
|
|
|
|
|
key,
|
|
|
|
|
value: defaultValue,
|
|
|
|
|
}],
|
|
|
|
|
}
|
|
|
|
|
return [...acc, config]
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return acc
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
return [...acc, config];
|
|
|
|
|
} else {
|
|
|
|
|
return acc;
|
|
|
|
|
}
|
|
|
|
|
}, [])
|
|
|
|
|
}, []);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
useInfiniteScroll(
|
|
|
|
|
el as any,
|
|
|
|
|
() => {
|
|
|
|
|
loadMore()
|
|
|
|
|
loadMore();
|
|
|
|
|
},
|
|
|
|
|
{ distance: 10, interval: 300, canLoadMore: () => false },
|
|
|
|
|
)
|
|
|
|
|
{ distance: 10, interval: 300, canLoadMore: () => false }
|
|
|
|
|
);
|
|
|
|
|
const showClick = ()=>{
|
|
|
|
|
console.log('showClick')
|
|
|
|
|
inputHandler('')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function loadMore() {
|
|
|
|
|
if (loading || el.value == null)
|
|
|
|
|
return
|
|
|
|
|
if (loading || el.value == null) return;
|
|
|
|
|
|
|
|
|
|
const more = await featchList()
|
|
|
|
|
const more = await featchList();
|
|
|
|
|
|
|
|
|
|
if (more.length === 0)
|
|
|
|
|
return
|
|
|
|
|
if (more.length === 0) return;
|
|
|
|
|
|
|
|
|
|
data.value.push(...more)
|
|
|
|
|
data.value.push(...more);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function featchList() {
|
|
|
|
|
loading = true
|
|
|
|
|
loading = true;
|
|
|
|
|
try {
|
|
|
|
|
const searchParam: FilterSearchParam = { search_searchname: { value: keyword.value, op: 'like', type: 'string' } }
|
|
|
|
|
const result = await getConditionList(pagination, searchParam, props.type)
|
|
|
|
|
const { data } = result
|
|
|
|
|
const searchParam: FilterSearchParam = {
|
|
|
|
|
search_searchname: { value: keyword.value, op: "like", type: "string" },
|
|
|
|
|
};
|
|
|
|
|
const result = await getConditionList(pagination, searchParam, props.type);
|
|
|
|
|
const { data } = result;
|
|
|
|
|
// pagination.pageNo += 1
|
|
|
|
|
// canloadMore = pageCount >= pagination.pageNo
|
|
|
|
|
const entityList = generateFilterEntityList(data)
|
|
|
|
|
return entityList
|
|
|
|
|
}
|
|
|
|
|
catch (error) {
|
|
|
|
|
return []
|
|
|
|
|
}
|
|
|
|
|
finally {
|
|
|
|
|
loading = false
|
|
|
|
|
const entityList = generateFilterEntityList(data);
|
|
|
|
|
return entityList;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return [];
|
|
|
|
|
} finally {
|
|
|
|
|
loading = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 转换服务器数据格式
|
|
|
|
|
function generateFilterEntityList(data) {
|
|
|
|
|
const filterEntityList = data.map((item) => {
|
|
|
|
|
const { searchname, iztop, ocrUsersearchchildList, id } = item
|
|
|
|
|
const { searchname, iztop, ocrUsersearchchildList, id } = item;
|
|
|
|
|
|
|
|
|
|
const list = ocrUsersearchchildList.map((item) => {
|
|
|
|
|
const { searchfield, searchvalue } = item
|
|
|
|
|
const { searchfield, searchvalue } = item;
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
key: searchfield,
|
|
|
|
|
value: searchvalue,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const reg = new RegExp(keyword.value, 'gi')
|
|
|
|
|
const hilightText = searchname.replace(reg, `<span style='color:#FF0000'>${keyword.value}</span>`)
|
|
|
|
|
const reg = new RegExp(keyword.value, "gi");
|
|
|
|
|
const hilightText = searchname.replace(
|
|
|
|
|
reg,
|
|
|
|
|
`<span style='color:#FF0000'>${keyword.value}</span>`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
id,
|
|
|
|
@ -125,45 +131,45 @@ function generateFilterEntityList(data) {
|
|
|
|
|
favorite: iztop,
|
|
|
|
|
isDefaultFilter: false,
|
|
|
|
|
filterList: list,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return filterEntityList
|
|
|
|
|
return filterEntityList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function selectHandler(item: FilterEntity) {
|
|
|
|
|
(popover.value as any).setShow(false)
|
|
|
|
|
emit('select', item.id)
|
|
|
|
|
(popover.value as any).setShow(false);
|
|
|
|
|
emit("select", item.id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const inputHandler = debounce((word) => {
|
|
|
|
|
keyword.value = word
|
|
|
|
|
keyword.value = word;
|
|
|
|
|
featchList().then((list) => {
|
|
|
|
|
data.value = list
|
|
|
|
|
})
|
|
|
|
|
}, 300)
|
|
|
|
|
data.value = list;
|
|
|
|
|
});
|
|
|
|
|
}, 300);
|
|
|
|
|
|
|
|
|
|
function favoriteHandler(event: MouseEvent, item: any) {
|
|
|
|
|
event.stopImmediatePropagation()
|
|
|
|
|
event.stopPropagation()
|
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
|
|
|
|
const { isDefaultFilter, id } = item
|
|
|
|
|
const { isDefaultFilter, id } = item;
|
|
|
|
|
|
|
|
|
|
if (!isDefaultFilter) {
|
|
|
|
|
item.favorite = true
|
|
|
|
|
favorite(id)
|
|
|
|
|
item.favorite = true;
|
|
|
|
|
favorite(id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function unFavoriteHandler(event: MouseEvent, item) {
|
|
|
|
|
event.stopImmediatePropagation()
|
|
|
|
|
event.stopPropagation()
|
|
|
|
|
event.stopImmediatePropagation();
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
|
|
|
|
const { isDefaultFilter, id } = item
|
|
|
|
|
const { isDefaultFilter, id } = item;
|
|
|
|
|
|
|
|
|
|
if (!isDefaultFilter) {
|
|
|
|
|
item.favorite = false
|
|
|
|
|
unfavorite(id)
|
|
|
|
|
item.favorite = false;
|
|
|
|
|
unfavorite(id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
@ -173,29 +179,58 @@ function unFavoriteHandler(event: MouseEvent, item) {
|
|
|
|
|
<div class="wrapper-left">
|
|
|
|
|
<svg-icon name="shield" size="32" />
|
|
|
|
|
<n-popover
|
|
|
|
|
ref="popover" :style="{ padding: '0px' }" style="width: 248px" :show-arrow="false"
|
|
|
|
|
placement="bottom-start" trigger="click"
|
|
|
|
|
ref="popover"
|
|
|
|
|
:style="{ padding: '0px' }"
|
|
|
|
|
style="width: 248px"
|
|
|
|
|
:show-arrow="false"
|
|
|
|
|
placement="bottom-start"
|
|
|
|
|
trigger="click"
|
|
|
|
|
>
|
|
|
|
|
<template #trigger>
|
|
|
|
|
<div class="wrapper-left-dropdown">
|
|
|
|
|
<div class="wrapper-left-dropdown" @click="showClick">
|
|
|
|
|
<span>高级筛选</span>
|
|
|
|
|
<SvgIcon :style="{ marginLeft: '5px' }" name="down" size="14" />
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<n-spin :show="loading">
|
|
|
|
|
<div class="wrapper-left-popover">
|
|
|
|
|
<n-input :style="{ '--n-border': '0px' }" placeholder="请输入关键字" @input="inputHandler">
|
|
|
|
|
<n-input
|
|
|
|
|
:style="{ '--n-border': '0px' }"
|
|
|
|
|
placeholder="请输入关键字"
|
|
|
|
|
@input="inputHandler"
|
|
|
|
|
>
|
|
|
|
|
<template #prefix>
|
|
|
|
|
<SvgIcon size="14px" name="magnifying-1" />
|
|
|
|
|
</template>
|
|
|
|
|
<template #suffix>
|
|
|
|
|
<SvgIcon size="14px" style="cursor: pointer;" name="setting" @click="emit('show-filter')" />
|
|
|
|
|
<SvgIcon
|
|
|
|
|
size="14px"
|
|
|
|
|
style="cursor: pointer"
|
|
|
|
|
name="setting"
|
|
|
|
|
@click="emit('show-filter')"
|
|
|
|
|
/>
|
|
|
|
|
</template>
|
|
|
|
|
</n-input>
|
|
|
|
|
<ul ref="el" class="wrapper-left-list">
|
|
|
|
|
<li v-for="(item, index) in data" :key="index" style="display: flex;align-items: center;" @click="selectHandler(item)">
|
|
|
|
|
<SvgIcon v-if="item.favorite && !item.isDefaultFilter" name="favorite-fill" color="#fd9b0a" size="18" @click="unFavoriteHandler($event, item)" />
|
|
|
|
|
<SvgIcon v-else-if="!item.favorite && !item.isDefaultFilter" name="favorite-unfill" size="18" @click="favoriteHandler($event, item)" />
|
|
|
|
|
<li
|
|
|
|
|
v-for="(item, index) in data"
|
|
|
|
|
:key="index"
|
|
|
|
|
style="display: flex; align-items: center"
|
|
|
|
|
@click="selectHandler(item)"
|
|
|
|
|
>
|
|
|
|
|
<SvgIcon
|
|
|
|
|
v-if="item.favorite && !item.isDefaultFilter"
|
|
|
|
|
name="favorite-fill"
|
|
|
|
|
color="#fd9b0a"
|
|
|
|
|
size="18"
|
|
|
|
|
@click="unFavoriteHandler($event, item)"
|
|
|
|
|
/>
|
|
|
|
|
<SvgIcon
|
|
|
|
|
v-else-if="!item.favorite && !item.isDefaultFilter"
|
|
|
|
|
name="favorite-unfill"
|
|
|
|
|
size="18"
|
|
|
|
|
@click="favoriteHandler($event, item)"
|
|
|
|
|
/>
|
|
|
|
|
<div v-html="item.name" />
|
|
|
|
|
</li>
|
|
|
|
|
</ul>
|
|
|
|
@ -204,8 +239,18 @@ function unFavoriteHandler(event: MouseEvent, item) {
|
|
|
|
|
</n-popover>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="wrapper-right">
|
|
|
|
|
<SvgIcon style="display: block;cursor: pointer;" size="18" name="magnifying-1" @click="emit('update:search')" />
|
|
|
|
|
<SvgIcon style="display: block;cursor: pointer;margin-left: 10px;" size="18" name="filter" @click="emit('show-custom')" />
|
|
|
|
|
<SvgIcon
|
|
|
|
|
style="display: block; cursor: pointer"
|
|
|
|
|
size="18"
|
|
|
|
|
name="magnifying-1"
|
|
|
|
|
@click="emit('update:search')"
|
|
|
|
|
/>
|
|
|
|
|
<SvgIcon
|
|
|
|
|
style="display: block; cursor: pointer; margin-left: 10px"
|
|
|
|
|
size="18"
|
|
|
|
|
name="filter"
|
|
|
|
|
@click="emit('show-custom')"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
@ -243,7 +288,7 @@ function unFavoriteHandler(event: MouseEvent, item) {
|
|
|
|
|
scrollbar-width: none; /* firefox */
|
|
|
|
|
-ms-overflow-style: none; /* IE 10+ */
|
|
|
|
|
|
|
|
|
|
&::-webkit-scrollbar{
|
|
|
|
|
&::-webkit-scrollbar {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|