import { ProTable, DragSortTable } from '@ant-design/pro-components'; import { DownOutlined, UpOutlined, CaretDownOutlined, CaretRightOutlined } from '@ant-design/icons'; import type { ColumnsState, ProTableProps } from '@ant-design/pro-table'; import { Space, Typography } from 'antd'; import { ConfigProvider, Tour } from 'antd5'; import type { TourStepProps } from 'antd5'; import { FormattedMessage, useIntl } from 'umi'; import CustomLink from '../CustomLink'; import style from './index.less'; import { memo, useEffect, useMemo, useRef, useState } from 'react'; import { useGetAppId } from '../utils/hooks'; import { isBoolean } from 'lodash'; import { components, getMergeColumns } from './ResizableTableUtil'; export interface CustomTableProps extends ProTableProps { loading?: boolean; showTour?: boolean; draggerable?: boolean; onDragSortEnd?: (beforeIndex: number, afterIndex: number, newDataSource: any) => void; tableAlert?: (data: { selectedRowKeys: any; selectedRows: any; onCleanSelected: any }) => any[]; selectHidden?: boolean; overflow?: boolean; } export const CustomTable = >(props: CustomTableProps) => { const { formatMessage } = useIntl(); const ref = useRef(null); const firstRef = useRef(true); const appId = useGetAppId(); const { showTour = false, search = {}, columns: _columns, expandable = {}, draggerable = false, onDragSortEnd = () => {}, pagination, overflow, ...otherProps } = props; const { loading = false, tableAlert, rowSelection } = otherProps; const [columns, setColumns] = useState( _columns?.map(({ ellipsis, ...col }) => ({ ...col, ellipsis: col.render || !ellipsis ? ellipsis : false, render: col.render || !ellipsis ? col.render : (node) => (
{node}
), })), ); const mergeColumns = getMergeColumns(columns, setColumns); const [open, setOpen] = useState(false); const [columnsStateMap, setColumnsStateMap] = useState>(); const tableAlertOptionRender = ({ selectedRowKeys, onCleanSelected }) => { if (!tableAlert) { return false; } return ( 0 ? '' : style.disable} size={16}> {' '} {selectedRowKeys.length}{' '} ); }; const tableAlertRender = (data) => { if (!tableAlert) { return false; } return ( 0 ? '' : style.disable} size={6}>
{tableAlert(data).map((item, i) => ( ))}
); }; const [steps, setSteps] = useState([]); const columnsState = useMemo( () => columns?.reduce((pre, cur) => { // @ts-ignore const { optionShow, fixed, order, disable } = cur; // @ts-ignore pre[cur.dataIndex] = { fixed, order, disable, show: typeof optionShow === 'boolean' ? optionShow : true, }; return pre; }, {}), [columns], ); const expandIcon = ({ expanded, onExpand, record }) => { if (!record.children || record.children.length === 0) { return null; // 如果没有数据,返回 null 不渲染展开图标 } return expanded ? ( onExpand(record, e)}> ) : ( onExpand(record, e)}> ); }; // const handleDragSortEnd3 = (beforeIndex: number, afterIndex: number, newDataSource: any) => { // console.log('排序后的数据', newDataSource); // // // 模拟将排序后数据发送到服务器的场景 // // remoteData = newDataSource; // // // 请求成功之后刷新列表 // // actionRef.current?.reload(); // // message.success('修改列表排序成功'); // }; useEffect(() => { // @ts-ignore setColumnsStateMap(columnsState); }, [columnsState]); useEffect(() => { const isOpen = localStorage.getItem(`app_${appId}_feature_tour`); if (!loading && !isOpen && showTour) { setSteps([ { title: formatMessage({ id: 'base.common.tour.more' }), target: () => ref?.current, }, { title: formatMessage({ id: 'base.common.tour.filter' }), // @ts-ignore target: () => document.querySelector( 'span[class="ant-dropdown-trigger ant-table-filter-trigger"] span', ), }, { title: formatMessage({ id: 'base.common.tour.setting' }), // @ts-ignore target: () => document.querySelector( '.ant-pro-table-list-toolbar-setting-item .anticon.anticon-setting', ), }, { title: formatMessage({ id: 'base.common.tour.checked' }), // @ts-ignore target: () => document.querySelector('tbody tr td label[class="ant-checkbox-wrapper"]'), }, ]); setOpen(true); localStorage.setItem(`app_${appId}_feature_tour`, 'ok'); } }, [loading, appId, ref, showTour]); useEffect(() => { if (!firstRef.current) { setColumns( _columns?.map(({ ellipsis, ...col }) => ({ ...col, ellipsis: col.render || !ellipsis ? ellipsis : false, render: col.render || !ellipsis ? col.render : (node) => (
{node}
), })), ); } else { firstRef.current = false; } }, [_columns]); return ( <> {draggerable ? ( dragSortKey="sort" onDragSortEnd={onDragSortEnd} rowKey="id" components={components} columnsState={{ value: columnsStateMap, onChange: setColumnsStateMap, }} options={{ density: false, }} columns={[ { fixed: 'left', dataIndex: 'sort', search: false, width: 60, }, ...mergeColumns, ]} search={ isBoolean(search) ? search : { labelWidth: 'auto', span: 6, defaultCollapsed: true, collapseRender: (collapsed, showCollapseButton, intl) => { if (!showCollapseButton) return null; return (
{collapsed ? formatMessage({ id: 'base.common.expand' }) : formatMessage({ id: 'base.common.collapse' })}
{collapsed ? : }
); }, ...search, } } scroll={{ x: '1400', }} expandable={{ expandIcon, indentSize: 15, // todo 等待官方修复 showExpandColumn: true, defaultExpandAllRows: true, ...expandable, }} tableAlertRender={tableAlertRender} tableAlertOptionRender={tableAlertOptionRender} pagination={ !isBoolean(pagination) ? { ...{ pagination }, showSizeChanger: true, } : pagination } {...otherProps} /> ) : ( tableClassName={overflow ? '' : style['ant-table-overflow']} rowKey="id" components={components} columnsState={{ value: columnsStateMap, onChange: setColumnsStateMap, }} options={{ density: false, }} columns={mergeColumns} search={ isBoolean(search) ? search : { labelWidth: 'auto', span: 6, defaultCollapsed: true, collapseRender: (collapsed, showCollapseButton, intl) => { if (!showCollapseButton) return null; return (
{collapsed ? formatMessage({ id: 'base.common.expand' }) : formatMessage({ id: 'base.common.collapse' })}
{collapsed ? : }
); }, ...search, } } scroll={{ x: '1400', }} expandable={{ expandIcon, indentSize: 15, // todo 等待官方修复 showExpandColumn: true, defaultExpandAllRows: true, ...expandable, }} tableAlertRender={tableAlertRender} tableAlertOptionRender={tableAlertOptionRender} pagination={ !isBoolean(pagination) ? { ...pagination, showSizeChanger: true, } : pagination } {...otherProps} {...(overflow ? {} : { rowSelection: tableAlert ? { alwaysShowAlert: true, ...rowSelection } : false })} /> )} setOpen(false)} steps={steps} /> ); }; export default memo(CustomTable);