You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ocr-web/src/views/home/aside/Aside.vue

304 lines
9.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script lang="ts" setup>
import { computed, inject, nextTick, onBeforeMount, onMounted, reactive, ref, shallowRef, unref, watch } from 'vue'
import { CustomFilterModalVue, FilterModalVue, NewFilterModalVue } from './comp/modals'
import Search from './comp/Search.vue'
import AdvanceFilter from './comp/AdvanceFilter.vue'
import { getViewportOffset } from '@/utils/domUtils'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { useConfig } from '@/store/modules/asideConfig'
import type { Filter } from '/#/home'
import type { AsideEntity } from '@/config/aside'
import { asideMap } from '@/config/aside'
import type { AsideConfig } from '/#/api'
import emitter from '@/utils/mitt'
import { getFilterList } from '@/api/home/main'
import dayjs from 'dayjs'
const configStore = useConfig()
// 所有左侧模块的值
const asideValue: Record<keyof typeof asideMap, any> = reactive({})
// 左侧某个模块是否显示: 显示需同时满足系统配置和个人配置
const asideVisible: Partial<Record<keyof AsideConfig, boolean>> = reactive({})
// 当前显示的模块,按照数组顺序显示
const showItems = shallowRef<{ key: string, config: AsideEntity }[]>([])
Object.keys(asideMap).forEach((key) => {
const entity = asideMap[key]
const { defaultValue } = entity
asideValue[key] = defaultValue
})
const filterModalRef = ref(null)
const newFilterModalRef = ref(null)
const customModalRef = ref(null)
const customObjRef = ref<any>(null) // 获取高级筛选获取的值
function showModal(modalRef: any) {
const modal = unref(modalRef)! as any
modal.showModal()
}
onMounted(() => {
nextTick(() => {
computeSlideHeight()
})
})
const collapse = ref(false)
const mousetrap = inject('mousetrap') as any
mousetrap.bind('[', collapseHandler)
function collapseHandler() {
collapse.value = !collapse.value
}
const asideWidth = computed(() => {
return collapse.value ? 0 : 308
})
const asideHeight = ref(500)
const asideStyle = computed(() => {
return {
width: `${asideWidth.value}px`,
height: `${asideHeight.value}px`,
}
})
const collapseIcon = computed(() => {
return collapse.value ? 'expand-cir' : 'collapse-cir'
})
function computeSlideHeight() {
const headEl = document.querySelector('.aside-header')!
const { bottomIncludeBody } = getViewportOffset(headEl)
const height = bottomIncludeBody
asideHeight.value = height - 24
}
useWindowSizeFn(computeSlideHeight, 280)
onBeforeMount(async () => {
configStore.fetchConfig()
configStore.fetchCustomConfig()
})
configStore.$subscribe(() => {
const config = configStore.getConfig
const customConfig = configStore.getCustomConfig
if (config == null || customConfig == null)
return
// console.log("config", config, "customConfig", customConfig);
/* rao
const showKeys = [...customConfig].filter(key => !asideMap[key].isDefaultFilter)// 获取customConfig 非isDefaultFilter的选项
const defaultKeys = Object.keys(asideMap).filter(key => asideMap[key].isDefaultFilter)// 获取asideMap isDefaultFilter的选项
showKeys.unshift(...defaultKeys)
*/
const showKeys = [...customConfig];
Object.keys(config).forEach((key) => {
if (key.startsWith('iz') && asideMap[key] !== undefined)
asideVisible[key] = (showKeys.includes(key) || asideMap[key].isDefaultFilter) && config[key] === 'Y'
})
if(customObjRef.value) {// 赋值
Object.keys(customObjRef.value).map(key => {
if(asideMap.hasOwnProperty(key)) {
const str = key.toLowerCase()
console.log("customObjRef.value[str]1111111111111", customObjRef.value[str]);
if(str == "izsimilarity" && typeof customObjRef.value[str] == "string") {
customObjRef.value[str] = customObjRef.value[str].split(',');
asideValue[key] = customObjRef.value[str];// 赋值
}else if(str == "izyear" && typeof customObjRef.value[str] == "string") {
let time = customObjRef.value[str].split('-');
time[0] = (new Date(time[0])).getTime();
time[1] = (new Date(time[1])).getTime();
customObjRef.value[str] = time;
asideValue[key] = customObjRef.value[str];// 赋值
console.log("时间2222222222", customObjRef.value[str]);
}else if((str != 'izsimilarity' && str != "izyear") && customObjRef.value[str]) {
console.log("customObjRef.value[str]222222", customObjRef.value[str]);
let list = customObjRef.value[str].split(',');
console.log("list222222", list);
asideValue[key] = customObjRef.value[str];// 赋值
}else {
asideValue[key] = "";
}
// asideMap[str].defaultValue = customObjRef.value[str];// 赋值
}
});
}
// console.log("showKeys", showKeys);
const items = showKeys.reduce((acc, key) => {
const { render } = asideMap[key]
if (render !== false) {
const str = key.toLowerCase()
const o = {
key: str,
config: asideMap[str],
}
return [...acc, o]
}
else {
return acc
}
}, [])
console.log("items", items);
showItems.value = items
})
const asideEnter = ref(false)
const showCollapse = computed(() => {
return collapse.value ? true : asideEnter.value
})
const showSearch = ref(false)
function setShowSearch(value: boolean) {
showSearch.value = value
}
// 滚动容器让key对应模块处于可视区域
function scrollHandler(key: string) {
const element = document.querySelector(`#${key}`)
element?.scrollIntoView(true)
}
// 选择某个过滤配置,刷新图片墙 -> 筛选搜索条件
async function filterHandler(searchId: string) {
// emitter.emit('filter', searchId)
const res = await getFilterList({userSearchId: searchId});
// console.log("顾虑结果", res);
if(res.code == "OK") {
let obj = res.data;
customObjRef.value = res.data;
let showKeys: any[] = [];
Object.keys(obj).map(key => {
if(asideMap.hasOwnProperty(key)) {
showKeys.push(key);
}
});
// console.log(showKeys);
configStore.setCustomConfig(showKeys);
}
}
function editFilter(filter: any) {
const modal = unref(newFilterModalRef)! as any
modal.showModal()
modal.edit(filter)
}
watch(asideValue, (newVal) => {
console.log("asideValue处理后", newVal);
configStore.setAsideValue(newVal)
}, { deep: true })
</script>
<template>
<div class="aside" :style="asideStyle" @mouseenter="asideEnter = true" @mouseleave="asideEnter = false">
<div v-show="showCollapse" class="aside-collapse">
<div class="aside-collapse-btn" @click="collapseHandler">
<SvgIcon :name="collapseIcon" size="40" />
</div>
</div>
<n-scrollbar trigger="none">
<div class="aside-header">
<!-- -->
<Search v-show="showSearch" @select="scrollHandler" @close="setShowSearch(false)" />
<!-- 高级筛选 -->
<AdvanceFilter
v-show="!showSearch" :type="0" @select="filterHandler" @update:search="setShowSearch(true)"
@show-custom="showModal(customModalRef)" @show-filter="showModal(filterModalRef)"
/>
</div>
<component
:is="item.config.component" v-for="(item, index) in showItems" :id="item.key" :key="index" v-model:value="asideValue[item.key]"
:label="item.config.label"
/>
<!-- 过滤列表 -->
<FilterModalVue ref="filterModalRef" @edit-filter="editFilter" @show-new-filter="showModal(newFilterModalRef)" />
<!-- 新增过滤 -->
<NewFilterModalVue ref="newFilterModalRef" />
<!-- 筛选 -->
<CustomFilterModalVue ref="customModalRef" />
</n-scrollbar>
</div>
</template>
<style lang="less" scoped>
.aside {
display: flex;
position: relative;
flex-direction: column;
background: #FFF;
border: 1px solid #efeff5;
border-radius: 3px;
box-sizing: border-box;
&-header {
padding: 10px;
width: 100%;
border-bottom: 1px solid #e8e8e8;
margin-bottom: 15px;
}
&-divider {
width: 100%;
height: 1px;
background-color: #e8e8e8;
}
&-collapse {
width: 2px;
height: 100%;
background: #507afd;
position: absolute;
right: 0;
top: 0;
z-index: 18;
}
&-collapse-btn {
position: absolute;
cursor: pointer;
width: 40px;
height: 40px;
top: calc(15%);
right: -20px;
}
::v-deep(.n-collapse .n-collapse-item.n-collapse-item--right-arrow-placement .n-collapse-item__header .n-collapse-item-arrow) {
margin-left: 8px;
}
::v-deep(.n-collapse .n-collapse-item .n-collapse-item__header .n-collapse-item__header-main) {
font-weight: bold;
justify-content: space-between;
}
::v-deep(.n-collapse .n-collapse-item .n-collapse-item__header) {
padding: 0px;
}
::v-deep(.n-collapse .n-collapse-item:not(:first-child)) {
border-top: 0px;
}
::v-deep(.n-collapse .n-collapse-item .n-collapse-item__content-wrapper .n-collapse-item__content-inner) {
padding-top: 10px;
}
::v-deep(.n-scrollbar > .n-scrollbar-rail.n-scrollbar-rail--vertical > .n-scrollbar-rail__scrollbar, .n-scrollbar + .n-scrollbar-rail.n-scrollbar-rail--vertical > .n-scrollbar-rail__scrollbar) {
width: 0px;
}
}
</style>