Closed sailei1 closed 3 years ago
import React, { useState, useEffect, useRef } from 'react'; import 'antd/dist/antd.css'; import { Table, Space, Popover, Tooltip, Tree, Form, Row, Col, Button, Divider, Input, Pagination, TreeNode, } from 'antd'; import useATRH from 'use-antd-resizable-header'; import 'use-antd-resizable-header/dist/style.css'; import { SettingOutlined } from '@ant-design/icons'; const ResizableTable = (props) => { const { columns = [], request, headerTitle = 'title', pagination = { showSizeChanger: true, // showTotal:true, }, } = props; const { components, resizableColumns, tableWidth } = useATRH({ columns, minConstraints: 50 }); const [columnsMap, setColumnsMap] = useState({}); const [showColumns, setShowColumns] = useState([]); const selectKey = useRef([]); const [allColumns, setAllColumns] = useState([]); const [form] = Form.useForm(); const [dataSource, setDataSource] = useState([]); const [total, setTotal] = useState(0); const [current, setCurrent] = useState(1); const [pageSize, setPageSize] = useState(10); const onFinish = (values) => { const obj = { ...values }; if (pagination !== false) { obj.current = current; obj.pageSize = pageSize; } request && request(obj) .then((res) => { setDataSource(res.data); setTotal(res.total); }) .catch((rej) => { console.log(rej); }); }; const changePage = (val1, val2) => { setCurrent(val1); setPageSize(val2); form.submit(); }; // 获取formitem const getFields = () => { const arr = []; for (let i = 0; i < columns.length; i += 1) { if (!columns[i].hideInSearch || columns[i].hideInSearch !== true) { arr.push( <Col span={8} key={i}> <Form.Item name={columns[i].key || columns[i].dataIndex} label={columns[i].title}> {columns[i].renderFormItem ? columns[i].renderFormItem() : <Input></Input>} </Form.Item> </Col>, ); } } return arr; }; useEffect(() => { let cols = []; resizableColumns.map((item) => { item.key = item.title; if (item.hideInTable) { return; } if (columnsMap[item.key]?.show) { if (columnsMap[item.key]?.order > -1) { cols[`${columnsMap[item.key].order}`] = item; } else { cols.push(item); } } }); setShowColumns(cols); }, [resizableColumns, columnsMap]); useEffect(() => { let treeDataConfig = []; const map = {}; resizableColumns.map((item) => { item.key = item.title; map[item.title] = { show: true }; treeDataConfig.push(item.title); }); selectKey.current = treeDataConfig; setColumnsMap(map); setShowColumns(resizableColumns); setAllColumns(resizableColumns); form.submit(); }, []); const move = (dragKey, dropKey, dropPosition) => { const newColumns = [...allColumns]; const newMap = { ...columnsMap }; const findIndex = newColumns.findIndex((item) => { return item.key == dragKey; }); const targetIndex = newColumns.findIndex((item) => { return item.key == dropKey; }); const isDownWord = dropPosition > findIndex; if (findIndex < 0) { return; } const targetItem = newColumns[findIndex]; newColumns.splice(findIndex, 1); if (dropPosition === 0) { newColumns.unshift(targetItem); } else { newColumns.splice(isDownWord ? targetIndex : targetIndex + 1, 0, targetItem); } // // 重新生成排序数组 newColumns.forEach((item, order) => { newMap[item.key] = { ...(newMap[item.key] || {}), order }; }); // // 更新数组 setColumnsMap(newMap); setAllColumns(newColumns); }; const content = () => { return ( <> <Tree checkable blockNode treeData={allColumns} checkedKeys={selectKey.current} draggable={true} onDrop={(info) => { const dropKey = info.node.key; const dragKey = info.dragNode.key; const { dropPosition, dropToGap } = info; const position = dropPosition === -1 || !dropToGap ? dropPosition + 1 : dropPosition; move(dragKey, dropKey, position); }} onCheck={(select, e) => { if (select.length > 0) { const columnKey = e.node.key; const tempConfig = columnsMap[columnKey] || {}; const newSetting = { ...tempConfig }; if (e.checked) { newSetting.show = true; } else { newSetting.show = false; } selectKey.current = select; const map = { ...columnsMap, [columnKey]: newSetting, }; setColumnsMap(map); } }} /> </> ); }; return ( <> <Form form={form} name="advanced_search" className="ant-advanced-search-form" onFinish={onFinish} labelCol={{ style: { width: '120px' } }} > <Row gutter={24} className="search-item"> {getFields()} </Row> <Row> <Col span={24} style={{ textAlign: 'right' }}> <Button key="searchText" type="primary" onClick={() => { form.submit(); }} style={{ marginRight: '10px' }} > 查询 </Button> <Button key="resetText" onClick={() => { form.resetFields(); }} > 重置 </Button> </Col> </Row> </Form> <Divider style={{ margin: '10px 0' }} /> <Row style={{ padding: '16px' }}> <Col span={4} style={{ textAlign: 'left' }}> {headerTitle} </Col> <Col span={20}> <div style={{ display: 'flex', justifyContent: 'flex-end' }}> <Popover arrowPointAtCenter title="列设置" trigger="click" placement="bottomRight" content={content} > <Tooltip placement="topLeft" title="列设置" arrowPointAtCenter> <SettingOutlined style={{ margin: '0, 16px' }} /> </Tooltip> </Popover> </div> </Col> </Row> <Table {...props} columns={showColumns} dataSource={dataSource} bordered size="middle" components={components} scroll={{ x: tableWidth }} pagination={ pagination === false ? false : { ...pagination, onChange: changePage, onShowSizeChange: changePage, pageSize, current, total, } } /> </> ); }; export default ResizableTable;