import { ProTable } from "@ant-design/pro-components"; import { useEffect, useMemo, useState } from "react"; import { throttle } from "throttle-debounce"; import { useAntdResizableHeader } from "use-antd-resizable-header"; import { getDataType, getIndexColumn } from "../../utils"; import "use-antd-resizable-header/dist/style.css"; import "./index.less"; function getPersistenceKey(index) { const basename = process.env?.app?.basename; const pathname = decodeURIComponent(window.location.pathname); const insertIndex = getDataType(index) === "Undefined" ? "" : `#{${index}}`; return { size: `${basename}#${pathname}${insertIndex}#size`, resizable: `${basename}#${pathname}${insertIndex}#resizable`, columnState: `${basename}#${pathname}${insertIndex}#columnState`, }; } function getTableSize(index) { return window.sessionStorage.getItem(getPersistenceKey(index).size); } function setTableSize(value, index) { return window.sessionStorage.setItem(getPersistenceKey(index).size, value); } function Table(props) { const { columns = [], showIndexColumn = true, ellipsis = true, align = "center", indexColumnFixed = "left", rowKey = "id", storeIndex, disabledResizer = false, height, ...restProps } = props; const antPrefix = process.env.app.antd["ant-prefix"]; const prefix = antPrefix || "ant"; const baseCls = `.${prefix}-table`; const tableCls = `${baseCls}-wrapper`; const tableBodyCls = `${baseCls}-body`; const [size, setSize] = useState(getTableSize(storeIndex) || "default"); const [tableHeight, setTableHeight] = useState(0); const persistenceKey = getPersistenceKey(storeIndex); const enabledResizer = !disabledResizer; const { components, resizableColumns, tableWidth, resetColumns, } = useAntdResizableHeader({ columns, columnsState: { persistenceKey: persistenceKey.resizable, persistenceType: "localStorage", }, }); // 计算高度 const calcTableHeight = throttle(50, () => { try { // table元素 const tableEl = document.querySelector(tableCls); // table-body元素 const tableBodyEl = document.querySelector(tableBodyCls); // 获取页脚元素高度 const footerEl = document.querySelector(".page-layout-footer"); const footerHeight = footerEl ? footerEl.offsetHeight : 0; if (tableBodyEl && tableEl) { // 获取table元素的矩形数据 const tableRect = tableEl.getBoundingClientRect(); // 获取table-body元素的矩形数据 const tableBodyRect = tableBodyEl.getBoundingClientRect(); // 获取底部的高度差 const bottomHeight = tableRect.bottom - tableBodyRect.bottom; // 计算最终值,减去页脚高度 setTableHeight(innerHeight - tableBodyRect.top - bottomHeight - (window.__IN_BASE__ ? 38 : 22) - footerHeight); } } catch (e) { window.console.error(e); } }); useEffect(() => { let mutationObserver, resizeObserver; if (enabledResizer) { // 监听-DOM树 mutationObserver = new MutationObserver(mutations => mutations.forEach(() => calcTableHeight())); // 监听-缩放 resizeObserver = new ResizeObserver(entries => entries.forEach(() => calcTableHeight())); // 初始化首次计算 setTimeout(() => calcTableHeight(), 500); // 执行-监听-缩放 resizeObserver.observe(document.body); // 执行-监听-DOM树是否发生变化 mutationObserver.observe(document.body, { subtree: true, childList: true, }); } return () => { if (mutationObserver && resizeObserver && enabledResizer) { resizeObserver.unobserve(document.body); mutationObserver.disconnect(document.body); } }; }, []); useEffect(() => { setTableSize(size, storeIndex); }, [size]); const settingColumns = () => { const columnsCopy = [...resizableColumns]; showIndexColumn && columnsCopy.unshift({ ...getIndexColumn(props.pagination), fixed: indexColumnFixed }); const setAlign = column => ({ align, ellipsis, ...column, ...(column.children ? { children: column.children.map(setAlign) } : {}), }); return columnsCopy.map(setAlign); }; const processedColumns = useMemo(() => settingColumns(), [resizableColumns, showIndexColumn, align, ellipsis, indexColumnFixed, props.pagination]); return (
重置列宽 ), }, }} components={components} columnsState={{ persistenceKey: persistenceKey.columnState, persistenceType: "localStorage", }} onSizeChange={setSize} columns={processedColumns} bordered size="small" rowKey={rowKey} {...restProps} />
); } Table.displayName = "Table"; export default Table;