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

423 lines
12 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 dayjs from 'dayjs'
import { cloneDeep, isEqual } from 'lodash-es'
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'
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: any = ref(null)
const newFilterModalRef = ref(null)
const customModalRef = ref(null)
const customObjRef = ref<any>(null) // 获取高级筛选获取的值
const customTempObjRef = ref<any>(null) // 获取高级筛选获取的值(作对比)
const configFilterRef = ref<any>([]) // 获取排序的值
const AdvanceFilterRef: any = ref(null)
function showModal(modalRef: any) {
const modal = unref(modalRef)! as any
modal.showModal()
}
onMounted(() => {
nextTick(() => {
computeSlideHeight()
const tempAsideValue = cloneDeep(asideValue)
// configStore.setAsideValue(tempAsideValue);
console.log('asideMap和asideValue', tempAsideValue)
})
})
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 (
configFilterRef.value.length > 0
&& isEqual(configFilterRef.value, configStore.getFilterConfig)
&& customObjRef.value
&& isEqual(customObjRef.value, customTempObjRef.value)
)
return
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 sortKeyList: any = []
console.log('init')
configStore.getFilterConfig.map((item: any) => {
console.log(item)
console.log('item')
sortKeyList.push(item.id)
})
const showKeys = [...sortKeyList]
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') {
if (typeof customObjRef.value[str] == 'string')
customObjRef.value[str] = customObjRef.value[str].split(',')
asideValue[key] = customObjRef.value[str] // 赋值
console.log('相似度2222222222', asideValue[key])
}
else if (str == 'izyear') {
if (typeof customObjRef.value[str] == 'string') {
const 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', asideValue[key])
}
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] = null
}
// asideMap[str].defaultValue = customObjRef.value[str];// 赋值
}
})
customTempObjRef.value = customObjRef.value
console.log('asideValue直接处理后的结果', asideValue)
console.log('customTempObjRef.value', customTempObjRef.value)
const tempobj = cloneDeep(asideValue)
console.log('tempObj', tempobj)
configStore.setAsideValue(tempobj)
}
// 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('showItems=================================', items)
showItems.value = items
configFilterRef.value = configStore.getFilterConfig
})
const asideEnter = ref(false)
const showCollapse = computed(() => {
return collapse.value ? true : asideEnter.value
})
const showSearch = ref(false)
function setShowSearch(value: boolean) {
showSearch.value = value
}
function newFilterOk() {
filterModalRef.value.query(
filterModalRef.value.pagination.page,
filterModalRef.value.pagination.pageSize,
)
}
// 滚动容器让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') {
const obj = res.data
customObjRef.value = res.data
const 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)
}
function updateComponent(key, e) {
console.log('跟新值', key, e)
console.log('tempAsideValue跟新值', configStore.getAsideValue, asideValue)
// let tempAsideValue = configStore.getAsideValue || asideValue;
const tempobj = cloneDeep(asideValue)
console.log(tempobj, 'tempobj')
tempobj[key] = e
console.log(tempobj, 'tempobj After')
customObjRef.value = tempobj
// asideValue = Object.assign({}, asideValue, tempobj);
console.log('asideValue跟新值', tempobj)
configStore.setAsideValue(tempobj)
}
function handleOk(item: any) {
console.log('handleOk', item)
if (item) {
AdvanceFilterRef.value.setCurrentlySelectedAdvanced(item.searchname)
filterHandler(item.id)
}
else {
AdvanceFilterRef.value.setCurrentlySelectedAdvanced('高级筛选')
filterHandler('')
}
}
// 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"
ref="AdvanceFilterRef"
: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="item.key"
v-model:value="asideValue[item.key]"
:label="item.config.label"
@update:value="(e) => updateComponent(item.key, e)"
/>
<!-- 过滤列表 -->
<FilterModalVue
ref="filterModalRef"
@edit-filter="editFilter"
@show-new-filter="showModal(newFilterModalRef)"
@handle-ok="handleOk"
/>
<!-- 新增过滤 -->
<NewFilterModalVue ref="newFilterModalRef" @on-ok="newFilterOk" />
<!-- 筛选 -->
<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>