123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- import React, { ReactNode ,useEffect, useRef, useState} from 'react'
- import { Table, Tag, message } from 'antd';
- import { Excle } from '@/utils/Excle'
- import style from './index.less'
- import './index.less'
- import { Resizable } from 'react-resizable'
- import { SortOrder } from 'antd/lib/table/interface';
- 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>
- }
- /**
- * https://ant-design.gitee.io/components/table-cn/#API
- */
- interface Props {
- dataSource: any[],
- columns: any[],
- excle?: {
- fillName: string,//文件名称
- filter?: string[]//需要排除的数据,输入数据key
- },
- total?: number,
- current?: number,
- pageSize?: number,
- rowSelection?: any,//选择
- onRow?: {//行操作事件
- onClick?: (event?: any) => void, // 点击行
- onDoubleClick?: (event?: any) => void,
- onContextMenu?: (event?: any) => void,
- onMouseEnter?: (event?: any) => void, // 鼠标移入行
- onMouseLeave?: (event?: any) => void,
- }
- pageChange?: (page: number, pageSize?: number) => void,
- sizeChange?: (current: number, size?: number) => void,
- rowClassName?: string | ((record: any, index: any) => string),//样式
- expandedRowRender?: any,//子table
- scroll?: { x?: number, y?: number },
- summary?: (data: readonly any[]) => ReactNode,
- size?: 'small' | 'middle' | 'large',
- loading?: boolean,
- defaultPageSize?: 10 | 20 | 30 | 100,
- bordered?: boolean,
- onChange?: (pagination: any, filters: any, sorter: any) => void//服务端排序回调
- pagination?: boolean,
- showHeader?: boolean,
- hideOnSinglePage?: boolean,
- className?: string,
- handelResize?:(columns:any)=>void//当表头被拖动改变宽度时回调设置对应的本地保存
- sortDirections?: SortOrder[],
- isShowTotal?: boolean, // 是否展示总计
- }
- function Tables(props: Props) {
- // //导出数据
- let { columns, dataSource, excle, total,handelResize, rowSelection, onRow, isShowTotal = true, hideOnSinglePage, rowClassName, className, expandedRowRender, scroll, summary, showHeader = true, bordered, size = 'small', onChange, sortDirections, pagination, ...prop } = props
- let handleExcle = () => {
- if (dataSource.length < 1) {
- message.error('请先搜索再导出');
- return
- }
- let thName: any = {};
- let obj = columns;
- obj.forEach((item: any) => {
- thName[item.key] = item.title
- })
- let fillName = excle?.fillName || ''
- let filter = excle?.filter || []
- Excle(thName, dataSource, fillName, filter)
- }
- let ww = document.body.clientWidth < 415
- // 拖动宽逻辑
- const [cols,setCols] = useState<any>(columns)
- const colsRef = useRef<any[]>([])
- const components={
- header:{
- cell:ResizableHeader
- }
- }
- useEffect(()=>{
- setCols(columns)
- },[columns])
- const handleResize=(index:any)=>(e:any,{size}:any)=>{
- const nextColumns=[...cols]
- nextColumns[index]={
- ...nextColumns[index],
- width:size.width
- }
- setCols(nextColumns)
- handelResize && handelResize(nextColumns)
- }
- colsRef.current = (cols||[]).map((col:any,index:any)=>({
- ...col,
- onHeaderCell:(column:any)=>({
- width:column.width,
- onResize:handleResize(index)
- })
- }))
- return <div className='components-table-resizable-column'>
- {
- excle && <Tag color='#f50' style={{ margin: '10px 0', float: 'right' }} onClick={handleExcle}><a>导出数据</a></Tag>
- }
- <Table
- components={components}
- columns={colsRef?.current}
- sortDirections={sortDirections || ['descend', 'ascend', null]}
- onChange={(pagination, filters, sorter) => {
- onChange && onChange(pagination, filters, sorter)
- }}
- bordered={bordered ? bordered : false}
- dataSource={dataSource}
- showHeader={showHeader}
- scroll={scroll ? { ...scroll, scrollToFirstRowOnChange: true } : undefined}
- size={size}
- rowKey={(a: any) => {
- return (JSON.stringify(a?.id) || JSON.stringify(a?.key))
- }}
- rowSelection={rowSelection ? rowSelection : undefined}
- onRow={record => {
- return {
- onClick: onRow?.onClick && onRow?.onClick.bind('', record) || undefined,
- }
- }}
- // rowClassName={(record: any) => {
- // if (rowClassName && record[rowClassName as string] === 2) {
- // return style.unfollow
- // }
- // if (rowClassName && !record[rowClassName as string]) {
- // return style.unfollow
- // }
- // }
- // }
- // rowClassName={rowClassName}
- summary={summary}
- className={className}
- expandable={expandedRowRender ? {
- defaultExpandedRowKeys: ['0'],
- expandRowByClick: true, expandedRowRender: (data) => {
- return expandedRowRender(data)
- }
- } : {}}
- pagination={
- {
- total: total || 0,//总共多少条数据,服务器给,设置后分页自动计算页数
- current: props.current,//当前页数,需state控制配合翻页
- pageSize: props?.pageSize,
- defaultCurrent: 1,//默认初始的当前页数
- defaultPageSize: props?.defaultPageSize || 20,//默认初始的每页条数
- pageSizeOptions: ['10', '20', '30', '40', '50', '60', '70', '80', '90', '100'],
- showTotal: (total) => isShowTotal ? <Tag color="cyan">总共{total}数据</Tag> : null,
- showSizeChanger: true, //手动开启条数筛选器,默认超过50条开启
- // size:'small',//设置分页尺寸
- //responsive:true,//当 size 未指定时,根据屏幕宽度自动调整尺寸
- onChange: props.pageChange, //点击页码或条数筛选时触发获取当前页数和每页条数
- onShowSizeChange: props.sizeChange,//点击条数筛选器触发
- simple: ww ? true : false,//开启简单分页
- hideOnSinglePage: hideOnSinglePage ? hideOnSinglePage : false,//只有一页数据隐藏分页
- showLessItems: true
- }
- }
- {...prop}
- {...{
- rowClassName: typeof rowClassName === 'string' ? (record: any) => {
- if (rowClassName && record[rowClassName as string] === 2) {
- return style.unfollow
- }
- if (rowClassName && !record[rowClassName as string]) {
- return style.unfollow
- }
- } : rowClassName
- }
- }
- />
- </div>
- }
- export default Tables
|