|  | @@ -7,6 +7,25 @@ import classNames from "classnames";
 | 
	
		
			
				|  |  |  import ResizeObserver from "rc-resize-observer";
 | 
	
		
			
				|  |  |  import type { ColumnsType } from "antd/es/table";
 | 
	
		
			
				|  |  |  import { VariableSizeGrid as Grid } from "react-window";
 | 
	
		
			
				|  |  | +import { Resizable } from "react-resizable";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const ResizableHeader = (props: { [x: string]: any; onResize: any; width: any }) => {
 | 
	
		
			
				|  |  | +    const { onResize, width, ...restProps } = props;
 | 
	
		
			
				|  |  | +    if (!width) {
 | 
	
		
			
				|  |  | +        return <th {...restProps} />
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return <Resizable width={width} height={0} onResize={onResize} draggableOpts={{ enableUserSelectHack: false }}>
 | 
	
		
			
				|  |  | +        <th {...restProps} />
 | 
	
		
			
				|  |  | +    </Resizable>
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const getColumns = <RecordType extends object>(columns: ColumnsType<RecordType> | undefined) => {
 | 
	
		
			
				|  |  | +    return columns!.map((column) => {
 | 
	
		
			
				|  |  | +        if (column.width)  return column;
 | 
	
		
			
				|  |  | +        return { ...column, width: 100 };
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  interface Props<RecordType extends object> extends TableProps<RecordType> {
 | 
	
		
			
				|  |  |      rowHeight: number
 | 
	
	
		
			
				|  | @@ -17,24 +36,51 @@ interface Props<RecordType extends object> extends TableProps<RecordType> {
 | 
	
		
			
				|  |  |      defaultPageSize?: number
 | 
	
		
			
				|  |  |      pageChange?: (page: number, pageSize?: number) => void,
 | 
	
		
			
				|  |  |      sizeChange?: (current: number, size?: number) => void,
 | 
	
		
			
				|  |  | +    isShowTotal?: boolean
 | 
	
		
			
				|  |  | +    handelResize?: (columns: any) => void//当表头被拖动改变宽度时回调设置对应的本地保存
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const VTable = <RecordType extends object>(props: Props<RecordType>) => {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    const { columns, scroll, className, rowHeight, loading = false, total = 0, current, pageSize, defaultPageSize, pageChange, sizeChange } = props;
 | 
	
		
			
				|  |  | +    const {
 | 
	
		
			
				|  |  | +        columns,
 | 
	
		
			
				|  |  | +        scroll,
 | 
	
		
			
				|  |  | +        className,
 | 
	
		
			
				|  |  | +        rowHeight,
 | 
	
		
			
				|  |  | +        loading = false,
 | 
	
		
			
				|  |  | +        total = 0,
 | 
	
		
			
				|  |  | +        current,
 | 
	
		
			
				|  |  | +        pageSize,
 | 
	
		
			
				|  |  | +        defaultPageSize,
 | 
	
		
			
				|  |  | +        pageChange,
 | 
	
		
			
				|  |  | +        sizeChange,
 | 
	
		
			
				|  |  | +        isShowTotal = true,
 | 
	
		
			
				|  |  | +        handelResize
 | 
	
		
			
				|  |  | +    } = props;
 | 
	
		
			
				|  |  |      const [tableWidth, setTableWidth] = useState(0);
 | 
	
		
			
				|  |  | +    let bodyWidth = document.body.clientWidth < 415
 | 
	
		
			
				|  |  | +    const [mergedColumns, setMergedColumns] = useState<ColumnsType<RecordType>>(getColumns(columns))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    useEffect(() => setMergedColumns(() => getColumns(columns)), [columns])
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    //   const widthColumnCount = columns!.filter(({ width }) => !width).length;
 | 
	
		
			
				|  |  | -    const mergedColumns = columns!.map((column) => {
 | 
	
		
			
				|  |  | -        if (column.width) {
 | 
	
		
			
				|  |  | -            return column;
 | 
	
		
			
				|  |  | +    const handleResize = (index: any) => (e: any, { size }: any) => {
 | 
	
		
			
				|  |  | +        const nextColumns = [...mergedColumns]
 | 
	
		
			
				|  |  | +        nextColumns[index] = {
 | 
	
		
			
				|  |  | +            ...nextColumns[index],
 | 
	
		
			
				|  |  | +            width: size.width
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        return {
 | 
	
		
			
				|  |  | -            ...column,
 | 
	
		
			
				|  |  | -            //   width: Math.floor(tableWidth / widthColumnCount)
 | 
	
		
			
				|  |  | -            width: 100
 | 
	
		
			
				|  |  | -        };
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | +        setMergedColumns(nextColumns)
 | 
	
		
			
				|  |  | +        handelResize?.(nextColumns)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    const columnsRef = useRef<any[]>([])
 | 
	
		
			
				|  |  | +    columnsRef.current = (mergedColumns || []).map((col: any, index: any) => ({
 | 
	
		
			
				|  |  | +        ...col,
 | 
	
		
			
				|  |  | +        onHeaderCell: (column: any) => ({
 | 
	
		
			
				|  |  | +            width: column.width,
 | 
	
		
			
				|  |  | +            onResize: handleResize(index)
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +    }))
 | 
	
		
			
				|  |  | +    console.log('---->', columnsRef.current)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      const gridRef = useRef<any>();
 | 
	
		
			
				|  |  |      const [connectObject] = useState<any>(() => {
 | 
	
	
		
			
				|  | @@ -65,25 +111,21 @@ const VTable = <RecordType extends object>(props: Props<RecordType>) => {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      useEffect(() => resetVirtualGrid, [tableWidth]);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    const renderVirtualList = (
 | 
	
		
			
				|  |  | -        rawData: object[],
 | 
	
		
			
				|  |  | -        { scrollbarSize, ref, onScroll }: any
 | 
	
		
			
				|  |  | -    ) => {
 | 
	
		
			
				|  |  | +    const renderVirtualList = (rawData: object[], { scrollbarSize, ref, onScroll }: any) => {
 | 
	
		
			
				|  |  |          ref.current = connectObject;
 | 
	
		
			
				|  |  | -        const totalHeight = rawData.length * 54;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        const totalHeight = rawData.length * rowHeight + 6;
 | 
	
		
			
				|  |  |          return (
 | 
	
		
			
				|  |  |              <Grid
 | 
	
		
			
				|  |  |                  ref={gridRef}
 | 
	
		
			
				|  |  |                  className="virtual-grid"
 | 
	
		
			
				|  |  | -                columnCount={mergedColumns.length}
 | 
	
		
			
				|  |  | +                columnCount={columnsRef.current.length}
 | 
	
		
			
				|  |  |                  columnWidth={(index: number) => {
 | 
	
		
			
				|  |  | -                    const { width } = mergedColumns[index];
 | 
	
		
			
				|  |  | -                    return totalHeight > (scroll!.y! as any) && index === mergedColumns.length - 1
 | 
	
		
			
				|  |  | +                    const { width } = columnsRef.current[index];
 | 
	
		
			
				|  |  | +                    return totalHeight > (scroll!.y! as any) && index === columnsRef.current.length - 1
 | 
	
		
			
				|  |  |                          ? (width as number) - scrollbarSize - 1
 | 
	
		
			
				|  |  |                          : (width as number);
 | 
	
		
			
				|  |  |                  }}
 | 
	
		
			
				|  |  | -                height={scroll!.y as number}
 | 
	
		
			
				|  |  | +                height={scroll!.y as number > totalHeight ? totalHeight : scroll!.y as number}
 | 
	
		
			
				|  |  |                  rowCount={rawData.length}
 | 
	
		
			
				|  |  |                  rowHeight={() => rowHeight}
 | 
	
		
			
				|  |  |                  width={tableWidth}
 | 
	
	
		
			
				|  | @@ -92,7 +134,10 @@ const VTable = <RecordType extends object>(props: Props<RecordType>) => {
 | 
	
		
			
				|  |  |                  }}
 | 
	
		
			
				|  |  |              >
 | 
	
		
			
				|  |  |                  {({ columnIndex, rowIndex, style }: { columnIndex: number; rowIndex: number; style: React.CSSProperties; }) => {
 | 
	
		
			
				|  |  | -                    const { render, dataIndex, align } = (mergedColumns as any)[columnIndex];
 | 
	
		
			
				|  |  | +                    const { render, dataIndex, align } = (columnsRef.current as any)[columnIndex];
 | 
	
		
			
				|  |  | +                    if ((columnsRef.current as any)[columnIndex].title === 'C') {
 | 
	
		
			
				|  |  | +                        console.log('style--->', style)
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  |                      const myStyle = {
 | 
	
		
			
				|  |  |                          justifyContent:
 | 
	
		
			
				|  |  |                              align === "left"
 | 
	
	
		
			
				|  | @@ -105,7 +150,7 @@ const VTable = <RecordType extends object>(props: Props<RecordType>) => {
 | 
	
		
			
				|  |  |                      return (
 | 
	
		
			
				|  |  |                          <div
 | 
	
		
			
				|  |  |                              className={classNames("virtual-table-cell", {
 | 
	
		
			
				|  |  | -                                "virtual-table-cell-last": columnIndex === mergedColumns.length - 1
 | 
	
		
			
				|  |  | +                                "virtual-table-cell-last": columnIndex === columnsRef.current.length - 1
 | 
	
		
			
				|  |  |                              })}
 | 
	
		
			
				|  |  |                              style={myStyle}
 | 
	
		
			
				|  |  |                          >
 | 
	
	
		
			
				|  | @@ -123,39 +168,39 @@ const VTable = <RecordType extends object>(props: Props<RecordType>) => {
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      return <Spin style={{ width: '100%' }} spinning={loading}>
 | 
	
		
			
				|  |  | -        <div>
 | 
	
		
			
				|  |  | -            <ResizeObserver
 | 
	
		
			
				|  |  | -                onResize={({ width }) => {
 | 
	
		
			
				|  |  | -                    setTableWidth(width);
 | 
	
		
			
				|  |  | +        <ResizeObserver
 | 
	
		
			
				|  |  | +            onResize={({ width }) => {
 | 
	
		
			
				|  |  | +                setTableWidth(width);
 | 
	
		
			
				|  |  | +            }}
 | 
	
		
			
				|  |  | +        >
 | 
	
		
			
				|  |  | +            <Table
 | 
	
		
			
				|  |  | +                {...props}
 | 
	
		
			
				|  |  | +                bordered
 | 
	
		
			
				|  |  | +                className={`virtual-table all_table ${className ? className : ''}`}
 | 
	
		
			
				|  |  | +                columns={columnsRef.current}
 | 
	
		
			
				|  |  | +                pagination={{
 | 
	
		
			
				|  |  | +                    defaultCurrent: 1,
 | 
	
		
			
				|  |  | +                    total: total || 0,
 | 
	
		
			
				|  |  | +                    current: current || 1,
 | 
	
		
			
				|  |  | +                    pageSize: pageSize || 20,
 | 
	
		
			
				|  |  | +                    defaultPageSize: defaultPageSize || 20,
 | 
	
		
			
				|  |  | +                    pageSizeOptions: ['10', '20', '30', '40', '50', '60', '70', '80', '90', '100'],
 | 
	
		
			
				|  |  | +                    size: "small",
 | 
	
		
			
				|  |  | +                    showTotal: (total) => isShowTotal ? <Tag color="cyan">总共{total}数据</Tag> : null,
 | 
	
		
			
				|  |  | +                    showSizeChanger: true,
 | 
	
		
			
				|  |  | +                    onChange: pageChange,
 | 
	
		
			
				|  |  | +                    onShowSizeChange: sizeChange,
 | 
	
		
			
				|  |  | +                    showLessItems: true,
 | 
	
		
			
				|  |  | +                    simple: bodyWidth ? true : false,//开启简单分页
 | 
	
		
			
				|  |  |                  }}
 | 
	
		
			
				|  |  | -            >
 | 
	
		
			
				|  |  | -                <Table
 | 
	
		
			
				|  |  | -                    {...props}
 | 
	
		
			
				|  |  | -                    bordered
 | 
	
		
			
				|  |  | -                    className={`virtual-table all_table ${className ? className : ''}`}
 | 
	
		
			
				|  |  | -                    columns={mergedColumns}
 | 
	
		
			
				|  |  | -                    pagination={false}
 | 
	
		
			
				|  |  | -                    components={{
 | 
	
		
			
				|  |  | -                        body: renderVirtualList as any
 | 
	
		
			
				|  |  | -                    }}
 | 
	
		
			
				|  |  | -                />
 | 
	
		
			
				|  |  | -            </ResizeObserver>
 | 
	
		
			
				|  |  | -            <div style={{ textAlign: 'end', padding: '16px 0', background: '#FFF' }}>
 | 
	
		
			
				|  |  | -                <Pagination
 | 
	
		
			
				|  |  | -                    defaultCurrent={1}
 | 
	
		
			
				|  |  | -                    total={total || 0}
 | 
	
		
			
				|  |  | -                    current={current || 1}
 | 
	
		
			
				|  |  | -                    pageSize={pageSize || 20}
 | 
	
		
			
				|  |  | -                    defaultPageSize={defaultPageSize || 20}
 | 
	
		
			
				|  |  | -                    pageSizeOptions={['10', '20', '30', '40', '50', '60', '70', '80', '90', '100']}
 | 
	
		
			
				|  |  | -                    size="small"
 | 
	
		
			
				|  |  | -                    showTotal={(total) => <Tag color="cyan">总共{total}数据</Tag>}
 | 
	
		
			
				|  |  | -                    showSizeChanger={true}
 | 
	
		
			
				|  |  | -                    onChange={pageChange}
 | 
	
		
			
				|  |  | -                    onShowSizeChange={sizeChange}
 | 
	
		
			
				|  |  | -                />
 | 
	
		
			
				|  |  | -            </div>
 | 
	
		
			
				|  |  | -        </div>
 | 
	
		
			
				|  |  | +                components={{
 | 
	
		
			
				|  |  | +                    header: {
 | 
	
		
			
				|  |  | +                        cell: ResizableHeader
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                    body: renderVirtualList as any
 | 
	
		
			
				|  |  | +                }}
 | 
	
		
			
				|  |  | +            />
 | 
	
		
			
				|  |  | +        </ResizeObserver>
 | 
	
		
			
				|  |  |      </Spin>
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -217,7 +262,7 @@ const columns: ColumnsType<any> = [
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const data = Array.from({ length: 100 }, (_, key) => ({
 | 
	
		
			
				|  |  |      key,
 | 
	
		
			
				|  |  | -    dd: "啊大大撒旦啊实打实大苏打阿斯顿撒打算阿三打撒"
 | 
	
		
			
				|  |  | +    dd: "啊大大撒1111"
 | 
	
		
			
				|  |  |  }));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 |