/*
 * Creater:     柿子
 * CreateDate:  2023/05/06
 * Describe：   table行内编辑
 * */
import React, { Component } from 'react';
import { Select, Input, DatePicker, TimePicker, Tooltip, Switch, message, Popconfirm, Icon, Divider } from 'antd';
import { Util, dayFormat, timeFormat } from 'tools';
import moment from 'moment';
import PublicModalTable from './PublicModalTable';
import PublicTablePagination from 'pages/common/PubilcTablePagination';
import '../workstation/style/index.less';
const { TextArea } = Input;

class PublicTableinLineEditing extends Component {
  constructor(props) {
    super(props);
    this.state = {
      userData: React.$getSessionData(),
      selectData: {},
      openObj: {}, // 是否展开下拉菜单
      totalWidth: 0,
      columns: [],
      filterColumns: [],
      tableData: [],
      filterTableData: [],
      propsAdmID: '',
      rowID: '',
      formatType: {},
      selectedRowKeys: [],
      selectedRows: [],
      modalRecordIndex: 0,
      modalRecordItem: {},
      modalRecordData: {},
      top: 0,
      left: 0,
      modalTableData: [],
      modalPage: 1,
      modalPageSize: 10,
      modalTotal: 0,
      modalRowID: '',
      searchDesc: '',
      modalTableLoading: false,
      modalTableComponentName: '',
      modalColumns: [],
      modalTotalWidth: 460,
      modalColumnsInfo: {},
      doubleClickDataIndex: '', // 双击查看知识库
      doubleClickIndex: ''
    };
    this.timeout = null;
    this.isOnComposition = false;
  }

  componentDidMount() {
    this.props.onRef && this.props.onRef(this);
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    //该方法内禁止访问this
    if (nextProps.admID !== undefined && JSON.stringify(nextProps.admID) !== JSON.stringify(prevState.propsAdmID)) {
      return {
        propsAdmID: nextProps.admID
      }
    }
    if (nextProps?.columns !== undefined && (JSON.stringify(nextProps.columns) !== JSON.stringify(prevState.columns))) {
      return {
        totalWidth: nextProps.totalWidth,
        columns: JSON.parse(JSON.stringify(nextProps.columns)), // 防止重复渲染
        filterColumns: nextProps.columns
      }
    }
    if (nextProps.selectData !== undefined && (JSON.stringify(nextProps.selectData) !== JSON.stringify(prevState.selectData))) {
      return {
        selectData: nextProps.selectData
      }
    }
    //不需要更新状态，返回null
    return null
  }

  componentDidUpdate(nextProps, prevState) {
    if (nextProps?.columns !== undefined && (JSON.stringify(nextProps.columns) !== JSON.stringify(this.state.columns))) {
      this.handleFilterColumns();
    }
  }

  // 设置列表数据
  setTableData = (tableData, autoAddFlag) => {
    let filterTableData = Util.addKeyValueToDataSource(tableData, '', 0);
    this.setState({
      filterTableData,
      selectedRowKeys: [],
      selectedRows: []
    }, () => {
      if (autoAddFlag === 'Y') { // 自动添加一行空数据 || !(filterTableData && filterTableData.length > 0)
        this.addTableData('propsAuto', 300);
      }
      if (autoAddFlag === 'refreshColumns') {
        this.handleFilterColumns();
      }
    });
  }

  setTableColumns = (columns) => {
    this.setState({ filterColumns: columns && Array.isArray(columns) ? JSON.parse(JSON.stringify(columns)) : [] }, () => {
      this.handleFilterColumns();
    })
  }

  // 获取默认数据
  getDefaultData = () => {
    let { filterColumns, userData, selectData } = this.state;
    let defaultValues = {};
    for (let i = 0; i < filterColumns.length; i++) {
      let currentDefaultValue = filterColumns[i]?.default || filterColumns[i].defaultValue || undefined;
      if (filterColumns[i].inputType === 'DatePicker' || filterColumns[i].inputType === 'Date') { // 默认日期
        if (currentDefaultValue) {
          currentDefaultValue = String(currentDefaultValue);
          if (currentDefaultValue && (currentDefaultValue.indexOf('-') > -1 || currentDefaultValue.indexOf(':') > -1)) { // 实际的时间格式
            defaultValues[filterColumns[i].dataIndex] = currentDefaultValue;
          } else {
            let dateNum = currentDefaultValue && parseInt(currentDefaultValue) ? moment().subtract(parseInt(currentDefaultValue), 'days') : moment();
            defaultValues[filterColumns[i].dataIndex] = moment(dateNum).format(dayFormat);
          }
        }
        if ('className' in filterColumns[i] && filterColumns[i].className === 'disabledDate') { // 日期选择控制
          let methodName = filterColumns[i].methodName || '<';
          filterColumns[i].disabledDate = (curDate) => {
            return curDate && (methodName === '>' ? curDate > moment().subtract(1, 'days').endOf('day') : ( // 今天之前的开始选择
              methodName === '>=' ? curDate >= moment().endOf('day') : ( // 今天或者今天之前的可以选择
                methodName === '<' ? curDate < moment().endOf('day') : ( // 今天之后的开始选择
                  methodName === '<=' ? curDate <= moment().subtract(1, 'days').endOf('day') : '')))); // 今天或者今天之后的可以选择
          }
        }
      } else if (filterColumns[i] && (filterColumns[i].inputType === 'Select' || filterColumns[i].inputType === 'RadioGroup')) { // 下拉框数据对应取值及数据默认
        let selectDefault = currentDefaultValue === 'currentHospID' ? userData?.hospID : (currentDefaultValue === 'currentLocID' ? userData?.locID : (currentDefaultValue === 'currentUserID' ? userData?.userID : currentDefaultValue));
        let rowDefault = ''; // 后台下拉数据存在默认值的情况
        if (filterColumns[i].className && selectData) {
          let currentDetailItem = [];
          for (let keys in selectData) {
            if (filterColumns[i].className === keys) {
              currentDetailItem = selectData[keys];
              filterColumns[i].detailItem = selectData[keys];
            }
          }
          let currentDetaultItem = currentDetailItem.filter(item => item.default === 'Y');
          rowDefault = currentDetaultItem && currentDetaultItem.length > 0 ? currentDetaultItem[0].id : '';
        }
        defaultValues[filterColumns[i].dataIndex] = currentDefaultValue || rowDefault || selectDefault || undefined;
      } else {
        if (currentDefaultValue === 'currentUserDesc') { // 默认当前登录人
          currentDefaultValue = userData?.userName || undefined;
        }
        if (currentDefaultValue === 'currentDate') { // 当前时间
          currentDefaultValue = moment().format(filterColumns[i]?.format || dayFormat);
        }
        if (currentDefaultValue === 'currentTime') { // 当前时间
          currentDefaultValue = moment().format(filterColumns[i]?.format || timeFormat);
        }
        if (currentDefaultValue === 'empty') { // 空字符串
          currentDefaultValue = '';
        }
        defaultValues[filterColumns[i].dataIndex] = currentDefaultValue;
      }
    }
    return defaultValues;
  }

  // 差异对比 - 判断是否修改未保存
  handleDifferenceComparison = () => {
    let { filterTableData } = this.state;
    let modifyFlag = false;
    for (let i = 0; i < filterTableData.length; i++) {
      if (filterTableData[i] && 'modifyFlag' in filterTableData[i] && filterTableData[i].modifyFlag === 'Y') {
        modifyFlag = true;
        break;
      }
    }
    return modifyFlag;
  }

