policeSecurity/superManagement/src/components/table/TableProMax.vue

224 lines
6.0 KiB
Vue
Raw Normal View History

2024-08-30 17:03:25 +08:00
<template>
<div class="table-pro-content">
<div class="card padding" v-if="props.searchFormOptions">
<FormProMax
ref="searchFormRef"
:form-item-options="props.searchFormOptions"
v-model:value="searchParams"
v-bind="props.searchFormProps"
>
<template v-slot:formOperation>
<a-space class="margin-right flex-end">
<a-button type="primary" @click="search">
<search-outlined/>
搜索
</a-button>
<a-button danger @click="resetFormAndTable">
<rollback-outlined/>
重置
</a-button>
</a-space>
</template>
</FormProMax>
</div>
<div class="card padding margin-top-xs">
<div class="flex-justify-between">
<slot name="tableHeader" :selectKeys="selectKeys" :selectRows="selectRows"></slot>
<div></div>
<slot name="tableHeaderRight" :selectKeys="selectKeys" :selectRows="selectRows"></slot>
<a-space>
<template v-if="!props.searchFormOptions">
<a-tooltip>
<template #title>刷新数据</template>
<a-button shape="circle" @click="requestGetTableData">
<ReloadOutlined/>
</a-button>
</a-tooltip>
</template>
<template v-if="props.isPrinter">
<a-tooltip>
<template #title>打印数据</template>
<a-button shape="circle">
<PrinterOutlined/>
</a-button>
</a-tooltip>
</template>
</a-space>
</div>
<a-table
class="margin-top"
v-bind="props"
:columns="tableColumns"
:row-selection="props.isSelection ? props.selectionProps ? props.selectionProps : defaultSelectProps : null"
:data-source="dataSource"
:loading="loading"
:pagination="false"
>
<template v-for="(_,key) in slots" v-slot:[key]="scope">
<slot v-if="!includes(['tableHeader','tableHeaderRight'],key)" :name="key" v-bind="scope"></slot>
</template>
</a-table>
<a-pagination
v-if="props.isPagination"
class="flex-end margin-top margin-right"
v-model:current="pageParams.current"
v-model:page-size="pageParams.size"
:total="pageParams.total"
v-bind="props.paginationProps"
@change="handleCurrentChange"
@showSizeChange="handleSizeChange"
/>
</div>
</div>
</template>
<script
setup
lang="ts"
generic="T extends BaseTableRowRecord = {},P extends { [key: string]: any } ={}"
>
import FormProMax from "@/components/form/FormProMax.vue";
import {PrinterOutlined, ReloadOutlined, RollbackOutlined, SearchOutlined} from "@ant-design/icons-vue";
import {computed, onMounted, Ref, ref} from "vue";
import {FormInstance} from "ant-design-vue";
import useTableProMax from "@/hooks/useTableProMax";
import {includes, isEmpty} from "lodash-es";
import {BaseTableRowRecord, TableProMaxProps, TableProMaxRowSelect, TableProMaxSlots} from "@/types/components/table";
const selectKeys = ref<string[]>([])
const selectRows = ref<T[]>([]) as Ref<T[]>
const defaultSelectProps: TableProMaxRowSelect<T> = {
type: "checkbox",
selectedRowKeys: selectKeys as any,
preserveSelectedRowKeys: true,
onSelect: (record, selected) => {
if (selected) {
selectKeys.value.push(record[props.rowKey] as string)
selectRows.value.push(record)
} else {
selectKeys.value.splice(selectKeys.value.findIndex(x => x === record[props.rowKey]));
selectRows.value.splice(selectRows.value.findIndex(r => r[props.rowKey] === record[props.rowKey]))
}
},
onChange: (selectedRowKeys, selectedRows) => {
selectKeys.value = selectedRowKeys as string[];
selectRows.value = selectedRows;
},
}
const clearSelect = () => {
selectKeys.value = [];
selectRows.value = [];
}
const props = withDefaults(defineProps<TableProMaxProps<T, P>>(), {
needIndex: true,
searchFormProps: () => {
return {
grid: {
xs: 24,
sm: 12,
md: 8,
lg: 6,
xl: 4
},
labelCol: undefined,
wrapperCol: undefined
}
},
rowKey: 'snowFlakeId',
requestAuto: true,
isPagination: true,
isSelection: false,
paginationProps: () => {
return {
showTotal: (total) => `${total}`,
showSizeChanger: true,
}
},
bordered: true,
showSorterTooltip: undefined,
showHeader: undefined,
expandFixed: undefined,
expandRowByClick: undefined,
defaultExpandAllRows: undefined,
showExpandColumn: undefined,
sticky: undefined
})
const slots = defineSlots<TableProMaxSlots<T>>()
const tableColumns = computed(() => {
let cols = props.columns;
if (!isEmpty(cols) && props.needIndex) {
if (!(cols?.[0].dataIndex === 'index')) {
cols?.unshift({
dataIndex: 'index',
2024-09-06 14:54:14 +08:00
width: 70,
2024-08-30 17:03:25 +08:00
title: '序号',
customRender: ({index}) => index + 1
})
}
}
return cols;
})
/**
* 表单实例
*/
const searchFormRef = ref<FormInstance>() as Ref<FormInstance>
/**
* 查询参数
*/
const searchParams = ref<P | Record<string, any>>(props.defaultSearchParams || {}) as Ref<P>
const {
loading,
dataSource,
pageParams,
search,
requestGetTableData,
handleSizeChange,
handleCurrentChange,
resetState
} = useTableProMax(props.requestApi,
searchFormRef,
searchParams,
props.isPagination,
props.dataCallback,
props.requestError
)
onMounted(() => props.requestAuto && requestGetTableData(true))
/**
* 重置表单并查询
*/
const resetFormAndTable = () => {
searchFormRef.value?.resetFields()
requestGetTableData()
}
defineExpose({
selectKeys,
selectRows,
requestGetTableData,
clearSelect,
resetTable: () => {
searchFormRef.value?.resetFields()
resetState();
}
})
</script>
<style scoped lang="scss">
.card {
box-sizing: border-box;
background-color: #ffffff;
border: 1px solid #e4e7ed;
border-radius: 6px;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.05);
}
</style>