index.tsx 6.13 KB
import React, { useContext, useEffect, useState, useRef } from 'react';
import { Form, Table } from 'antd';
import type { GetRef, InputRef, TableProps, } from 'antd';
import * as commonUtils from '@/utils/utils';
import FormItemType from '@/components/Common/CommonComponentNew';

import type { PropsType, RecordType, EditableRowProps, EditableCellProps, ShowConfigType } from './type';
import style from './index.less';

const TableNewEvent: React.FC<PropsType> = (props) => {
  const addState: any = {};

  // 保存行数据
  addState.onSaveRowData = (record: any) => {
    const { name, data = [] } = props;
    const { sId } = record;
    const iIndex = data.findIndex((item: any) => item.sId === sId);
    const rowDataNew = {
      ...record,
      handleType: record.handleType || 'update',
    }
    const dataNew = [...data];
    dataNew[iIndex] = rowDataNew;
    props.onSaveState({
      [`${name}Data`]: dataNew,
    })
  };

  // 获取字段配置
  addState.getShowConfig = (sName: string, bSlaveInfo: boolean): ShowConfigType => {
    /*   返回值声明   */
    let showConfig = { sName: "" };
    /*   通过sName过滤出对应的showConfig   */
    const { config, customConfig } = props;
    if (customConfig) {
      const iIndex = customConfig.findIndex(item => item.sName === sName && item.bVisible);
      if (iIndex !== -1) {
        showConfig = customConfig[iIndex];
      }
    } else if (config) {
      const iIndex = config.gdsconfigformslave.findIndex(item => item.sName === sName && item.bVisible);
      if (iIndex !== -1) {
        showConfig = config.gdsconfigformslave[iIndex];
      }

      if (bSlaveInfo && props.slaveInfo?.config) {
        const iIndex = props.slaveInfo.config.gdsconfigformslave.findIndex(item => item.sName === sName && item.bVisible);
        if (iIndex !== -1) {
          showConfig = props.slaveInfo.config.gdsconfigformslave[iIndex];
        }
      }

    }
    /*   返回值   */
    return showConfig;
  };

  // 获取展示内容
  addState.onGetTableChildNode = (sName: string, record: any, children: any): React.ReactNode => {
    return children;
  };

  return {
    ...props,
    ...addState,
  }
};

const TableNew: React.FC<PropsType> = (baseProps) => {
  const props: any = TableNewEvent(baseProps);

  const tableProps = {
    columns: TableColumns(props),
    dataSource: TableData(props),
    components: TableComponents(props),
    rowClassName: 'editable-row',
    scroll: {
      // x: 'max-content',
      y: '100%',
    },
    bordered: true,
  };

  return (
    <div className={style.tableNew}>
      <Table<TableProps> {...tableProps} />
    </div>
  );
};


// 处理数据
const TableData = (props: PropsType): TableProps['dataSource'] => {
  const { data = [] } = props;
  return data.map((item: any) => ({
    ...item,
    editable: true,
  }));
}

// 处理表头
const TableColumns = (props: PropsType): PropsType['headerColumn'] => {
  const { headerColumn = [], data = [], enabled } = props;

  return headerColumn.map((columnOld) => {
    const column = { ...columnOld };
    column.ellipsis = true;
    column.title = (
      <>
        {column.bNotEmpty && <span style={{ color: 'red' }}>*</span>}
        {column.title}
      </>
    );
    if (!('dataIndex' in column)) return column;
    const { dataIndex } = column;
    if (dataIndex === 'sPartNameStatus') {
      interface TextJsonItem {
        sProcessName: string;
        sState: number;
      }
      return {
        ...column,
        render: (text: string, record: object) => {
          const textJson: TextJsonItem[] = commonUtils.convertStrToObj(text.replace(",]", ']'), []) as TextJsonItem[];
          return textJson.map(item => item.sProcessName).join('->');
        },
      };
    }

    if (!enabled) {
      return column;
    }

    return {
      ...column,
      onCell: (record: RecordType) => ({
        record,
        ...column,
      }),
    };

  });
}

type FormInstance<T> = GetRef<typeof Form<T>>;
const EditableContext = React.createContext<FormInstance<any> | null>(null);
const TableComponents = (props: PropsType): TableProps['components'] => {
  const { enabled } = props;

  const EditableRow: React.FC<EditableRowProps> = ({ index, ...rest }) => {

    const [form] = Form.useForm();
    return (
      <Form form={form} component={false}>
        <EditableContext.Provider value={form}>
          <tr {...rest} />
        </EditableContext.Provider>
      </Form>
    );
  };

  const EditableCell: React.FC<EditableCellProps> = ({
    title,
    dataIndex,
    record,
    children,
    bNotEmpty,
    bReadonly,
    ...restProps
  }) => {
    const [editing, setEditing] = useState(false);
    // const inputRef = useRef<any>(null);
    const form = useContext(EditableContext) as FormInstance<any>;

    const showConfig = props.getShowConfig(dataIndex);

    // useEffect(() => {
    //   if (editing) {
    //     inputRef.current?.focus();
    //   }
    // }, [editing]);

    const toggleEdit = () => {
      setEditing(!editing);
      form.setFieldsValue({ [dataIndex]: record[dataIndex] });
    };

    const save = async () => {
      try {
        const values = await form.validateFields();
        toggleEdit();

        props.onSaveRowData({ ...record, ...values });
      } catch (errInfo) {
        console.log('Save failed:', errInfo);
      }
    };

    // 是否可编辑
    const bEidtable = enabled && !bReadonly;
    // 是否显示编辑框
    const bShowType = bEidtable && editing;

    let childNode = bShowType ? '' : props.onGetTableChildNode(dataIndex, record, children);

    const FormItemTypeProps = {
      ...props,
      record,
      showConfig,
      form,
      // ref: inputRef,
      onSave: save,
      onChange: props.onDataChange,
      getDropDownData: props.getDropDownData,
    }

    if (bEidtable) {
      childNode = editing ?
        <FormItemType {...FormItemTypeProps} />
        : (
          <div
            className="editable-cell-value-wrap"
            onClick={toggleEdit}
          >
            {children}
          </div>
        );
    }

    return <td {...restProps}>{childNode}</td>;
  };

  return {
    body: {
      row: EditableRow,
      cell: EditableCell,
    },
  };
}

export default TableNew;