123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- import { QuestionCircleOutlined } from "@ant-design/icons";
- import { useDebounceFn, useFullscreen, useLocalStorageState, useMount, useSetState } from "ahooks";
- import { Card, Col, Row, Space, Tooltip } from "antd";
- import React, { useCallback, useEffect, useRef, useState } from "react"
- import style from './index.less'
- import Settings from "../Settings";
- import CustomListModel from "@/components/CustomList";
- import NewTable from "./newTable";
- const log = (text?: any, key?: string) => {
- console.log(`pro_${key || ''}----->`, text)
- }
- export const DispatchContext = React.createContext<PROAPI.TableContentProps | null>(null);
- export const DispatchHeader = React.createContext<PROAPI.HeaderContentProps | null>(null);
- export const version = '1.0.0'
- const ran = Math.ceil(Math.random() * 100)
- /**
- * 升级版表格
- * @returns
- */
- const TablePro: React.FC<PROAPI.TableProProps> = ({
- configName,
- config,
- fixed = { left: 0, right: 0 },
- title,
- tips,
- ajax,
- czChild,
- leftChild,
- size = 'small',
- className,
- total,
- page,
- pageSize,
- scroll,
- dataSource,
- isZj,
- totalData = [],
- summary,
- ...props
- }) => {
- /*********************************************/
- const [lsDataSource, setLsDataSource] = useLocalStorageState<PROAPI.ColumnsTypePro<any>>(`myAdMonitorConfig${version}_` + configName);
- const [lsFixed] = useLocalStorageState<{ left: number, right: number }>(`myAdMonitorConfigFixed${version}_` + configName);
- const [state, setState] = useSetState<PROAPI.State>({
- // 所有配置用key转Object
- configObj: {},
- columns: [],
- // 默认配置
- defaultColumns: []
- });
- const ref = useRef(null)
- const [isFull, { toggleFull }] = useFullscreen(ref);
- const [isFullscreen, setIsFullscreen] = useState<boolean>(true);
- const [visible, setVisible] = useState<boolean>(false)
- // const { configObj, columns, defaultColumns } = state
- /*********************************************/
- // 首次渲染
- useMount(() => {
- log('----mount-----')
- handleConfig()
- });
- /**
- * 处理config成对象 减少后期轮询
- * 拿到默认Columns
- */
- const handleConfig = () => {
- // log(config)
- let newColumns: PROAPI.ColumnsTypePro<any> = []
- let newConfigObj: { [key: string]: PROAPI.ColumnTypePro<any>; } = {}
- config?.forEach((item: { data: { default: any; dataIndex: string }[] }) => {
- item?.data?.forEach((d: { default: any, dataIndex: string }) => {
- newConfigObj[d.dataIndex] = { ...d }
- if (d.default) {
- newColumns[d.default - 1] = d
- }
- })
- })
- setState({ defaultColumns: newColumns, configObj: newConfigObj })
- handleColumns(newColumns, newConfigObj, lsDataSource, lsFixed)
- }
- // 处理columns
- const handleColumns = (defaultColumns: PROAPI.ColumnsTypePro<any>, configObj: { [key: string]: PROAPI.ColumnTypePro<any>; }, lsDataSource?: PROAPI.ColumnsTypePro<any>, lsFixed?: { left: number, right: number }) => {
- // log(defaultColumns, 'defaultColumns')
- // log(configObj, 'configObj')
- // log(lsDataSource, 'lsDataSource')
- // 使用默认配置
- let newColumns: PROAPI.ColumnsTypePro<any> = defaultColumns
- let newFixed: { left: number, right: number } = fixed
- if (lsFixed) {
- newFixed = lsFixed
- }
- if (lsDataSource) { // 找到了设置的配置
- newColumns = lsDataSource
- .filter((item: { dataIndex: string | number; }) => !!item && configObj[item.dataIndex])
- .map((item: { dataIndex: string | number; width: number }) => {
- let column = { ...configObj[item.dataIndex] }
- column['width'] = item.width
- return column
- })
- }
- // log(newFixed, 'newFixed')
- newColumns = newColumns.map(item => {
- if (item?.tips && typeof item.title === 'string') {
- let column: any = configObj[item.dataIndex]
- item.title = <Space size={2}>
- {column.title}
- <Tooltip title={column?.tips} placement='bottom'>
- <QuestionCircleOutlined />
- </Tooltip>
- </Space>
- }
- return { ...item, key: item.dataIndex }
- })
- if (newFixed.left || newFixed.right) {
- for (let i = 0; i < Math.min(newFixed.left, newColumns.length); i++) {
- newColumns[i] = { ...newColumns[i], fixed: 'left' };
- }
- const arrayLength = newColumns.length;
- for (let i = Math.max(0, arrayLength - newFixed.right); i < arrayLength; i++) {
- newColumns[i] = { ...newColumns[i], fixed: 'right' };
- }
- }
- // log(newColumns, 'newColumns')
- setState({ columns: newColumns })
- }
- useEffect(() => {
- const contentBodyScroll = (e: any) => {
- let el = document.querySelector(`.header_table_body_${ran} .ant-table-body`);
- if (el) {
- el.scrollLeft = e.target.scrollLeft
- }
- }
- const headerBodyScroll = (e: any) => {
- let el = document.querySelector(`.content_table_body_${ran} .ant-table-body`);
- if (el) {
- el.scrollLeft = e.target.scrollLeft
- }
- }
- if (isZj) {
- document.querySelector(`.content_table_body_${ran} .ant-table-body`)?.addEventListener('scroll', contentBodyScroll);
- document.querySelector(`.header_table_body_${ran} .ant-table-body`)?.addEventListener('scroll', headerBodyScroll);
- }
- () => {
- if (isZj) {
- document.querySelector(`.content_table_body_${ran} .ant-table-body`)?.removeEventListener('scroll', contentBodyScroll);
- document.querySelector(`.header_table_body_${ran} .ant-table-body`)?.removeEventListener('scroll', headerBodyScroll);
- }
- }
- }, [isZj, ran])
- const { run: runResize } = useDebounceFn((columns) => {
- if (configName) {
- let newSelectData: PROAPI.ColumnsTypePro<any> = []
- state.columns?.forEach((item, index) => {
- newSelectData.push({ ...JSON.parse(JSON.stringify(state.configObj[item.dataIndex])), width: columns[index]['width'] })
- })
- setLsDataSource(newSelectData)
- if (isZj) { // 有总计需要刷新内容表格
- handleColumns(state.defaultColumns, state.configObj, newSelectData, lsFixed)
- }
- }
- }, { wait: 200 });
- //拖动宽度设置设置保存
- const handelResize = useCallback((columns: PROAPI.ColumnTypePro<any>) => {
- runResize(columns)
- }, [configName, state.columns])
- return <>
- {/* 设置展示参数 */}
- {visible && <CustomListModel
- columns={state.columns}
- sysFixed={fixed}
- version={version}
- config={config}
- configName={configName}
- visible={visible}
- onClose={() => { setVisible(false) }}
- onChange={(value) => {
- if (value) {
- handleColumns(state.defaultColumns, state.configObj, value?.selectData, value?.fixed)
- } else {
- handleColumns(state.defaultColumns, state.configObj)
- }
- }}
- />}
- <Row gutter={[0, 20]} ref={ref} style={isFull ? { background: '#fff' } : {}}>
- <Col span={24}>
- <Card
- style={{ borderRadius: 8 }}
- headStyle={{ textAlign: 'left' }}
- bodyStyle={{ padding: '5px 10px' }}
- >
- {title && <div className={style.title}>
- <Space><span>{title}</span>{tips && <Tooltip title={tips}><span><QuestionCircleOutlined /></span></Tooltip>}</Space>
- </div>}
- <Row gutter={[0, 16]}>
- <DispatchHeader.Provider value={{ setIsFullscreen, isFullscreen, isFull, toggleFull, setVisible, ajax, czChild, leftChild }}>
- <Settings />
- </DispatchHeader.Provider>
- <DispatchContext.Provider value={{ total, page, pageSize, handelResize }}>
- <Col span={24}>
- <div className={`${style[size]} ${className ? style[className] : ''} `}>
- {
- isZj && <NewTable
- bordered
- columns={state.columns}
- dataSource={totalData?.length > 0 ? [...totalData] : [{ id: 1 }]}
- scroll={scroll ? isFull ? { ...scroll, y: document.body.clientHeight - 300 } : scroll : {}}
- size={size}
- pagination={false}
- className={`all_table header_table_body header_table_body_${ran} ${className ? className : ''}`}
- sortDirections={['ascend', 'descend', null]}
- {...props}
- />
- }
- <NewTable
- showHeader={!isZj}
- sortDirections={['ascend', 'descend', null]}
- bordered
- className={`all_table content_table_body content_table_body_${ran} ${className ? className : ''}`}
- scroll={scroll ? isFull ? { ...scroll, y: document.body.clientHeight - 300 } : scroll : {}}
- columns={state.columns}
- dataSource={dataSource}
- summary={summary}
- pagination={{}}
- {...props}
- />
- </div>
- </Col>
- </DispatchContext.Provider>
- </Row>
- </Card>
- </Col>
- </Row>
- </>
- }
- export default React.memo(TablePro)
|