379 lines
11 KiB
Vue
379 lines
11 KiB
Vue
<template>
|
|
<div ref="tableHeader" class="cn-table-header">
|
|
<div class="table-header ba-scroll-style" :key="num">
|
|
<el-form
|
|
style="flex: 1; height: 34px; margin-right: 20px; display: flex; flex-wrap: wrap"
|
|
ref="headerForm"
|
|
@submit.prevent=""
|
|
@keyup.enter="onComSearch"
|
|
label-position="left"
|
|
:inline="true"
|
|
>
|
|
<el-form-item label="日期" v-if="datePicker" style="grid-column: span 2; max-width: 570px">
|
|
<DatePicker
|
|
ref="datePickerRef"
|
|
:nextFlag="nextFlag"
|
|
:theCurrentTime="theCurrentTime"
|
|
@change="handleDatePickerChange"
|
|
></DatePicker>
|
|
</el-form-item>
|
|
|
|
<el-form-item label="区域" v-if="area">
|
|
<Area ref="areaRef" v-model.trim="tableStore.table.params.deptIndex" />
|
|
</el-form-item>
|
|
<slot name="select"></slot>
|
|
</el-form>
|
|
<template v-if="$slots.select || datePicker || showSearch">
|
|
<el-button type="primary" @click="showSelectChange" v-if="showUnfoldButton">
|
|
<Icon size="14" name="el-icon-ArrowUp" style="color: #fff" v-if="showSelect" />
|
|
<Icon size="14" name="el-icon-ArrowDown" style="color: #fff" v-else />
|
|
</el-button>
|
|
<el-button @click="onComSearch" v-if="showSearch" type="primary" :icon="Search">查询</el-button>
|
|
<el-button @click="onResetForm" v-if="showSearch && showReset" :icon="RefreshLeft">重置</el-button>
|
|
<el-button
|
|
@click="onExport"
|
|
v-if="showExport"
|
|
:loading="tableStore.table.loading"
|
|
type="primary"
|
|
icon="el-icon-Download"
|
|
>
|
|
导出
|
|
</el-button>
|
|
</template>
|
|
<slot name="operation"></slot>
|
|
</div>
|
|
<el-form
|
|
:style="showSelect && showUnfoldButton ? headerFormSecondStyleOpen : headerFormSecondStyleClose"
|
|
ref="headerFormSecond"
|
|
@submit.prevent=""
|
|
@keyup.enter="onComSearch"
|
|
label-position="left"
|
|
:inline="true"
|
|
></el-form>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { inject, ref, onMounted, nextTick, onUnmounted } from 'vue'
|
|
import type TableStore from '@/utils/tableStore'
|
|
import DatePicker from '@/components/form/datePicker/index.vue'
|
|
import Area from '@/components/form/area/index.vue'
|
|
import { mainHeight } from '@/utils/layout'
|
|
import { useDictData } from '@/stores/dictData'
|
|
import { Search, RefreshLeft } from '@element-plus/icons-vue'
|
|
import { defineProps } from 'vue'
|
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
|
import { useRoute } from 'vue-router'
|
|
|
|
const emit = defineEmits(['selectChange'])
|
|
|
|
const tableStore = inject('tableStore') as TableStore
|
|
const tableHeader = ref()
|
|
const datePickerRef = ref()
|
|
const dictData = useDictData()
|
|
const areaRef = ref()
|
|
const headerForm = ref()
|
|
const headerFormSecond = ref()
|
|
const num = ref(0)
|
|
|
|
// 获取路由和缓存 store
|
|
const route = useRoute()
|
|
const timeCacheStore = useTimeCacheStore()
|
|
|
|
interface Props {
|
|
datePicker?: boolean
|
|
area?: boolean
|
|
showSearch?: boolean
|
|
nextFlag?: boolean //控制时间是否可以往后推
|
|
theCurrentTime?: boolean //控制时间前3天展示上个月时间
|
|
showReset?: boolean //是否显示重置
|
|
showExport?: boolean //导出控制
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
datePicker: false,
|
|
area: false,
|
|
showSearch: true,
|
|
nextFlag: false,
|
|
theCurrentTime: true,
|
|
showReset: true,
|
|
showExport: false
|
|
})
|
|
|
|
// 处理 DatePicker 值变化事件
|
|
const handleDatePickerChange = (value: any) => {
|
|
// 将值缓存到 timeCache
|
|
if (value) {
|
|
timeCacheStore.setCache(route.path, value.interval, value.timeValue)
|
|
}
|
|
|
|
// 将 datePicker 的变化传递给父组件
|
|
emit('selectChange', true, tableHeader.value.offsetHeight, value)
|
|
}
|
|
|
|
// 动态计算table高度
|
|
let resizeObserver = new ResizeObserver(entries => {
|
|
for (const entry of entries) {
|
|
handlerHeight()
|
|
computedSearchRow()
|
|
}
|
|
})
|
|
const showUnfoldButton = ref(false)
|
|
const headerFormSecondStyleOpen = {
|
|
opacity: 1,
|
|
height: 'auto',
|
|
padding: '0 15px 0px 15px'
|
|
}
|
|
const headerFormSecondStyleClose = {
|
|
opacity: 0,
|
|
height: '0',
|
|
padding: '0'
|
|
}
|
|
onMounted(() => {
|
|
// 设置初始值到 DatePicker
|
|
if (props.datePicker && datePickerRef.value) {
|
|
// 从缓存中获取值并设置
|
|
const cached = timeCacheStore.getCache(route.path)
|
|
if (cached) {
|
|
if (cached.interval !== undefined) {
|
|
datePickerRef.value.setInterval(cached.interval)
|
|
}
|
|
if (cached.timeValue) {
|
|
datePickerRef.value.timeValue = cached.timeValue
|
|
}
|
|
}
|
|
|
|
// 更新 tableStore 参数
|
|
tableStore.table.params.searchBeginTime = datePickerRef.value?.timeValue?.[0]
|
|
tableStore.table.params.searchEndTime = datePickerRef.value?.timeValue?.[1]
|
|
tableStore.table.params.startTime = datePickerRef.value?.timeValue?.[0]
|
|
tableStore.table.params.endTime = datePickerRef.value?.timeValue?.[1]
|
|
tableStore.table.params.timeFlag = datePickerRef.value?.timeFlag
|
|
}
|
|
|
|
if (props.area) {
|
|
tableStore.table.params.deptIndex = dictData.state.area[0].id
|
|
}
|
|
|
|
nextTick(() => {
|
|
resizeObserver.observe(tableHeader.value)
|
|
computedSearchRow()
|
|
})
|
|
})
|
|
onUnmounted(() => {
|
|
resizeObserver.disconnect()
|
|
})
|
|
|
|
const handlerHeight = () => {
|
|
if (tableStore && tableStore.table) {
|
|
tableStore.table.height = mainHeight(
|
|
tableStore.table.publicHeight + tableHeader.value.offsetHeight + (tableStore.showPage ? 58 : 0) + 20
|
|
).height as string
|
|
}
|
|
}
|
|
// 刷新页面handler高度出下拉
|
|
const computedSearchRow = () => {
|
|
if (!headerForm.value.$el) return
|
|
|
|
// 清空headerFormSecond.value.$el下的元素
|
|
while (headerFormSecond.value.$el.firstChild) {
|
|
headerForm.value.$el.appendChild(headerFormSecond.value.$el.firstChild)
|
|
}
|
|
|
|
// 获取第一行放了几个表单
|
|
const elFormItem = headerForm.value.$el.querySelectorAll('.el-form-item')
|
|
|
|
// 把第一行放不下的复制一份放到headerFormSecond.value.$el
|
|
let width = 0
|
|
for (let i = 0; i < elFormItem.length; i++) {
|
|
width += elFormItem[i].offsetWidth + 32
|
|
if (width > headerForm.value.$el.offsetWidth) {
|
|
headerFormSecond.value.$el.appendChild(elFormItem[i])
|
|
}
|
|
}
|
|
|
|
// 判断是否需要折叠
|
|
if (headerFormSecond.value.$el.scrollHeight > 0) {
|
|
showUnfoldButton.value = true
|
|
} else {
|
|
showUnfoldButton.value = false
|
|
}
|
|
}
|
|
|
|
const showSelect = ref(false)
|
|
const showSelectChange = () => {
|
|
showSelect.value = !showSelect.value
|
|
setTimeout(() => {
|
|
emit('selectChange', showSelect.value, tableHeader.value.offsetHeight)
|
|
}, 20)
|
|
}
|
|
const onComSearch = async () => {
|
|
if (props.datePicker) {
|
|
tableStore.table.params.searchBeginTime = datePickerRef.value.timeValue[0]
|
|
tableStore.table.params.searchEndTime = datePickerRef.value.timeValue[1]
|
|
tableStore.table.params.startTime = datePickerRef.value.timeValue[0]
|
|
tableStore.table.params.endTime = datePickerRef.value.timeValue[1]
|
|
tableStore.table.params.timeFlag = datePickerRef.value.timeFlag
|
|
}
|
|
|
|
await tableStore.onTableAction('search', {})
|
|
}
|
|
const setDatePicker = (list: any) => {
|
|
datePickerRef.value.setTimeOptions(list)
|
|
}
|
|
const onResetForm = () => {
|
|
//时间重置成默认值
|
|
datePickerRef.value?.setInterval(3)
|
|
tableStore.onTableAction('reset', {})
|
|
}
|
|
const setInterval = (val: any) => {
|
|
datePickerRef.value.setInterval(val)
|
|
}
|
|
|
|
const setTimeInterval = (val: any) => {
|
|
datePickerRef.value.timeValue = val
|
|
tableStore.table.params.searchBeginTime = val[0]
|
|
tableStore.table.params.searchEndTime = val[1]
|
|
tableStore.table.params.startTime = val[0]
|
|
tableStore.table.params.endTime = val[1]
|
|
}
|
|
// 导出
|
|
const onExport = () => {
|
|
tableStore.onTableAction('export', { showAllFlag: true })
|
|
}
|
|
|
|
defineExpose({
|
|
onComSearch,
|
|
areaRef,
|
|
setDatePicker,
|
|
setInterval,
|
|
setTimeInterval,
|
|
datePickerRef,
|
|
showSelectChange,
|
|
computedSearchRow
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.cn-table-header {
|
|
border: 1px solid var(--el-border-color);
|
|
}
|
|
|
|
.table-header {
|
|
position: relative;
|
|
overflow-x: auto;
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100%;
|
|
max-width: 100%;
|
|
background-color: var(--ba-bg-color-overlay);
|
|
|
|
border-bottom: none;
|
|
padding: 13px 15px 9px;
|
|
font-size: 14px;
|
|
|
|
.table-header-operate-text {
|
|
margin-left: 6px;
|
|
}
|
|
}
|
|
|
|
.table-com-search {
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
max-width: 100%;
|
|
background-color: var(--ba-bg-color-overlay);
|
|
border: 1px solid var(--ba-border-color);
|
|
border-bottom: none;
|
|
padding: 13px 15px 20px 15px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
#header-form-second,
|
|
#header-form {
|
|
// display: flex;
|
|
// flex-wrap: wrap;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.mlr-12 {
|
|
margin-left: 12px;
|
|
}
|
|
|
|
.mlr-12 + .el-button {
|
|
margin-left: 12px;
|
|
}
|
|
|
|
.table-search {
|
|
display: flex;
|
|
margin-left: auto;
|
|
|
|
.quick-search {
|
|
width: auto;
|
|
}
|
|
}
|
|
|
|
.table-search-button-group {
|
|
display: flex;
|
|
margin-left: 12px;
|
|
border: 1px solid var(--el-border-color);
|
|
border-radius: var(--el-border-radius-base);
|
|
overflow: hidden;
|
|
|
|
button:focus,
|
|
button:active {
|
|
background-color: var(--ba-bg-color-overlay);
|
|
}
|
|
|
|
button:hover {
|
|
background-color: var(--el-color-info-light-7);
|
|
}
|
|
|
|
.table-search-button-item {
|
|
height: 30px;
|
|
border: none;
|
|
border-radius: 0;
|
|
}
|
|
|
|
.el-button + .el-button {
|
|
margin: 0;
|
|
}
|
|
|
|
.right-border {
|
|
border-right: 1px solid var(--el-border-color);
|
|
}
|
|
}
|
|
|
|
html.dark {
|
|
.table-search-button-group {
|
|
button:focus,
|
|
button:active {
|
|
background-color: var(--el-color-info-dark-2);
|
|
}
|
|
|
|
button:hover {
|
|
background-color: var(--el-color-info-light-7);
|
|
}
|
|
|
|
button {
|
|
background-color: var(--ba-bg-color-overlay);
|
|
|
|
el-icon {
|
|
color: white !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#header-form,
|
|
#header-form-second {
|
|
:deep(.el-select) {
|
|
--el-select-width: 220px;
|
|
}
|
|
|
|
:deep(.el-input) {
|
|
--el-input-width: 220px;
|
|
}
|
|
}
|
|
</style>
|