116 lines
3.0 KiB
TypeScript
116 lines
3.0 KiB
TypeScript
import { ListProps, TableProps } from 'antd';
|
|
import { useState, useRef, useEffect } from 'react';
|
|
import { PageResult, SearchOption } from '../../service/def';
|
|
|
|
|
|
type TableState<T> = {
|
|
data: T[];
|
|
total: number;
|
|
loading: boolean;
|
|
|
|
pageSize: number;
|
|
pageNumber: number;
|
|
search: { [key: string]: string };
|
|
sort?: [string, 'asc' | 'desc'];
|
|
}
|
|
|
|
|
|
export type PageTableContext<T> = {
|
|
tableProps: TableProps<T>,
|
|
listProps?: ListProps<T>,
|
|
search: (params?: SearchOption) => void,
|
|
refresh: () => void
|
|
}
|
|
|
|
function usePageTable<T>(
|
|
service: (params?: SearchOption) => Promise<PageResult<T>>,
|
|
options: SearchOption = {}
|
|
): PageTableContext<T> {
|
|
// 写在一起避免异步之后多次setState导致多次重绘
|
|
const [state, setState] = useState<TableState<T>>(() => ({
|
|
data: [],
|
|
total: 0,
|
|
loading: false,
|
|
pageSize: options.pageSize ?? 10,
|
|
pageNumber: options.pageNumber ?? 1,
|
|
sort: options.sort,
|
|
search: options.search || {},
|
|
}));
|
|
|
|
const abort = useRef(false);
|
|
useEffect(() => {
|
|
abort.current = false;
|
|
search();
|
|
return () => { abort.current = true; }
|
|
}, []);
|
|
|
|
const search = (opt: SearchOption = {}) => {
|
|
setState(s => ({ ...s, loading: true }));
|
|
const pageParams = {
|
|
pageNumber: opt?.pageNumber ?? state.pageNumber,
|
|
pageSize: opt?.pageSize ?? state.pageSize,
|
|
sort: opt?.sort ?? state.sort,
|
|
search: opt?.search ?? state.search,
|
|
};
|
|
service(pageParams).then((data) => {
|
|
if (!abort.current) {
|
|
setState({
|
|
...pageParams,
|
|
data: data.list,
|
|
total: data.totalRow,
|
|
loading: false,
|
|
})
|
|
}
|
|
});
|
|
}
|
|
|
|
const handleTableChange = (pagination: any, filters: any, sort: any) => {
|
|
search({ pageNumber: pagination.current, pageSize: pagination.pageSize, sort });
|
|
}
|
|
|
|
let listProps = undefined;
|
|
if (false) {
|
|
const handleListChange = (page: number, pageSize: number) => {
|
|
search({ pageNumber: page, pageSize: pageSize });
|
|
}
|
|
listProps = {
|
|
dataSource: state.data,
|
|
loading: state.loading,
|
|
pagination: {
|
|
showTotal: (totalRow: any) => `共${totalRow}条`,
|
|
showSizeChanger: true,
|
|
showQuickJumper: true,
|
|
pageSize: state.pageSize,
|
|
current: state.pageNumber,
|
|
total: state.total,
|
|
pageSizeOptions: ['10', '20', '50', '100'],
|
|
onChange: handleListChange
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
tableProps: {
|
|
size: 'small',
|
|
bordered: true,
|
|
dataSource: state.data,
|
|
pagination: {
|
|
showTotal: (totalRow: any) => `共${totalRow}条`,
|
|
showSizeChanger: true,
|
|
showQuickJumper: true,
|
|
pageSize: state.pageSize,
|
|
current: state.pageNumber,
|
|
total: state.total,
|
|
pageSizeOptions: ['10', '20', '50', '100'],
|
|
hideOnSinglePage: true,
|
|
},
|
|
loading: state.loading,
|
|
onChange: handleTableChange,
|
|
},
|
|
listProps,
|
|
search: (params?: SearchOption) => search({ ...params, pageNumber: 1 }),
|
|
refresh: search,
|
|
}
|
|
}
|
|
|
|
export default usePageTable |