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.
 
 
 
 

174 lines
4.5 KiB

<template>
<el-dialog v-model="visible" :title="title" width="1200px" :before-close="handleClose">
<!-- 搜索和筛选区域 -->
<div class="filter-container">
<el-form :model="queryParams" label-width="80px" inline>
<el-form-item label="关键字">
<el-input v-model="queryParams.keyword" placeholder="请输入关键字搜索" clearable @keyup.enter="handleSearch" />
</el-form-item>
<el-form-item label="时间范围">
<el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期"
end-placeholder="结束日期" value-format="YYYY-MM-DD" @change="handleDateChange" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 数据表格 -->
<el-table :data="tableData" border stripe style="width: 100%" v-loading="loading">
<el-table-column v-for="column in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label"
:width="column.width" :formatter="column.formatter" />
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination v-model:current-page="queryParams.pageNo" v-model:page-size="queryParams.pageSize"
:page-sizes="[10, 20, 50, 100]" :total="total" layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose">关闭</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ElDialog, ElForm, ElFormItem, ElInput, ElDatePicker, ElButton, ElTable, ElTableColumn, ElPagination } from 'element-plus'
// 定义组件属性
interface Props {
modelValue: boolean
title?: string
columns: Array<{
prop: string
label: string
width?: string | number
formatter?: (row: any, column: any, cellValue: any) => string
}>
data: any[]
}
// 定义事件
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void
(e: 'search', params: any): void
}>()
// 属性定义
const props = withDefaults(defineProps<Props>(), {
modelValue: false,
title: '历史记录',
columns: () => [],
data: () => []
})
// 响应式数据
const visible = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})
const queryParams = ref({
keyword: '',
startTime: '',
endTime: '',
pageNo: 1,
pageSize: 10
})
const dateRange = ref<[string, string]>(['', ''])
const loading = ref(false)
const total = ref(0)
// 表格数据计算属性
const tableData = computed(() => {
// 在实际应用中,这里应该是从服务器获取的数据
// 当前为了演示,我们使用传入的模拟数据
return props.data.slice(
(queryParams.value.pageNo - 1) * queryParams.value.pageSize,
queryParams.value.pageNo * queryParams.value.pageSize
)
})
// 表格列
const tableColumns = computed(() => props.columns)
// 处理关闭
const handleClose = () => {
visible.value = false
}
// 处理搜索
const handleSearch = () => {
// 发送搜索事件给父组件
emit('search', { ...queryParams.value })
}
// 重置查询条件
const resetQuery = () => {
queryParams.value.keyword = ''
queryParams.value.startTime = ''
queryParams.value.endTime = ''
dateRange.value = ['', '']
queryParams.value.pageNo = 1
handleSearch()
}
// 处理日期变化
const handleDateChange = (val: [string, string] | null) => {
if (val && val[0] && val[1]) {
queryParams.value.startTime = val[0]
queryParams.value.endTime = val[1]
} else {
queryParams.value.startTime = ''
queryParams.value.endTime = ''
}
}
// 处理分页大小变化
const handleSizeChange = (val: number) => {
queryParams.value.pageSize = val
queryParams.value.pageNo = 1
handleSearch()
}
// 处理当前页变化
const handleCurrentChange = (val: number) => {
queryParams.value.pageNo = val
handleSearch()
}
// 监听数据变化并更新总数
watch(
() => props.data,
(newData) => {
total.value = newData.length
},
{ immediate: true }
)
</script>
<style scoped>
.filter-container {
margin-bottom: 20px;
}
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
</style>