  handleFilterColumns = () => {
    let { filterColumns } = this.state;
    for (let i = 0; i < filterColumns.length; i++) {
      let item = filterColumns[i];
      let dataIndex = item.dataIndex;
      let required = item?.required || 'N';
      let title = item?.descripts || item?.title || '';
      let originalRenderFunc = typeof item.render === 'function' ? item.render : null;
      let width = item && 'inputWidth' in item && item.inputWidth ? (String(item.inputWidth).indexOf('px') < 0 ? item.inputWidth + 'px' : item.inputWidth) : '96%';
      item.title = () => <div>{required === 'Y' ? <span style={{ position: 'relative', padding: '6px 0 0 18px' }} className="formRequired">{title}</span> : title}</div>;
      item.render = (text, record, index) => {
        if (originalRenderFunc) {
          return originalRenderFunc(text, record, index)
        } else {
          const { tooltipFlag } = this.props;
          let { openObj, propsAdmID } = this.state;
          if (record?.editingFlag !== 'N' && item?.inputType === 'SearchSelect') { // 搜索下拉框
            let searchSelectAttr = { // 远程搜索属性
              showSearch: true,
              id: dataIndex + index,
              style: { width: width },
              // 是否可操作可根据某个字段去判断【disabledDataIndex】，栗：行ID存在的话不可编辑当前框
              // record[dataIndex + 'DisabledFlag'] 具体字段控制，比如复制时数量不可编辑
              disabled: !propsAdmID || item?.disabled === 'Y' || record[dataIndex + 'DisabledFlag'] === 'Y' || (item && 'disabledDataIndex' in item ? !!(record[item.disabledDataIndex]) : false),
              loading: record.loading === 'Y' || record.loading === true,
              allowClear: !(record.loading === 'Y' || record.loading === true), // 与loading效果互斥
              showArrow: false,
              filterOption: false,
              notFoundContent: null,
              defaultActiveFirstOption: false,
              value: record && dataIndex in record ? record[dataIndex] : undefined,
              placeholder: item.placeholder ? item.placeholder : (item?.trigger === 'enter' ? '输入关键字回车(Enter)搜索' : '输入关键字自动搜索'),
              ref: ref => this[dataIndex + index] = ref,
              getPopupContainer: item?.popupContainer === 'N' ? null : (triggerNode) => triggerNode.parentNode,
              onChange: (e) => this.handleInputChange(index, e, item, record),
              onSearch: (e) => this.handleSelectSearch(item, e, index),
              onInputKeyDown: (e) => this.handleKeyDown(dataIndex, index, item, e),
              onBlur: () => this.handleSetSelectOpenFlag(index, item, 'blur'),
              onFocus: () => this.handleSetSelectOpenFlag(index, item, 'focus'),
            };
            let searchSelectOption = record.detailItem && Array.isArray(record.detailItem) ? React.$SelectOptions(
              record.detailItem,
              item?.valueindex || item?.valueIndex || 'id',
              item?.descindex || item?.descIndex || 'descripts'
            ) : ''
            if (item?.autoOpenFlag !== 'N') { // 是否自动展开弹窗
              return (
                <Select {...searchSelectAttr} open={openObj[dataIndex + index] || false} >
                  {searchSelectOption}
                </Select>
              )
            } else {
              return (
                <Select {...searchSelectAttr}>
                  {searchSelectOption}
                </Select>
              )
            }
          } else if (item?.inputType === 'Select' || item?.inputType === 'SelectMultiple' || item?.inputType === 'SelectTags') { // 不判断是否可编辑，不可编辑直接展示对应描述
            // detailItemSource表示下拉框取值来源，record表示取行数据中的数据，detailItemDataIndex为对应的取值字段
            let selectOptionData = item?.detailItemSource === 'record' && item.detailItemDataIndex ? record[item?.detailItemDataIndex] : (item?.detailItem || []);
            let selectAttr = { // 下拉框属性
              allowClear: true,
              showSearch: true,
              id: dataIndex + index,
              style: { width: width },
              optionFilterProp: "seachprop",
              disabled: !propsAdmID || item?.disabled === 'Y' || record[dataIndex + 'DisabledFlag'] === 'Y' || (item && 'disabledDataIndex' in item ? !!(record[item.disabledDataIndex]) : false),
              mode: item && item.mode ? item.mode : (item?.inputType === 'SelectMultiple' ? 'multiple' : (item?.inputType === 'SelectTags' ? 'tags' : null)),
              placeholder: item.placeholder ? item.placeholder : '请选择',
              value: record && dataIndex in record ? record[dataIndex] : undefined,
              ref: ref => this[dataIndex + index] = ref,
              getPopupContainer: item?.popupContainer === 'N' ? null : (triggerNode) => triggerNode.parentNode,
              onChange: (e) => this.handleInputChange(index, e, item, record),
              onBlur: () => this.handleSetSelectOpenFlag(index, item, 'blur'),
              onFocus: () => this.handleSetSelectOpenFlag(index, item, 'focus'),
              onInputKeyDown: (e) => this.handleKeyDown(dataIndex, index, item, e),
            };
            let selectOption = selectOptionData && Array.isArray(selectOptionData) ? React.$SelectOptions(
              selectOptionData,
              item?.valueindex || item?.valueIndex || 'id',
              item?.descindex || item?.descIndex || 'descripts'
            ) : '';
            if (record?.editingFlag !== 'N') {
              if (item?.autoOpenFlag !== 'N') { // 是否自动展开弹窗
                return (
                  <Select {...selectAttr} open={openObj[dataIndex + index] || false}>
                    {selectOption}
                  </Select>
                )
              } else {
                return (
                  <Select {...selectAttr}>
                    {selectOption}
                  </Select>
                )
              }
            } else {
              // 下拉框取描述
              let descDataIndex = dataIndex && dataIndex.indexOf('ID') > -1 ? dataIndex.replace('ID', 'Desc') : dataIndex + 'Desc';
              return (
                tooltipFlag !== 'N' ? (
                  <Tooltip title={record[descDataIndex]}>
                    <span className="ellipsis" style={{ width: '100%', display: 'block' }}>{record[descDataIndex]}</span>
                  </Tooltip>
                ) : record[descDataIndex]
              );
            }
          } else if (record?.editingFlag !== 'N' && (item?.inputType === 'DatePicker' || item?.inputType === 'Date')) {
            let datePickerAttr = {
              separator: '-',
              id: dataIndex + index,
              style: { width: width },
              disabled: !propsAdmID || item?.disabled === 'Y' || record[dataIndex + 'DisabledFlag'] === 'Y' || (item && 'disabledDataIndex' in item ? !!(record[item.disabledDataIndex]) : false),
              showTime: item?.showTime || false,
              format: item && item.showTime ? (!openObj[dataIndex + index] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYYMMDD HHmmss') : (!openObj[dataIndex + index] ? 'YYYY-MM-DD' : 'YYYYMMDD'),
              value: record && dataIndex in record && record[dataIndex] ? moment(record[dataIndex], item?.format || dayFormat) : null,
              disabledDate: item.disabledDate || null, // 限制日期选择
              ref: ref => this[dataIndex + index] = ref,
              onChange: (e) => this.handleInputChange(index, e, item, record),
              onBlur: () => this.handleSetSelectOpenFlag(index, item, 'blur'),
              onFocus: () => this.handleSetSelectOpenFlag(index, item, 'focus'),
              onOpenChange: (isOpen) => this.handleOpenChangeData(index, item, isOpen),
              onKeyDown: (e) => this.handleKeyDown(dataIndex, index, item, e),
            };
            if (item?.autoOpenFlag !== 'N' && record?.autoOpenFlag !== 'N') { // 是否自动展开弹窗
              return (
                <DatePicker {...datePickerAttr} open={openObj[dataIndex + index] || false} />
              );
            } else {
              return (
                <DatePicker {...datePickerAttr} />
              );
            }
          } else if (record?.editingFlag !== 'N' && (item?.inputType === 'TimePicker' || item?.inputType === 'Time')) {
            return (
              <TimePicker
                id={dataIndex + index}
                style={{ width: width }}
                disabled={!propsAdmID || item?.disabled === 'Y' || record[dataIndex + 'DisabledFlag'] === 'Y' || (item && 'disabledDataIndex' in item ? !!(record[item.disabledDataIndex]) : false)}
                ref={ref => this[dataIndex + index] = ref}
                format={item?.format || timeFormat}
                // defaultOpenValue={moment('00:00:00', item?.format || timeFormat)}
                value={record && dataIndex in record && record[dataIndex] ? moment(record[dataIndex], item?.format || timeFormat) : null}
                onChange={(e) => this.handleInputChange(index, e, item, record)}
                onOpenChange={(isOpen) => this.handleOpenChangeData(index, item, isOpen)}
              />
            )
          } else if (record?.editingFlag !== 'N' && (item?.inputType === 'inputNumber' || item?.inputType === 'InputNumber')) {
            return (
              <Input
                // type="number"
                // className="input-number"
                // pattern="[0-9]*[.]?[0-9]+"
                id={dataIndex + index}
                placeholder={item.placeholder ? item.placeholder : '请输入'}
                disabled={!propsAdmID || item?.disabled === 'Y' || record[dataIndex + 'DisabledFlag'] === 'Y' || (item && 'disabledDataIndex' in item ? !!(record[item.disabledDataIndex]) : false)}
                style={{ width: width }}
                ref={ref => this[dataIndex + index] = ref}
                value={record && dataIndex in record ? record[dataIndex] : undefined}
                onChange={(e) => this.handleInputChange(index, e.target.value, item, record)}
                onBlur={() => this.handleSetSelectOpenFlag(index, item, 'blur')}
                onFocus={() => this.handleSetSelectOpenFlag(index, item, 'focus')}
                onKeyDown={(e) => this.handleKeyDown(dataIndex, index, item, e)}
                onCompositionStart={(e) => this.handleComposition(index, e.target.value, item, record, 'compositionstart')}
                onCompositionUpdate={(e) => this.handleComposition(index, e.target.value, item, record, 'compositionupdate')}
                onCompositionEnd={(e) => this.handleComposition(index, e.target.value, item, record, 'compositionend')}
              />);
          } else if (item?.inputType === 'Switch') {
            if (record?.editingFlag !== 'N') {
              return (
                <Switch
                  id={dataIndex + index}
                  checkedChildren={item?.checkedChildren || '是'}
                  unCheckedChildren={item?.unCheckedChildren || '否'}
                  disabled={item.disabled === 'Y' ? true : false}
                  ref={ref => this[dataIndex + index] = ref}
                  checked={record && dataIndex in record ? (record[dataIndex] === 'Y' ? true : false) : false}
                  onChange={(e) => this.handleInputChange(index, e ? 'Y' : 'N', item, record)}
                />
              )
            } else {
              // 下拉框取描述
              let switchDesc = text === 'Y' ? '是' : '否';
              return (
                tooltipFlag !== 'N' ? (
                  <Tooltip title={switchDesc}>
                    <span className="ellipsis" style={{ width: '100%', display: 'block' }}>{switchDesc}</span>
                  </Tooltip>
                ) : switchDesc
              )
            }
          } else if (record?.editingFlag !== 'N' && (item?.inputType === 'TextArea' || item?.inputType === 'Labelarea')) {
            return (
              <TextArea
                id={dataIndex + index}
                autoSize={{ minRows: item.minRows || 1, maxRows: item.maxRows || 12 }}
                placeholder={item.placeholder ? item.placeholder : '请输入'}
                style={{ width: width }}
                disabled={!propsAdmID || item?.disabled === 'Y' || record[dataIndex + 'DisabledFlag'] === 'Y' || (item && 'disabledDataIndex' in item ? !!(record[item.disabledDataIndex]) : false)}
                ref={ref => this[dataIndex + index] = ref}
                value={record && dataIndex in record ? record[dataIndex] : undefined}
                onChange={(e) => this.handleInputChange(index, e.target.value, item, record)}
                onKeyDown={(e) => this.handleKeyDown(dataIndex, index, item, e)}
                onDoubleClick={(e) => this.handleEMRDoubleClick(dataIndex, index, item, e)}
              />
            )
          } else if (record?.editingFlag !== 'N' && item?.inputType === 'Input') {
            return (
              <Input
                id={dataIndex + index}
                placeholder={item.placeholder ? item.placeholder : '请输入'}
                style={{ width: width }}
                disabled={!propsAdmID || item?.disabled === 'Y' || record[dataIndex + 'DisabledFlag'] === 'Y' || (item && 'disabledDataIndex' in item ? !!(record[item.disabledDataIndex]) : false)}
                ref={ref => this[dataIndex + index] = ref}
                value={record && dataIndex in record ? record[dataIndex] : undefined}
                onChange={(e) => this.handleInputChange(index, e.target.value, item, record)}
                onKeyDown={(e) => this.handleKeyDown(dataIndex, index, item, e)}
                onDoubleClick={(e) => this.handleEMRDoubleClick(dataIndex, index, item, e)}
              />
            )
          } else if (record?.editingFlag !== 'N' && item?.inputType === 'InputTable') {
            return (
              <Input
                id={dataIndex + index}
                placeholder={item.placeholder ? item.placeholder : '输入关键字回车搜索'}
                style={{ width: width }}
                disabled={item.disabled === 'Y' || (item && 'disabledDataIndex' in item ? !!(record[item.disabledDataIndex]) : false)}
                value={record && dataIndex in record ? record[dataIndex] : undefined}
                onClick={item.onClick || null}
                ref={ref => this[dataIndex + index] = ref}
                onChange={(e) => this.handleInputChange(index, e.target.value, item, record)}
                // onPressEnter={(e) => this.handleShowTableModal(e, item, index, record)}
                onKeyDown={(e) => this.handleKeyDown(dataIndex, index, item, e, record)}
              />
            )
          } else {
            return (
              tooltipFlag !== 'N' ? (
                <Tooltip title={text}>
                  <span className="ellipsis" style={{ width: '100%', display: 'block' }}>{text}</span>
                </Tooltip>
              ) : text
            )
          }
        }
      }
    }
    this.setState({ filterColumns });
  }

  //日期面板打开/关闭
  handleOpenChangeData = (index, item, isOpen) => {
    this.handleSetSelectOpenFlag(index, item, isOpen ? 'focus' : 'blur');
  }

  // 搜索框search
  handleSelectSearch = (item, value, index) => {
    if (!(item && 'trigger' in item && item.trigger === 'enter')) { // 下拉搜索触发方式为回车不自动触发查询
      this.handleRemoteSearch(item, value, index);
    }
  }

  // 搜索框键盘事件
  handleSelecttKeyDown = (item, e, index) => {
    if (e.keyCode == '13') {
      this.handleRemoteSearch(item, e.target.value, index);
    }
  }

  // 远程搜索
  handleRemoteSearch = (item, value, index) => {
    this.state.filterTableData[index].loading = 'Y';
    this.setState({});
    this.getSearchSelectData(value, item, data => {
      this.state.filterTableData[index].loading = 'N';
      this.state.filterTableData[index].detailItem = data;
      this.setState({}, () => {
        this.handleFilterColumns();
      })
    });
  }

  // 远程搜索
  getSearchSelectData = (value, item, callback) => {
    const { propsAdmID } = this.state;
    value = value.replace(/^\s+/, '').replace(/\s+$/, '');
    if (value === '') { // || !item?.linkCode
      callback([]);
      return;
    }
    if (this.timeout) {
      clearTimeout(this.timeout);
      this.timeout = null;
    }
    async function getData() {
      try {
        let data = {
          params: [{
            admID: propsAdmID,
            desc: value,
            inputDesc: value,
            inputValue: value,
            searchWords: value,
          }],
          pagination: [{
            pageSize: 100,
            currentPage: 1
          }]
        }
        let res = await React.$asyncPost(this, item?.linkCode || '02020352', data);
        let selectData = res && 'result' in res && res.result ? (
          'rows' in res.result && res.result.rows ? res.result.rows : (
            'Data' in res.result ? res.result.Data : (
              'data' in res.result ? res.result.data : 'for_in'
            ))) : 'for_in';
        if (selectData === 'for_in') {
          selectData = [];
          for (let keys in res) {
            if (res[keys] && Array.isArray(res[keys]) && res[keys].length > 0) {
              selectData = res[keys];
              break
            }
          }
        }
        callback(selectData);
      } catch (error) {
        console.log(error)
        callback([]);
      }
    }
    this.timeout = setTimeout(getData, 500);
  }

  //列跳转设置
  handleKeyDown = (dataIndex, index, item, e, record) => {
    const key = e.key;
    const keyCode = e.keyCode;
    if (keyCode == '13' || keyCode == '39') { // 回车和右箭头
      if (item?.inputType === 'InputTable' && keyCode == '13') { // InputTable并且回车时打开弹窗
        e?.preventDefault();
        this.handleShowTableModal(e, item, index, record)
      } else {
        let selectionEnd = 0;
        let selectionInputType = ['Input', 'InputNumber', 'inputNumber', 'InputTable', 'TextArea', 'Labelarea'];
        if (selectionInputType.indexOf(item?.inputType || '') > -1) {
          let currentVal = e.target.value;
          selectionEnd = this[dataIndex + index]?.input?.selectionEnd || 0;
          selectionEnd = currentVal.length - selectionEnd;
        }
        !selectionEnd && e?.preventDefault();
        !selectionEnd && this.getFocusNext(index, item, 'next');
      }
    } else if (keyCode == '37') { // 左箭头
      let selectionStart = this[dataIndex + index]?.input?.selectionStart || 0;
      !selectionStart && e?.preventDefault();
      !selectionStart && this.getFocusNext(index, item, 'prev');
    } else if (keyCode == '38') { // 光标上移
      e?.preventDefault();
      this.getNextJumpAbleRowSubscript(index, item, 'prev', e)
    } else if (keyCode == '40') { // 光标下移
      e?.preventDefault();
      this.getNextJumpAbleRowSubscript(index, item, 'next', e);
    } else if (item?.inputType === 'inputNumber' || item?.inputType === 'InputNumber') {
      if (/^[0-9]$/.test(key) || /^[0-9]$/.test(String.fromCharCode(keyCode)) || keyCode === 8 || keyCode === 46 || keyCode === 110) { // 当前按下的是数字键，删除键，小数点
        this.isOnComposition = false;
      }
    }
  }

  // 获取下一个可跳转的行下标并跳转
  getNextJumpAbleRowSubscript = (index, item, type, e) => {
    let { filterTableData } = this.state;
    if (item?.inputType === 'Select' || item?.inputType === 'TimePicker' || item?.inputType === 'Time') return;
    function getNextIndex(currentIndex) {
      if ((currentIndex < 0 && type === 'prev') || (filterTableData.length < currentIndex && type === 'next')) {
        return 'none';
      }
      if (type === 'prev') {
        currentIndex = currentIndex - 1;
      } else {
        currentIndex = currentIndex + 1;
      }
      let currentEditingFlag = filterTableData[currentIndex]?.editingFlag || '';
      if (currentEditingFlag !== 'N') {
        return currentIndex;
      } else {
        return getNextIndex(currentIndex);
      }
    }
    let nextIndex = getNextIndex(index);
    let nextDataIndex = item?.dataIndex || '';
    if (nextIndex !== 'none' && nextDataIndex) {
      let currentDataIndex = nextDataIndex + nextIndex;
      nextDataIndex && this[currentDataIndex] && this[currentDataIndex].focus ? this[currentDataIndex].focus() : '';
    }
  }

  // 设置下拉框是否打开
  handleSetSelectOpenFlag = Util.debounce((index, item, type) => {
    let openObj = {};
    let dataIndex = item?.dataIndex || '';
    let currentDataIndex = dataIndex + index;
    if (type === 'focus') {
      openObj[currentDataIndex] = true;
      if (item?.inputType === 'Select' || item?.inputType === 'SearchSelect') { // 下拉框/日期框获取焦点
        setTimeout(() => {
          document.querySelector('input#' + dataIndex + index) && document.querySelector('input#' + dataIndex + index)?.focus();
        }, 300)
      }
    } else {
      openObj = { ...this.state.openObj };
      openObj[currentDataIndex] = false;
      this.isOnComposition = false;
    }
    this.setState({ openObj }, () => {
      this.handleFilterColumns();
    });
  })

  // 获取焦点
  getFocusNext = (index, item, type = 'next') => {
    let { filterColumns } = this.state;
    let currentIndex = 0;
    let operateColumns = filterColumns && [...filterColumns].filter(item => !!item.inputType); // 获取可操作表头的数据
    for (let i = 0; i < operateColumns.length; i++) {
      if (operateColumns[i].dataIndex === item.dataIndex) {
        currentIndex = i;
        break;
      }
    }
    if ((operateColumns.length - 1 === currentIndex && type === 'next') || item?.enterNextRow === 'Y') { // 切换下一个并且为最后一个时
      this.addTableData('auto'); // 可以新增一行
    } else if ((type === 'prev' && currentIndex > 0) || (type === 'next' && currentIndex > -1)) {
      let count = type === 'next' ? currentIndex + 1 : currentIndex - 1;
      let nextDataIndex = operateColumns[count]?.dataIndex || '';
      let currentDataIndex = nextDataIndex + index;
      nextDataIndex && this[currentDataIndex] && this[currentDataIndex].focus ? this[currentDataIndex].focus() : '';
    }
  }

  handleComposition = (index, val, item, record, type) => {
    const isChrome = navigator.userAgent.indexOf('Chrome') > -1;
    console.log('type', type)
    if (type === 'compositionend') {
      this.isOnComposition = false;
      if (!this.isOnComposition && isChrome) {
        this.handleInputChange(index, val, item, record)
      }
    } else {
      this.isOnComposition = true;
    }
  }

  handleInputChange = (index, val, item, record) => {
    const { modalTableSelectBy, totalAmountCalculation } = this.props;
    let { filterTableData } = this.state;
    let dataIndex = item?.dataIndex || '';
    let inputType = item?.inputType || 'Input';
    let computeFlag = item?.computeFlag || '';
    if (inputType === 'DatePicker' || item.inputType === 'Date') { // 日期
      record.autoOpenFlag = 'Y'; // 新增时不自动打开日期选择框，选择过一次之后左右键切回来自动打开
      val = val ? moment(val).format(item?.format || dayFormat) : undefined;
    } else if (inputType === 'TimePicker' || inputType === 'Time') { // 时间
      val = val ? moment(val).format(item?.format || timeFormat) : undefined;
    } else if (inputType === 'Select') { // 下拉框
      let descDataIndex = dataIndex && dataIndex.indexOf('ID') > -1 ? dataIndex.replace('ID', 'Desc') : dataIndex + 'Desc';
      let currentValue = Util.returnDataCccordingToAttributes(item.detailItem, val, item?.valueindex || 'id')[item?.descindex || item?.descIndex || 'descripts'] || '';
      record[descDataIndex] = currentValue;
    } else if (inputType === 'SearchSelect') { // 动态下拉
      let idDataIndex = '', currentValue = '';
      if (item?.valueindex === 'descripts') {
        idDataIndex = dataIndex && dataIndex.indexOf('Desc') > -1 ? dataIndex.replace('Desc', 'ID') : dataIndex + 'ID';
        currentValue = Util.returnDataCccordingToAttributes(record.detailItem, val, 'descripts')?.id || '';
      } else {
        idDataIndex = dataIndex && dataIndex.indexOf('ID') > -1 ? dataIndex.replace('ID', 'Desc') : dataIndex + 'Desc';
        currentValue = Util.returnDataCccordingToAttributes(record.detailItem, val, 'id')[item?.descindex || item?.descIndex || 'descripts'] || '';
      }
      record[idDataIndex] = currentValue;
    } else if (inputType === 'InputTable' && !val) { // 下拉列表
      record.detailRowData = {};
      if (modalTableSelectBy !== 'currentElement') { // 不只取当前元素时清空行数据
        filterTableData[index] = {
          key: record?.key || index,
          [dataIndex]: val,
          modifyFlag: 'Y'
        };
        record = {};
      }
    } else if (inputType === 'inputNumber' || inputType === 'InputNumber') {
      if (this.isOnComposition) return;
      val = val.replace(!/^[0-9]*[.]?[0-9]+$/, '');
    }
    // 修改数量，计算总金额
    if (computeFlag === 'amt') {
      let recordRp = parseFloat((parseFloat(record[item?.rpDataIndex || 'rp'] || 0)).toFixed(4).replace('.', ''));
      let recordSp = parseFloat((parseFloat(record[item?.spDataIndex || 'sp'] || 0)).toFixed(4).replace('.', ''));
      record[item?.spAmtDataIndex || 'spAmt'] = (recordSp * val) / 10000; // 售价金额
      record[item?.rpAmtDataIndex || 'rpAmt'] = (recordRp * val) / 10000; // 进价金额
    }
    record[dataIndex] = val;
    record.modifyFlag = 'Y';
    this.setState({}, () => {
      if (((inputType === 'DatePicker' || inputType === 'Date') && val) || inputType === 'Select') { // 选择后下一个获取焦点
        this.getFocusNext(index, item, 'next');
      }
      if (computeFlag) {
        totalAmountCalculation && totalAmountCalculation('N', val); // 修改数量重新计算总金额
      }
    });
  }

  // 新增行 - 单条根据表头数据添加
  addTableData = (trigger, timeOutFocus = 0) => {
    try {
      const { verifyEmptyDataFlag } = this.props;
      let { filterTableData, filterColumns, propsAdmID, selectedRowKeys } = this.state;
      let currentKey = filterTableData && filterTableData.length > 0 ? filterTableData.length : 0;
      let firstDataIndex = filterColumns[0]?.dataIndex || '';
      if (!propsAdmID) return;
      if (verifyEmptyDataFlag === 'Y') { // 校验是否已存在空数据
        let modifyFlag = 'N';
        for (let i = 0; i < filterTableData.length; i++) {
          if (filterTableData[i].modifyFlag === 'init' && filterTableData[i].editingFlag !== 'N') {
            modifyFlag = 'Y';
            break;
          }
        }
        if (modifyFlag === 'Y') {
          trigger === 'click' ? message.warning('已存在一条空数据，请先录入！') : ''; // 手动点击新增的时候有空数据提示
          firstDataIndex && this[firstDataIndex + (currentKey - 1)] && this[firstDataIndex + (currentKey - 1)].focus ? this[firstDataIndex + (currentKey - 1)].focus() : '';
          return;
        }
      }
      let currentDefaultValues = this.getDefaultData();
      let addValue = {
        ...currentDefaultValues,
        key: currentKey,
        autoOpenFlag: 'N',
        modifyFlag: verifyEmptyDataFlag === 'Y' ? 'init' : 'N'
      }
      if (selectedRowKeys && selectedRowKeys.length > 0 && trigger !== 'auto') {
        filterTableData.splice(parseInt(selectedRowKeys[selectedRowKeys.length - 1]) + 1, 0, addValue)
      } else {
        filterTableData.push(addValue);
      }
      this.setState({ filterTableData: Util.addKeyValueToDataSource(filterTableData, '', 0) }, () => {
        trigger !== 'click' && trigger !== 'auto' && this.handleFilterColumns(); // 组件外部调用时
        setTimeout(() => {
          firstDataIndex && this[firstDataIndex + currentKey] && this[firstDataIndex + currentKey].focus ? this[firstDataIndex + currentKey].focus() : '';
        }, timeOutFocus || 0)
      });
    } catch (error) {
      console.log(error);
    }
  }

  // 添加行 - 多行添加
  handleMultilineAdd = (arr) => {
    let { filterTableData } = this.state;
    if (arr && Array.isArray(arr) && arr.length > 0) {
      filterTableData = [...filterTableData, ...arr].filter(item => item.modifyFlag !== 'init');
      for (let i = 0; i < filterTableData.length; i++) {
        let currentRecord = filterTableData[i];
        filterTableData[i].key = i;
        filterTableData[i].editingFlag = currentRecord && 'editingFlag' in currentRecord ? currentRecord.editingFlag : 'N';
      }
      this.setState({ filterTableData })
    }
  }

  // 保存
  handleSave = () => {
    let { filterTableData } = this.state;
    let saveTableData = JSON.parse(JSON.stringify(filterTableData));
    saveTableData = saveTableData.filter(item => item.modifyFlag !== 'init');
    for (let i = 0; i < saveTableData.length; i++) {
      saveTableData[i].editingFlag = 'N';
      saveTableData[i].modifyFlag = 'N';
      saveTableData[i].check = undefined;
      saveTableData[i].detailItem = undefined;
      saveTableData[i].seqNo = i + 1;
    }
    return saveTableData;
  }

  // 点保存修改数据状态
  handleClearRecord = () => {
    let { filterTableData } = this.state;
    for (let i = 0; i < filterTableData.length; i++) {
      if (filterTableData[i].modifyFlag !== 'init') {
        filterTableData[i].editingFlag = 'N';
        filterTableData[i].modifyFlag = 'N';
      }
    }
    this.setState({ filterTableData });
  }

  // 多行删除
  handleMultilineDelete = () => {
    const { recordID, rowIDName } = this.props;
    const { selectedRowKeys, selectedRows } = this.state;
    if (!(selectedRows && selectedRows.length > 0)) return;
    let recordIDArr = [];
    for (let i = 0; i < selectedRows.length; i++) {
      let id = rowIDName ? selectedRows[i][rowIDName] : selectedRows[i][recordID];
      if (id) {
        recordIDArr.push(selectedRows[i].key)
      }
    }
    if (recordIDArr && recordIDArr.length > 0) {
      console.log('recordIDArr', recordIDArr)
      this.handleDelete('multilin', recordIDArr);
    } else {
      this.deleteRow('multilin', selectedRowKeys)
    }
  }

  // 行内删除
  handleLnIineDelete = (record, index, e, isRevert) => {
    React.$stopPropagation(e);
    let { recordID, rowIDName } = this.props;
    if (recordID && (record[recordID] || (rowIDName && record[rowIDName]))) {
      this.handleDelete('inLine', [], isRevert, index, record);
    } else {
      this.deleteRow('inLine', record.key);
    }
  }

  // 删除
  handleDelete = (deleteFlag, deleteArr, isRevert, index, record) => {
    const { selectedRows } = this.state;
    let { deleteCode, recordID, rowIDName, userData, inLineDeleteType } = this.props;
    if (this.props && this.props.handleDelete) { // 传入删除方法存在则走传入的，否则走统一的
      this.props.handleDelete(deleteFlag === 'inLine' ? record : deleteArr, () => this.deleteRow(deleteFlag, deleteFlag === 'inLine' ? record.key : deleteArr));
    } else {
      if (deleteCode === 'addDeleteFlag') { // 不实际删除，添加删除标志
        if (deleteFlag === 'inLine') { // 单行删除添加删除标志
          this.state.filterTableData[index].statusFlag = isRevert === 'revert' ? '' : 'D';
        } else {
          for (let i = 0; i < this.state.filterTableData.length; i++) {
            for (let j = 0; j < selectedRows.length; j++) {
              if (this.state.filterTableData[i].key === selectedRows[j].key) {
                this.state.filterTableData[i].statusFlag = isRevert === 'revert' ? '' : 'D';
              }
            }
          }
        }
        this.setState({}, () => {
          message.success(isRevert === 'revert' ? '还原成功' : '删除成功');
        });
      } else if (deleteCode) { // 传入删除接口删除
        let recordIDArr = [];
        for (let i = 0; i < selectedRows.length; i++) {
          recordIDArr.push((rowIDName ? selectedRows[i][rowIDName] : selectedRows[i][recordID]))
        }
        let deleteIndex = recordID && typeof (recordID) === 'string' && recordID.indexOf('ID') > -1 && recordID.replace('ID', 'Arr');
        let inLineID = '';
        if (record && Object.prototype.toString.call(record) === '[object Object]' && deleteFlag === 'inLine') {// 单行删除ID  inLineDeleteType - 传入数据类型
          inLineID = rowIDName ? record[rowIDName] : record[recordID];
        }
        let data = {
          params: [{
            [recordID + (deleteFlag === 'inLine' ? '' : 'Arr')]: deleteFlag === 'inLine' ? (inLineDeleteType === 'arr' ? [inLineID] : inLineID) : recordIDArr,
            [deleteIndex]: deleteFlag === 'inLine' ? (inLineDeleteType === 'arr' ? [inLineID] : inLineID) : recordIDArr,
            updateUserID: userData?.userID || ''
          }]
        }
        try {
          let res = React.$asyncPost(this, deleteCode, data);
          message.success(res && res.errorMessage ? res.errorMessage : '删除成功');
          this.deleteRow(deleteFlag, deleteFlag === 'inLine' ? record.key : deleteArr);
        } catch (error) {
          console.log(error)
        }
      } else {
        this.deleteRow(deleteFlag, deleteFlag === 'inLine' ? record.key : deleteArr);
      }
    }
  }

  // 本地删除数据
  deleteRow = (deleteFlag, key) => {
    let { filterTableData } = this.state;
    if (deleteFlag === 'inLine') {
      filterTableData = filterTableData.filter(item => item.key !== key);
    } else if (key && Array.isArray(key) && key.length > 0) {
      for (let i = 0; i < key.length; i++) {
        filterTableData = filterTableData.filter(item => item.key !== key[i]);
      }
    }
    filterTableData = Util.addKeyValueToDataSource(filterTableData, '', 0);
    if (deleteFlag === 'multilin') { // 多行删除删除后清除选中数据
      this.state.selectedRowKeys = [];
      this.state.selectedRows = [];
    }
    this.setState({ filterTableData, rowID: '' }, () => {
      this.props.updateTableData && this.props.updateTableData(this.state.filterTableData);
      this.props.rowSelectionPublic && this.props.rowSelectionPublic([], []);
    });
  }

  // 操作行
  onClickRowPublic = (record) => {
    let { idIndex } = this.props;
    return {
      // 单击行选中
      onClick: () => {
        if (record?.editingFlag === 'N') {
          if (this.state.rowID === '' || (this.state.rowID !== '' && (this.state.rowID !== record[idIndex || 'key']))) {
            this.setState({ rowID: record[idIndex || 'key'] }, () => {
              this.props.onClickRowPublic && this.props.onClickRowPublic(record);
            });
          } else {
            this.setState({ rowID: '' }, () => {
              this.props.onClickRowPublic && this.props.onClickRowPublic({});
            });
          }
        }
      }
    }
  }

  // 选中行操作
  setRowClassNamePublic = (record) => {
    let { idIndex } = this.props;
    return record[idIndex || 'key'] === this.state.rowID && record?.editingFlag === 'N' ? 'clickRowStyle' : '';
  }

  // 复制
  handleCopy = () => {
    let { selectedRows, filterTableData, filterColumns } = this.state;
    if (!(selectedRows && selectedRows.length > 0)) return;
    filterTableData = filterTableData.filter(item => item.modifyFlag !== 'init');
    let copyData = Util.customDeepCopy(selectedRows);
    for (let i = 0; i < copyData.length; i++) {
      let recordData = copyData[i];
      for (let keys in recordData) {
        let columnsItem = Util.returnDataCccordingToAttributes(filterColumns, keys, 'dataIndex');
        if (columnsItem?.copyClearFlag === 'Y') { // 根据清除标志清除部分复制内容
          recordData[keys] = undefined;
        }
        if (columnsItem?.copyDisabledFlag === 'Y') { // 字段禁用标志
          recordData[keys + 'DisabledFlag'] = 'Y';
        }
      }
    }
    filterTableData = Util.addKeyValueToDataSource([...filterTableData, ...copyData], '', 0);
    this.setState({ filterTableData }, () => {
      message.success('复制成功!');
      this.props.updateTableData && this.props.updateTableData(this.state.filterTableData);
      let firstDataIndex = filterColumns[0]?.dataIndex || '';
      let currentDataIndex = firstDataIndex + filterTableData.length;
      currentDataIndex && this[currentDataIndex] && this[currentDataIndex].focus ? this[currentDataIndex].focus() : '';
    });
  }

  // 上移
  handleUp = () => {
    let { selectedRowKeys, filterTableData } = this.state;
    if (!(selectedRowKeys && selectedRowKeys.length > 0)) {
      message.warning('请勾选要上移的行!');
      return;
    };
    let keys = selectedRowKeys;
    let data = filterTableData;
    let newKeys = [];
    keys = keys.sort(function (m, n) {
      if (m < n) return -1;
      else if (m > n) return 1;
      else return 0;
    });
    for (let i = 0; i < keys.length; i++) {
      if (keys[i] === 0) {
        newKeys.push(keys[i]);
        continue;
      }
      let curRowData = data[keys[i]];
      let curRowKey = curRowData.key;
      let upRowData = data[keys[i] - 1];
      let upRowKey = upRowData.key;
      upRowData.key = curRowKey;
      curRowData.key = upRowKey;
      data[keys[i]] = upRowData;
      data[keys[i] - 1] = curRowData;
      newKeys.push(keys[i] - 1);
    }
    this.setState({
      filterTableData: data,
      selectedRowKeys: newKeys
    })
  }

  // 下移
  handleDown = () => {
    let { selectedRowKeys, filterTableData } = this.state;
    if (!(selectedRowKeys && selectedRowKeys.length > 0)) {
      message.warning('请勾选要下移的行!');
      return;
    };
    let keys = selectedRowKeys;
    let data = filterTableData;
    let newKeys = [];
    keys = keys.sort(function (m, n) {
      if (m < n) return -1;
      else if (m > n) return 1;
      else return 0;
    });
    for (let i = keys.length - 1; i >= 0; i--) {
      if (keys[i] === data.length - 1) {
        newKeys.push(keys[i]);
        continue;
      }
      let curRowData = data[keys[i]];
      let upRowData = data[keys[i] + 1];
      let curRowKey = curRowData.key;
      let upRowKey = upRowData.key;
      upRowData.key = curRowKey;
      curRowData.key = upRowKey;
      data[keys[i]] = upRowData;
      data[keys[i] + 1] = curRowData;
      newKeys.push(keys[i] + 1);
    }
    this.setState({
      filterTableData: data,
      selectedRowKeys: newKeys
    });
  }

  // 监听键盘操作
  handleOnKeydown = (e) => {
    var e = window.event || e;
    switch (e.keyCode) {
      case 38: //上
        this.handleUp()
        break;
      case 40: //下
        this.handleDown();
        break;
    }
  }

  // 获取弹窗列表数据
  getModalTableColumns = async () => {
    try {
      const { modalTableComponentName } = this.state;
      let data = {
        params: [{
          compontName: modalTableComponentName || 'CommonInputTableModal',
          type: 'C',
        }]
      }
      let res = await React.$asyncPost(this, '01040073', data);
      let modalColumns = res.result?.C || [];
      if (modalColumns && modalColumns.length > 0) {
        let modalTotalWidth = parseInt(res?.totalWidth || 0) < 460 ? 460 : res?.totalWidth;
        this.setState({
          modalColumns,
          modalTotalWidth
        })
      }
    } catch (error) {
      console.log(error);
    }
  }

  // 打开弹窗
  handleShowTableModal = async (e, item, index, record) => {
    let searchDesc = e.target?.value || '';
    if (!searchDesc) {
      message.info('请输入关键字回车搜索！');
      return;
    }
    let { modalColumnsInfo } = this.state;
    let dataIndex = item?.dataIndex || '';
    let top = document.getElementById(dataIndex + index).getBoundingClientRect().top + 40;
    let left = document.getElementById(dataIndex + index).getBoundingClientRect().left;
    let modalColumns = [], modalTotalWidth = 0, modalTableComponentName = item?.componentName || item?.modalTableComponentName || 'CommonInputTableModal';
    let columnsInfo = modalColumnsInfo && modalTableComponentName in modalColumnsInfo && modalColumnsInfo.modalTableComponentName ? modalColumnsInfo.modalTableComponentName : [];
    let columns = columnsInfo?.columns || [];
    if (columns && columns.length > 0) {
      modalColumns = columns;
      modalTotalWidth = columnsInfo?.totalWidth || item?.totalWidth || 0;
    } else {
      let data = {
        params: [{
          compontName: modalTableComponentName,
          type: 'C',
        }]
      }
      let res = await React.$asyncPost(this, '01040073', data);
      modalColumns = res.result?.C || [];
      modalTotalWidth = res?.totalWidth || 0;
      // 将数据设置到表头数据中
      item.columns = modalColumns;
      item.totalWidth = modalTotalWidth;
      // 将数据存到当前界面，避免重复查询
      modalColumnsInfo[modalTableComponentName] = {
        columns: modalColumns,
        totalWidth: modalTotalWidth
      }
    }
    modalTotalWidth = isNaN(parseInt(modalTotalWidth)) ? 460 : parseInt(modalTotalWidth);
    if (modalTotalWidth < 460) { // 存在分页弹窗宽度至少460
      modalTotalWidth = 460
    }
    this.state.modalColumns = modalColumns;
    this.state.modalTotalWidth = modalTotalWidth;
    this.state.modalTableComponentName = modalTableComponentName;
    let innerHeight = window.innerHeight;
    let innerWidth = window.innerWidth;
    let modalDom = document.getElementById('public-editable-gundong');
    let modalHeight = modalDom?.clientHeight || modalDom?.offsetHeight || 300;
    if ((top + modalHeight) > innerHeight) {
      top = top - (modalHeight + 82);
      if (top < 0) {
        top = innerHeight / 2 + modalHeight / 2;
      }
    }
    if ((left + modalTotalWidth) > innerWidth) {
      left = left - modalTotalWidth + parseInt(item?.width || 0);
      if (left < 0) {
        left = innerWidth / 2 - modalTotalWidth / 2;
      }
    }
    this.setState({
      top: top + 'px',
      left: left + 'px',
      modalPage: 1,
      modalRecordItem: item,
      modalRecordData: record,
      modalRecordIndex: index,
      searchDesc, // 查询的别名
      modalColumnsInfo
    }, () => {
      this.modalTableRef && this.modalTableRef.showModal && this.modalTableRef.showModal(); // 打开弹窗
      this.getModalListData();
    })
  }

  // 获取描述列表数据
  getModalListData = async () => {
    try {
      const { inputTableIncomingDepartmentFlag, getFrLocID } = this.props;
      const { modalPage, modalPageSize, searchDesc, modalRecordItem } = this.state;
      if (!(modalRecordItem && 'linkCode' in modalRecordItem && modalRecordItem.linkCode)) return;
      let locInfo = {}; // 科室信息
      if (inputTableIncomingDepartmentFlag === 'Y') { // inputTable是否传入基本信息科室树
        locInfo = getFrLocID && getFrLocID();
        if (locInfo?.error) { // 判断是否校验科室必填
          this.setState({ modalTableData: [], modalTotal: 0, modalTableLoading: false });
          return
        };
      }
      this.setState({ modalTableLoading: true });
      let data = {
        params: [{
          inputDesc: searchDesc,
          inputValue: searchDesc,
          searchWords: searchDesc,
          [modalRecordItem?.methodName || 'desc']: searchDesc,
          ...locInfo
        }],
        pagination: [{
          pageSize: modalPageSize,
          currentPage: modalPage
        }]
      }
      let res = await React.$asyncPost(this, modalRecordItem?.linkCode || '02020352', data);
      let modalTableData = res && 'result' in res && res.result ? (
        'rows' in res.result && res.result.rows ? res.result.rows : (
          'Data' in res.result ? res.result.Data : (
            'data' in res.result ? res.result.data : 'for_in'
          ))) : 'for_in';
      if (modalTableData === 'for_in') {
        modalTableData = [];
        for (let keys in res) {
          if (res[keys] && Array.isArray(res[keys]) && res[keys].length > 0) {
            modalTableData = res[keys];
            break
          }
        }
      }
      modalTableData = Util.addKeyValueToDataSource(modalTableData)
      this.setState({
        modalTableData,
        modalTotal: res.result?.total || res.result?.totalCount || 0,
        modalRowID: modalTableData && modalTableData.length > 0 ? modalTableData[0].key : '',
        modalTableLoading: false
      })
      setTimeout(() => {
        var gundong = document.getElementById('public-editable-gundong');
        gundong && (gundong.scrollTop = 0);
      }, 100)
    } catch (error) {
      this.setState({ modalTableData: [], modalTotal: 0, modalTableLoading: false });
    }
  }

  // 修改名称列表条数以及列数
  handleModalCompilePage = (page, pageSize) => {
    this.setState({ modalPage: page, modalPageSize: pageSize }, () => {
      this.getModalListData();
    })
  }

  // 键盘操作名称模态框数据
  handlePublicModalTableOnKeydown = (e) => {
    var e = window.event || e;
    let scroll_height = 26;
    let id = '';
    let oneArr = this.state.modalTableData && this.state.modalTableData.length > 0 ? this.state.modalTableData : [];
    switch (e.keyCode) {
      case 13:
        if (this.state.modalRowID) {
          let obj = {}
          for (var i = 0; i < oneArr.length; i++) {
            if (oneArr[i].key === this.state.modalRowID) {
              obj = i > 0 ? oneArr[i] : oneArr[0];
              break;
            }
          }
          this.handleConfirmSelection(obj);
        } else {
          message.info('请选中一条数据操作');
        }
        break;
      case 38: //上
        if (this.state.modalRowID) {
          for (var i = 0; i < oneArr.length; i++) {
            if (oneArr[i].key === this.state.modalRowID) {
              id = i > 0 ? oneArr[i - 1].key : oneArr[0].key;
              break;
            }
          }
          this.setState({ modalRowID: id })
          setTimeout(() => {
            var gundong = document.getElementById('public-editable-gundong');
            gundong && (gundong.scrollTop = gundong.scrollTop - scroll_height);
          }, 100)
        } else {
          this.setState({ modalRowID: oneArr[0].key })
        }
        break;
      case 40: //下
        if (this.state.modalRowID) {
          for (let i = 0; i < oneArr.length; i++) {
            if (oneArr[i].key === this.state.modalRowID) {
              id = i + 1 >= oneArr.length ? oneArr[oneArr.length - 1].key : oneArr[i + 1].key;
              break;
            }
          }
          this.setState({ modalRowID: id })
          setTimeout(() => {
            var gundong = document.getElementById('public-editable-gundong');
            gundong && (gundong.scrollTop = gundong.scrollTop + scroll_height);
          }, 100)
        } else {
          this.setState({ modalRowID: oneArr[0].key })
        }
        break;
    }
  }

  handleModalRowClick = (record) => {
    let idIndex = 'key';
    return {
      // 单击行选中
      onClick: () => {
        if (this.state.modalRowID === '' || (this.state.modalRowID && (this.state.modalRowID !== record[idIndex]))) {
          this.setState({ modalRowID: record[idIndex] });
        } else {
          this.setState({ modalRowID: '' });
        }
      },
      onDoubleClick: () => {
        this.handleConfirmSelection(record);
      }
    }
  }

  // 选择弹窗数据
  handleConfirmSelection = (record) => {
    const { modalTableSelectBy } = this.props;
    let { modalRecordIndex, modalRecordItem, modalRecordData, filterTableData } = this.state;
    if (record?.banFlag === 'Y') {
      message.error(record?.banDesc || '您选择的数据已停用！');
      return;
    }
    if (modalTableSelectBy === 'currentElement') { // 只取当前元素
      let dataIndex = modalRecordItem?.dataIndex || '';
      if (dataIndex) {
        filterTableData[modalRecordIndex][dataIndex] = record?.descripts || '';
        let idDataIndex = dataIndex && dataIndex.indexOf('Desc') > -1 ? dataIndex.replace('Desc', 'ID') : dataIndex + 'ID';
        filterTableData[modalRecordIndex][idDataIndex] = record?.id || '';
      }
    } else { // 直接取行数据赋值
      filterTableData[modalRecordIndex] = { ...modalRecordData, ...record, key: modalRecordData && 'key' in modalRecordData ? modalRecordData.key : (filterTableData?.length - 1) };
    }
    this.setState({ filterTableData }, () => {
      this.modalTableRef && this.modalTableRef.handleCancel();
      this.props.updateTableData && this.props.updateTableData(this.state.filterTableData); // 更新父组件tableData
      // 选择完光标跳转下一个
      this.getFocusNext(modalRecordIndex, modalRecordItem, 'next');
    });
  }

  handleModalSetClassName = (record) => {
    let idIndex = 'key';
    return record[idIndex] === this.state.modalRowID ? 'clickRowStyle' : (record?.banFlag === 'Y' ? 'common-row-color-ff868c' : '');
  }

  // 多行编辑
  handleMultilineModify = () => {
    const { filterTableData, selectedRowKeys } = this.state;
    if (!(selectedRowKeys && selectedRowKeys.length > 0)) return;
    for (let i = 0; i < filterTableData.length; i++) {
      if (selectedRowKeys.indexOf(filterTableData[i].key) > -1) {
        filterTableData[i].editingFlag = 'Y';
      }
    }
    this.setState({ filterTableData });
  }

  // 编辑
  handleCompile = (index, e) => {
    let { filterTableData } = this.state;
    React.$stopPropagation(e);
    filterTableData[index].editingFlag = 'Y';
    this.setState({});
  }

  // 双击事件
  handleEMRDoubleClick = (dataIndex, index, item, e) => {
    console.log('双击', dataIndex, index, item, e)
  }

  render() {
    const { _key, page, total, loading, pageSize, totalWidth, componentName, maxHeight, operationFlag, rowClickFlag, operationFixed, operationBtnFlag, rowSelectionDisabledFlag, rowSelectionPublic, operationAddBtnFlag, operationCopyBtnFlag,
      operationDeleteBtnFlag, operationMoveBtnFlag, modifyFlag, deleteFlag, handleSave, btnMoveFlag, handlePrint, handleViewEMR, handleSelectPrint, operationModifyBtnFlag, stopFlag, rowSelectionFlag
    } = this.props;
    const { filterColumns, filterTableData, propsAdmID, selectedRowKeys, selectedRows, top, left, modalTotal, modalTableData, modalTableLoading, modalTableComponentName, modalColumns, modalTotalWidth, modalPage } = this.state;
    const operationObj = {
      width: modifyFlag !== 'N' ? 130 : 68,
      title: '操作',
      align: 'center',
      key: 'operation',
      fixed: operationFixed ? operationFixed : null,
      render: (text, record, index) => {
        return (
          <>
            {modifyFlag !== 'N' ? (
              record?.editingFlag === 'N' ? ( // 已保存的可以点修改按钮进行修改
                <>
                  <Icon type="edit" style={{ color: '#108EE9' }}></Icon>
                  <span className="span" onClick={(e) => this.handleCompile(index, e)}>
                    编辑
                  </span>
                  <Divider type="vertical"></Divider>
                </>
              ) : (
                <>
                  <span style={{ cursor: 'no-drop' }}>
                    <Icon type="edit"></Icon>
                    编辑
                  </span>
                  <Divider type="vertical"></Divider>
                </>
              )
            ) : ''}
            {deleteFlag !== 'N' ? (
              record?.editingFlag === 'N' ? ( // 已保存的不让删除
                <span style={{ cursor: 'no-drop' }}>
                  <Icon type="delete"></Icon>
                  删除
                </span>
              ) : (
                <Popconfirm title="删除不可恢复，你确定要删除吗?" onClick={(e) => React.$stopPropagation(e)} onConfirm={(e) => this.handleLnIineDelete(record, index, e)}>
                  <Icon type="delete" className="common-record-delete-span"></Icon>
                  <span className="span common-record-delete-span">删除</span>
                </Popconfirm>
              )
            ) : ''}
          </>
        )
      }
    };
    // 列表多选操作
    let rowSelection = {
      selectedRowKeys,
      selectedRows,
      getCheckboxProps: record => {
        return {
          disabled: !!(rowSelectionDisabledFlag), // 由外部参数控制是否可选择
        }
      },
      onChange: (selectedRowKeys, selectedRows) => {
        this.setState({
          selectedRows,
          selectedRowKeys,
        }, () => {
          rowSelectionPublic && rowSelectionPublic(selectedRowKeys, selectedRows);
        })
      },
    };
    return (
      <div>
        <div
          tabIndex={1}
          style={{ outline: 'none' }}
          onKeyDown={btnMoveFlag === 'Y' ? this.handleOnKeydown : null}
          className={maxHeight ? 'table-body-height' : ''}
        >
          {operationBtnFlag === 'Y' ? (
            <div style={{ marginBottom: '12px' }}>
              {operationAddBtnFlag !== 'N' ? (
                propsAdmID ? (
                  <Tooltip title="支持勾选行插入">
                    <span onClick={() => this.addTableData('click')} className="common-color333">
                      <Icon className="doctor-add-splice" style={{ marginLeft: 0 }} />
                      新增
                    </span>
                  </Tooltip>
                ) : (
                  <span className="common-color999">
                    <Icon className="doctor-add-splice" style={{ marginLeft: 0 }} />
                    新增
                  </span>
                )
              ) : ''}
              {operationCopyBtnFlag !== 'N' ? (
                <>
                  {operationAddBtnFlag === 'N' ? '' : <Divider type="vertical" />}
                  <span onClick={this.handleCopy} className={!(selectedRowKeys && selectedRowKeys.length > 0) ? 'common-color999' : 'common-color333'}>
                    <Icon className="doctor-copy-splice" />
                    复制
                  </span>
                </>
              ) : ''}
              {operationModifyBtnFlag !== 'N' ? (
                <>
                  {operationAddBtnFlag === 'N' && operationCopyBtnFlag === 'N' ? '' : <Divider type="vertical" />}
                  <span onClick={this.handleMultilineModify} className={!(selectedRowKeys && selectedRowKeys.length > 0) ? 'common-color999' : 'common-color333'}>
                    <Icon className="doctor-menu-unfold-splice" />
                    编辑
                  </span>
                </>
              ) : ''}
              {operationDeleteBtnFlag !== 'N' ? (
                <>
                  {operationAddBtnFlag === 'N' && operationCopyBtnFlag === 'N' ? '' : <Divider type="vertical" />}
                  <span onClick={this.handleMultilineDelete} className={!(selectedRowKeys && selectedRowKeys.length > 0) ? 'common-color999' : 'common-color333'}>
                    <Icon className="doctor-delete-splice" />
                    删除
                  </span>
                </>
              ) : ''}
              {operationMoveBtnFlag !== 'N' ? (
                <>
                  {operationAddBtnFlag === 'N' && operationCopyBtnFlag === 'N' && operationDeleteBtnFlag === 'N' && operationModifyBtnFlag !== 'N' ? '' : <Divider type="vertical" />}
                  <span onClick={this.handleUp} className={!(selectedRowKeys && selectedRowKeys.length > 0) ? 'common-color999' : 'common-color333'}>
                    <Icon className="doctor-up-splice" />
                    上移
                  </span>
                  <Divider type="vertical" />
                  <span onClick={this.handleDown} className={!(selectedRowKeys && selectedRowKeys.length > 0) ? 'common-color999' : 'common-color333'}>
                    <Icon className="doctor-down-splice" />
                    下移
                  </span>
                </>
              ) : ''}
              {handleViewEMR ? (
                <>
                  {operationAddBtnFlag === 'N' && operationCopyBtnFlag === 'N' && operationDeleteBtnFlag === 'N' && operationModifyBtnFlag !== 'N' && operationMoveBtnFlag === 'N' ? '' : <Divider type="vertical" />}
                  <span onClick={() => handleViewEMR(true)} className={!propsAdmID ? 'common-color999' : 'common-color333'}>
                    <Icon className="patient-table" />
                    查看病历
                  </span>
                </>
              ) : ''}
              {handlePrint ? (
                <>
                  {operationAddBtnFlag === 'N' && operationCopyBtnFlag === 'N' && operationDeleteBtnFlag === 'N' && operationModifyBtnFlag !== 'N' && operationMoveBtnFlag === 'N' && !handleViewEMR ? '' : <Divider type="vertical" />}
                  <span onClick={() => handlePrint('')} className={!propsAdmID ? 'common-color999' : 'common-color333'}>
                    <Icon className="doctor-profile-splice" />
                    打印
                  </span>
                </>
              ) : ''}
              {handleSelectPrint ? (
                <>
                  {operationAddBtnFlag === 'N' && operationCopyBtnFlag === 'N' && operationDeleteBtnFlag === 'N' && operationModifyBtnFlag !== 'N' && operationMoveBtnFlag === 'N' && !handleViewEMR && !handlePrint ? '' : <Divider type="vertical" />}
                  <span onClick={() => handleSelectPrint(selectedRowKeys, selectedRows)} className={!(selectedRowKeys && selectedRowKeys.length > 0) ? 'common-color999' : 'common-color333'}>
                    <Icon className="doctor-profile-splice" />
                    选择打印
                  </span>
                </>
              ) : ''}
              {handleSave ? (
                <>
                  {operationAddBtnFlag === 'N' && operationCopyBtnFlag === 'N' && operationDeleteBtnFlag === 'N' && operationModifyBtnFlag !== 'N' && operationMoveBtnFlag === 'N' && !handleViewEMR && !handlePrint && !handleSelectPrint ? '' : <Divider type="vertical" />}
                  <span onClick={() => handleSave('')} className={!propsAdmID ? 'common-color999' : 'common-color333'}>
                    <Icon className="doctor-save-splice" />
                    保存
                  </span>
                </>
              ) : ''}
            </div>
          ) : ''}
          <PublicTablePagination
            param={{
              _key,
              page,
              total,
              loading,
              pageSize,
              componentName,
              x: totalWidth, // 表格的宽度
              data: filterTableData, // 表格数据
              columns: operationFlag === 'Y' ? [...filterColumns, operationObj] : filterColumns, // 表头配置
              y: maxHeight ? maxHeight + (operationBtnFlag === 'Y' || rowSelectionFlag === 'Y' ? 0 : 32) : 'auto',
              height: maxHeight ? maxHeight + (operationBtnFlag === 'Y' || rowSelectionFlag === 'Y' ? 50 : 82) + 'px' : 'auto',
            }}
            rowSelectionPublic={operationBtnFlag === 'Y' || rowSelectionFlag === 'Y' || rowSelectionPublic ? rowSelection : null}
            compilePage={this.props.compilePage || null}
            getColumns={this.props.getColumns || null}
            onClickRowPublic={rowClickFlag !== 'N' ? this.onClickRowPublic : null}
            setRowClassNamePublic={rowClickFlag !== 'N' ? this.setRowClassNamePublic : null}
          />
        </div>
        <div
          tabIndex={1}
          onKeyDown={this.handlePublicModalTableOnKeydown}
          style={{ outline: 'none' }}
        >
          <PublicModalTable
            id="public-editable-gundong"
            param={{
              top,
              left,
              stopFlag: stopFlag || 'Y', // 停用标志
              showPagination: true,
              page: modalPage,
              total: modalTotal,
              data: modalTableData,
              loading: modalTableLoading,
              componentName: modalTableComponentName,
              columns: modalColumns && modalColumns.length > 0 ? modalColumns : [],
              width: modalTotalWidth && parseInt(modalTotalWidth) > 1200 ? '1200px' : modalTotalWidth,
            }}
            onRef={ref => this.modalTableRef = ref}
            compilePage={this.handleModalCompilePage}
            getColumns={this.getModalTableColumns}
            onClickRowPublic={this.handleModalRowClick}
            setRowClassNamePublic={this.handleModalSetClassName}
          />
        </div>
      </div>
    )
  }
}

export default PublicTableinLineEditing;