"use strict";

var _vue = require("vue");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _ui = require("../../../ui");
var _utils = require("../../../ui/src/utils");
var _util = require("../../src/util");
var _dom = require("../../../ui/src/dom");
var _log = require("../../../ui/src/log");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const {
  warnLog,
  errLog
} = (0, _log.createComponentLog)('table');
const {
  getConfig,
  renderer,
  hooks,
  getI18n
} = _ui.VxeUI;
const tableEditMethodKeys = ['insert', 'insertAt', 'insertNextAt', 'insertChild', 'insertChildAt', 'insertChildNextAt', 'remove', 'removeCheckboxRow', 'removeRadioRow', 'removeCurrentRow', 'getRecordset', 'getInsertRecords', 'getRemoveRecords', 'getUpdateRecords', 'getEditRecord', 'getActiveRecord', 'getEditCell', 'getSelectedCell', 'clearEdit', 'clearActived', 'clearSelected', 'isEditByRow', 'isActiveByRow', 'setEditRow', 'setActiveRow', 'setEditCell', 'setActiveCell', 'setSelectCell'];
hooks.add('tableEditModule', {
  setupTable($xeTable) {
    const {
      props,
      reactData,
      internalData
    } = $xeTable;
    const {
      refElem
    } = $xeTable.getRefMaps();
    const {
      computeMouseOpts,
      computeEditOpts,
      computeCheckboxOpts,
      computeTreeOpts,
      computeValidOpts
    } = $xeTable.getComputeMaps();
    const browseObj = _xeUtils.default.browse();
    let editMethods = {};
    let editPrivateMethods = {};
    const getEditColumnModel = (row, column) => {
      const {
        model,
        editRender
      } = column;
      if (editRender) {
        model.value = (0, _util.getCellValue)(row, column);
        model.update = false;
      }
    };
    const setEditColumnModel = (row, column) => {
      const {
        model,
        editRender
      } = column;
      if (editRender && model.update) {
        (0, _util.setCellValue)(row, column, model.value);
        model.update = false;
        model.value = null;
      }
    };
    const removeCellSelectedClass = () => {
      const el = refElem.value;
      if (el) {
        const cell = el.querySelector('.col--selected');
        if (cell) {
          (0, _dom.removeClass)(cell, 'col--selected');
        }
      }
    };
    const syncActivedCell = () => {
      const {
        editStore,
        tableColumn
      } = reactData;
      const editOpts = computeEditOpts.value;
      const {
        actived
      } = editStore;
      const {
        row,
        column
      } = actived;
      if (row && column) {
        if (editOpts.mode === 'row') {
          tableColumn.forEach(column => setEditColumnModel(row, column));
        } else {
          setEditColumnModel(row, column);
        }
      }
    };
    const insertTreeRow = (newRecords, isAppend) => {
      const {
        tableFullTreeData,
        afterFullData,
        fullDataRowIdData,
        fullAllDataRowIdData
      } = internalData;
      const treeOpts = computeTreeOpts.value;
      const {
        rowField,
        parentField,
        mapChildrenField
      } = treeOpts;
      const childrenField = treeOpts.children || treeOpts.childrenField;
      const funcName = isAppend ? 'push' : 'unshift';
      newRecords.forEach(item => {
        const parentRowId = item[parentField];
        const rowid = (0, _util.getRowid)($xeTable, item);
        const matchObj = parentRowId ? _xeUtils.default.findTree(tableFullTreeData, item => parentRowId === item[rowField], {
          children: mapChildrenField
        }) : null;
        if (matchObj) {
          const {
            item: parentRow
          } = matchObj;
          const parentRest = fullAllDataRowIdData[(0, _util.getRowid)($xeTable, parentRow)];
          const parentLevel = parentRest ? parentRest.level : 0;
          let pChilds = parentRow[childrenField];
          let pMapChilds = parentRow[mapChildrenField];
          if (!_xeUtils.default.isArray(pChilds)) {
            pChilds = parentRow[childrenField] = [];
          }
          if (!_xeUtils.default.isArray(pMapChilds)) {
            pMapChilds = parentRow[mapChildrenField] = [];
          }
          pChilds[funcName](item);
          pMapChilds[funcName](item);
          const rest = {
            row: item,
            rowid,
            _seq: -1,
            seq: -1,
            index: -1,
            _index: -1,
            $index: -1,
            treeIndex: -1,
            _tIndex: -1,
            items: pChilds,
            parent: parentRow,
            level: parentLevel + 1,
            height: 0,
            resizeHeight: 0,
            oTop: 0,
            expandHeight: 0
          };
          fullDataRowIdData[rowid] = rest;
          fullAllDataRowIdData[rowid] = rest;
        } else {
          if (parentRowId) {
            warnLog('vxe.error.unableInsert');
          }
          afterFullData[funcName](item);
          tableFullTreeData[funcName](item);
          const rest = {
            row: item,
            rowid,
            _seq: -1,
            seq: -1,
            index: -1,
            _index: -1,
            $index: -1,
            treeIndex: -1,
            _tIndex: -1,
            items: tableFullTreeData,
            parent: null,
            level: 0,
            height: 0,
            resizeHeight: 0,
            oTop: 0,
            expandHeight: 0
          };
          fullDataRowIdData[rowid] = rest;
          fullAllDataRowIdData[rowid] = rest;
        }
      });
    };
    // const insertGroupRow = (newRecords: any[], isAppend: boolean) => {
    // }
    const handleInsertRowAt = (records, targetRowOrRowid, isInsertNextRow) => {
      const {
        treeConfig
      } = props;
      const {
        isRowGroupStatus
      } = reactData;
      const {
        tableFullTreeData,
        afterFullData,
        mergeBodyList,
        tableFullData,
        fullDataRowIdData,
        fullAllDataRowIdData,
        insertRowMaps,
        removeRowMaps
      } = internalData;
      const treeOpts = computeTreeOpts.value;
      const {
        transform,
        parentField,
        rowField,
        mapChildrenField
      } = treeOpts;
      const childrenField = treeOpts.children || treeOpts.childrenField;
      if (!_xeUtils.default.isArray(records)) {
        records = [records];
      }
      let targetRow = targetRowOrRowid;
      if (_xeUtils.default.isString(targetRowOrRowid) || _xeUtils.default.isNumber(targetRowOrRowid)) {
        const rowRest = fullAllDataRowIdData[targetRowOrRowid];
        if (rowRest) {
          targetRow = rowRest.row;
        }
      }
      if (!records.length) {
        return Promise.resolve({
          row: null,
          rows: []
        });
      }
      $xeTable.handlePushStack();
      const newRecords = (0, _vue.reactive)($xeTable.defineField(records.map(record => Object.assign(treeConfig && transform ? {
        [mapChildrenField]: [],
        [childrenField]: []
      } : {}, record))));
      let treeRecords = [];
      if (treeConfig && transform) {
        treeRecords = _xeUtils.default.toArrayTree(newRecords, {
          key: rowField,
          parentKey: parentField,
          children: childrenField
        });
      }
      if (_xeUtils.default.eqNull(targetRow)) {
        // 如果为虚拟树
        if (treeConfig && transform) {
          insertTreeRow(newRecords, false);
        } else if (isRowGroupStatus) {
          // 如果分组
          if (treeConfig) {
            throw new Error(getI18n('vxe.error.noTree', ['insert']));
          }
          errLog(getI18n('vxe.error.noGroup', ['insert']));
          // insertGroupRow(newRecords, false)
        } else {
          newRecords.forEach(item => {
            const rowid = (0, _util.getRowid)($xeTable, item);
            const rest = {
              row: item,
              rowid,
              _seq: -1,
              seq: -1,
              index: -1,
              _index: -1,
              $index: -1,
              treeIndex: -1,
              _tIndex: -1,
              items: afterFullData,
              parent: null,
              level: 0,
              height: 0,
              resizeHeight: 0,
              oTop: 0,
              expandHeight: 0
            };
            fullDataRowIdData[rowid] = rest;
            fullAllDataRowIdData[rowid] = rest;
            afterFullData.unshift(item);
            tableFullData.unshift(item);
          });
          // 刷新单元格合并
          mergeBodyList.forEach(mergeItem => {
            const {
              row: mergeRowIndex
            } = mergeItem;
            if (mergeRowIndex >= 0) {
              mergeItem.row = mergeRowIndex + newRecords.length;
            }
          });
        }
      } else {
        if (targetRow === -1) {
          // 如果为虚拟树
          if (treeConfig && transform) {
            insertTreeRow(newRecords, true);
          } else if (isRowGroupStatus) {
            // 如果分组
            if (treeConfig) {
              throw new Error(getI18n('vxe.error.noTree', ['insert']));
            }
            errLog(getI18n('vxe.error.noGroup', ['insert']));
            // insertGroupRow(newRecords, true)
          } else {
            newRecords.forEach(item => {
              const rowid = (0, _util.getRowid)($xeTable, item);
              const rest = {
                row: item,
                rowid,
                _seq: -1,
                seq: -1,
                index: -1,
                _index: -1,
                treeIndex: -1,
                _tIndex: -1,
                $index: -1,
                items: afterFullData,
                parent: null,
                level: 0,
                height: 0,
                resizeHeight: 0,
                oTop: 0,
                expandHeight: 0
              };
              fullDataRowIdData[rowid] = rest;
              fullAllDataRowIdData[rowid] = rest;
              afterFullData.push(item);
              tableFullData.push(item);
            });
          }
        } else {
          // 如果为虚拟树
          if (treeConfig && transform) {
            const matchMapObj = _xeUtils.default.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], {
              children: mapChildrenField
            });
            if (matchMapObj) {
              const {
                parent: parentRow
              } = matchMapObj;
              const parentMapChilds = parentRow ? parentRow[mapChildrenField] : tableFullTreeData;
              const parentRest = fullAllDataRowIdData[(0, _util.getRowid)($xeTable, parentRow)];
              const parentLevel = parentRest ? parentRest.level : 0;
              treeRecords.forEach((row, i) => {
                if (parentRow) {
                  if (row[parentField] !== parentRow[rowField]) {
                    errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, `${parentField}=${parentRow[rowField]}`]);
                    row[parentField] = parentRow[rowField];
                  }
                } else {
                  if (row[parentField] !== null) {
                    if (!_xeUtils.default.eqNull(row[parentField])) {
                      errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, 'null']);
                    }
                    row[parentField] = null;
                  }
                }
                let targetIndex = matchMapObj.index + i;
                if (isInsertNextRow) {
                  targetIndex = targetIndex + 1;
                }
                parentMapChilds.splice(targetIndex, 0, row);
              });
              _xeUtils.default.eachTree(treeRecords, item => {
                const rowid = (0, _util.getRowid)($xeTable, item);
                const rest = {
                  row: item,
                  rowid,
                  _seq: -1,
                  seq: -1,
                  index: -1,
                  _index: -1,
                  $index: -1,
                  treeIndex: -1,
                  _tIndex: -1,
                  items: parentMapChilds,
                  parent: parentRow,
                  level: parentLevel + 1,
                  height: 0,
                  resizeHeight: 0,
                  oTop: 0,
                  expandHeight: 0
                };
                if (item[childrenField]) {
                  item[mapChildrenField] = item[childrenField];
                }
                fullDataRowIdData[rowid] = rest;
                fullAllDataRowIdData[rowid] = rest;
              }, {
                children: childrenField
              });
              // 源
              if (parentRow) {
                const matchObj = _xeUtils.default.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], {
                  children: childrenField
                });
                if (matchObj) {
                  const parentChilds = matchObj.items;
                  let targetIndex = matchObj.index;
                  if (isInsertNextRow) {
                    targetIndex = targetIndex + 1;
                  }
                  parentChilds.splice(targetIndex, 0, ...treeRecords);
                }
              }
            } else {
              warnLog('vxe.error.unableInsert');
              insertTreeRow(newRecords, true);
            }
          } else if (isRowGroupStatus) {
            // 如果分组
            if (treeConfig) {
              throw new Error(getI18n('vxe.error.noTree', ['insert']));
            }
            errLog(getI18n('vxe.error.noGroup', ['insert']));
          } else {
            if (treeConfig) {
              throw new Error(getI18n('vxe.error.noTree', ['insert']));
            }
            let afIndex = -1;
            // 如果是可视索引
            if (_xeUtils.default.isNumber(targetRow)) {
              if (targetRow < afterFullData.length) {
                afIndex = targetRow;
              }
            } else {
              afIndex = $xeTable.findRowIndexOf(afterFullData, targetRow);
            }
            // 如果是插入指定行的下一行
            if (isInsertNextRow) {
              afIndex = Math.min(afterFullData.length, afIndex + 1);
            }
            if (afIndex === -1) {
              throw new Error(getI18n('vxe.error.unableInsert'));
            }
            afterFullData.splice(afIndex, 0, ...newRecords);
            const tfIndex = $xeTable.findRowIndexOf(tableFullData, targetRow);
            if (tfIndex > -1) {
              tableFullData.splice(tfIndex + (isInsertNextRow ? 1 : 0), 0, ...newRecords);
            } else {
              tableFullData.push(...newRecords);
            }
            // 刷新单元格合并
            mergeBodyList.forEach(mergeItem => {
              const {
                row: mergeRowIndex,
                rowspan: mergeRowspan
              } = mergeItem;
              if (mergeRowIndex >= afIndex) {
                mergeItem.row = mergeRowIndex + newRecords.length;
              } else if (isInsertNextRow ? mergeRowIndex + mergeRowspan >= afIndex : mergeRowIndex + mergeRowspan > afIndex) {
                mergeItem.rowspan = mergeRowspan + newRecords.length;
              }
            });
          }
        }
      }
      const handleStatus = newRow => {
        const rowid = (0, _util.getRowid)($xeTable, newRow);
        // 如果是被删除的数据，则还原状态
        if (removeRowMaps[rowid]) {
          delete removeRowMaps[rowid];
          if (insertRowMaps[rowid]) {
            delete insertRowMaps[rowid];
          }
        } else {
          insertRowMaps[rowid] = newRow;
        }
      };
      // 如果为虚拟树
      if (treeConfig && transform) {
        _xeUtils.default.eachTree(treeRecords, handleStatus, {
          children: mapChildrenField
        });
      } else {
        newRecords.forEach(handleStatus);
      }
      reactData.removeRowFlag++;
      reactData.insertRowFlag++;
      $xeTable.cacheRowMap(false);
      $xeTable.updateScrollYStatus();
      $xeTable.handleTableData(treeConfig && transform);
      if (!(treeConfig && transform)) {
        $xeTable.updateAfterDataIndex();
      }
      $xeTable.updateFooter();
      $xeTable.handleUpdateBodyMerge();
      $xeTable.checkSelectionStatus();
      if (reactData.scrollYLoad) {
        $xeTable.updateScrollYSpace();
      }
      return (0, _vue.nextTick)().then(() => {
        $xeTable.updateCellAreas();
        return $xeTable.recalculate(true);
      }).then(() => {
        return {
          row: newRecords.length ? newRecords[newRecords.length - 1] : null,
          rows: newRecords
        };
      });
    };
    const handleInsertChildRowAt = (records, parentRowOrParentId, targetRow, isInsertNextRow) => {
      const {
        treeConfig
      } = props;
      const {
        fullAllDataRowIdData
      } = internalData;
      const treeOpts = computeTreeOpts.value;
      const {
        transform,
        rowField,
        parentField
      } = treeOpts;
      if (treeConfig && transform) {
        if (!_xeUtils.default.isArray(records)) {
          records = [records];
        }
        let parentRow = parentRowOrParentId;
        if (_xeUtils.default.isString(parentRowOrParentId) || _xeUtils.default.isNumber(parentRowOrParentId)) {
          const rowRest = fullAllDataRowIdData[parentRowOrParentId];
          if (rowRest) {
            parentRow = rowRest.row;
          }
        }
        return handleInsertRowAt(records.map(item => Object.assign({}, item, {
          [parentField]: parentRow[rowField]
        })), targetRow, isInsertNextRow);
      } else {
        errLog('vxe.error.errProp', ['tree-config.transform=false', 'tree-config.transform=true']);
      }
      return Promise.resolve({
        row: null,
        rows: []
      });
    };
    const handleClearEdit = (evnt, targetRow) => {
      const {
        editStore
      } = reactData;
      const {
        actived,
        focused
      } = editStore;
      const {
        row,
        column
      } = actived;
      const validOpts = computeValidOpts.value;
      if (row || column) {
        if (targetRow && (0, _util.getRowid)($xeTable, targetRow) !== (0, _util.getRowid)($xeTable, row)) {
          return (0, _vue.nextTick)();
        }
        syncActivedCell();
        $xeTable.updateFooter();
        actived.args = null;
        actived.row = null;
        actived.column = null;
        $xeTable.dispatchEvent('edit-closed', {
          row,
          rowIndex: $xeTable.getRowIndex(row),
          $rowIndex: $xeTable.getVMRowIndex(row),
          column,
          columnIndex: $xeTable.getColumnIndex(column),
          $columnIndex: $xeTable.getVMColumnIndex(column)
        }, evnt || null);
      }
      focused.row = null;
      focused.column = null;
      if (validOpts.autoClear) {
        if (validOpts.msgMode !== 'full' || getConfig().cellVaildMode === 'obsolete') {
          if ($xeTable.clearValidate) {
            return $xeTable.clearValidate();
          }
        }
      }
      return (0, _vue.nextTick)().then(() => $xeTable.updateCellAreas());
    };
    const handleEditActive = (params, evnt, options) => {
      const $xeGrid = $xeTable.xeGrid;
      const $xeGantt = $xeTable.xeGantt;
      const {
        editConfig,
        mouseConfig
      } = props;
      const {
        editStore,
        tableColumn
      } = reactData;
      const editOpts = computeEditOpts.value;
      const {
        mode
      } = editOpts;
      const {
        actived,
        focused
      } = editStore;
      const {
        row,
        column
      } = params;
      const {
        editRender
      } = column;
      const {
        isFocus,
        isPos,
        isClear
      } = options;
      const cell = params.cell || $xeTable.getCellElement(row, column);
      const beforeEditMethod = editOpts.beforeEditMethod || editOpts.activeMethod;
      params.cell = cell;
      if (cell && (0, _utils.isEnableConf)(editConfig) && (0, _utils.isEnableConf)(editRender)) {
        // 激活编辑
        if (!$xeTable.isPendingByRow(row) && !$xeTable.isAggregateRecord(row)) {
          if (actived.row !== row || (mode === 'cell' ? actived.column !== column : false)) {
            // 判断是否禁用编辑
            let type = 'edit-disabled';
            if (!beforeEditMethod || beforeEditMethod(Object.assign(Object.assign({}, params), {
              $table: $xeTable,
              $grid: $xeGrid,
              $gantt: $xeGantt
            }))) {
              if (mouseConfig) {
                $xeTable.clearSelected();
                if ($xeTable.clearCellAreas) {
                  $xeTable.clearCellAreas();
                  $xeTable.clearCopyCellArea();
                }
              }
              $xeTable.closeTooltip();
              if (actived.column) {
                handleClearEdit(evnt);
              }
              type = 'edit-activated';
              column.renderHeight = cell.offsetHeight;
              actived.args = params;
              actived.row = row;
              actived.column = column;
              $xeTable.handlePushStack();
              if (isClear) {
                (0, _util.setCellValue)(row, column, null);
              }
              if (mode === 'row') {
                tableColumn.forEach(column => getEditColumnModel(row, column));
              } else {
                getEditColumnModel(row, column);
              }
              const afterEditMethod = editOpts.afterEditMethod;
              (0, _vue.nextTick)(() => {
                if (isFocus) {
                  $xeTable.handleFocus(params, evnt);
                }
                if (afterEditMethod) {
                  afterEditMethod(Object.assign(Object.assign({}, params), {
                    $table: $xeTable,
                    $grid: $xeGrid,
                    $gantt: $xeGantt
                  }));
                }
              });
            }
            $xeTable.dispatchEvent(type, {
              row,
              rowIndex: $xeTable.getRowIndex(row),
              $rowIndex: $xeTable.getVMRowIndex(row),
              column,
              columnIndex: $xeTable.getColumnIndex(column),
              $columnIndex: $xeTable.getVMColumnIndex(column)
            }, evnt);
            // v4已废弃
            if (type === 'edit-activated') {
              $xeTable.dispatchEvent('edit-actived', {
                row,
                rowIndex: $xeTable.getRowIndex(row),
                $rowIndex: $xeTable.getVMRowIndex(row),
                column,
                columnIndex: $xeTable.getColumnIndex(column),
                $columnIndex: $xeTable.getVMColumnIndex(column)
              }, evnt);
            }
          } else {
            const {
              column: oldColumn
            } = actived;
            if (mouseConfig) {
              $xeTable.clearSelected();
              if ($xeTable.clearCellAreas) {
                $xeTable.clearCellAreas();
                $xeTable.clearCopyCellArea();
              }
            }
            if (oldColumn && oldColumn !== column) {
              const {
                model: oldModel
              } = oldColumn;
              if (oldModel.update) {
                (0, _util.setCellValue)(row, oldColumn, oldModel.value);
              }
              if ($xeTable.clearValidate) {
                $xeTable.clearValidate(row, column);
              }
            }
            column.renderHeight = cell.offsetHeight;
            actived.args = params;
            actived.column = column;
            if (isPos) {
              setTimeout(() => {
                $xeTable.handleFocus(params, evnt);
              });
            }
          }
          focused.column = null;
          focused.row = null;
          $xeTable.focus();
        }
      }
      return (0, _vue.nextTick)();
    };
    const handleEditCell = (row, fieldOrColumn, options) => {
      const {
        editConfig
      } = props;
      const {
        isPos
      } = options;
      const column = _xeUtils.default.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn;
      if (row && column && (0, _utils.isEnableConf)(editConfig) && (0, _utils.isEnableConf)(column.editRender) && !$xeTable.isAggregateRecord(row)) {
        return Promise.resolve(isPos ? $xeTable.scrollToRow(row, column) : null).then(() => {
          const cell = $xeTable.getCellElement(row, column);
          if (cell) {
            handleEditActive({
              row,
              rowIndex: $xeTable.getRowIndex(row),
              column,
              columnIndex: $xeTable.getColumnIndex(column),
              cell,
              $table: $xeTable
            }, null, {
              isFocus: isPos,
              isPos
            });
            internalData._lastCallTime = Date.now();
          }
          return (0, _vue.nextTick)();
        });
      }
      return (0, _vue.nextTick)();
    };
    editMethods = {
      /**
       * 往表格中插入临时数据
       *
       * @param {*} records
       */
      insert(records) {
        return handleInsertRowAt(records, null);
      },
      /**
       * 往表格指定行中插入临时数据
       * 如果 row 为空则从插入到顶部，如果为树结构，则插入到目标节点顶部
       * 如果 row 为 -1 则从插入到底部，如果为树结构，则插入到目标节点底部
       * 如果 row 为有效行则插入到该行的位置，如果为树结构，则有插入到效的目标节点该行的位置
       */
      insertAt(records, targetRowOrRowid) {
        return handleInsertRowAt(records, targetRowOrRowid);
      },
      insertNextAt(records, targetRowOrRowid) {
        return handleInsertRowAt(records, targetRowOrRowid, true);
      },
      insertChild(records, parentRowOrParentId) {
        window.aa = internalData;
        return handleInsertChildRowAt(records, parentRowOrParentId, null);
      },
      insertChildAt(records, parentRowOrParentId, targetRow) {
        return handleInsertChildRowAt(records, parentRowOrParentId, targetRow);
      },
      insertChildNextAt(records, parentRowOrParentId, targetRow) {
        return handleInsertChildRowAt(records, parentRowOrParentId, targetRow, true);
      },
      /**
       * 删除指定行数据
       * 如果传 row 则删除一行
       * 如果传 rows 则删除多行
       * 如果为空则删除所有
       */
      remove(rows) {
        const {
          treeConfig
        } = props;
        const {
          editStore,
          isRowGroupStatus
        } = reactData;
        const {
          tableFullTreeData,
          selectCheckboxMaps,
          afterFullData,
          mergeBodyList,
          tableFullData,
          pendingRowMaps,
          insertRowMaps,
          removeRowMaps
        } = internalData;
        const checkboxOpts = computeCheckboxOpts.value;
        const treeOpts = computeTreeOpts.value;
        const {
          transform,
          mapChildrenField
        } = treeOpts;
        const childrenField = treeOpts.children || treeOpts.childrenField;
        const {
          actived
        } = editStore;
        const {
          checkField
        } = checkboxOpts;
        let delList = [];
        if (!rows) {
          rows = tableFullData;
        } else if (!_xeUtils.default.isArray(rows)) {
          rows = [rows];
        }
        if (!rows.length) {
          return Promise.resolve({
            row: null,
            rows: []
          });
        }
        $xeTable.handlePushStack();
        // 如果是新增，则保存记录
        rows.forEach(row => {
          if (!$xeTable.isInsertByRow(row)) {
            const rowid = (0, _util.getRowid)($xeTable, row);
            removeRowMaps[rowid] = row;
          }
        });
        // 如果绑定了多选属性，则更新状态
        if (!checkField) {
          rows.forEach(row => {
            const rowid = (0, _util.getRowid)($xeTable, row);
            if (selectCheckboxMaps[rowid]) {
              delete selectCheckboxMaps[rowid];
            }
          });
          reactData.updateCheckboxFlag++;
        }
        // 从数据源中移除
        if (tableFullData === rows) {
          rows = delList = tableFullData.slice(0);
          internalData.tableFullData = [];
          internalData.afterFullData = [];
          $xeTable.clearMergeCells();
        } else {
          // 如果为虚拟树
          if (treeConfig && transform) {
            rows.forEach(row => {
              const rowid = (0, _util.getRowid)($xeTable, row);
              const matchMapObj = _xeUtils.default.findTree(tableFullTreeData, item => rowid === (0, _util.getRowid)($xeTable, item), {
                children: mapChildrenField
              });
              if (matchMapObj) {
                const rItems = matchMapObj.items.splice(matchMapObj.index, 1);
                delList.push(rItems[0]);
              }
              const matchObj = _xeUtils.default.findTree(tableFullTreeData, item => rowid === (0, _util.getRowid)($xeTable, item), {
                children: childrenField
              });
              if (matchObj) {
                matchObj.items.splice(matchObj.index, 1);
              }
              const afIndex = $xeTable.findRowIndexOf(afterFullData, row);
              if (afIndex > -1) {
                afterFullData.splice(afIndex, 1);
              }
            });
          } else if (isRowGroupStatus) {
            // 如果分组
            warnLog(getI18n('vxe.error.noGroup', ['remove']));
          } else {
            rows.forEach(row => {
              const tfIndex = $xeTable.findRowIndexOf(tableFullData, row);
              if (tfIndex > -1) {
                const rItems = tableFullData.splice(tfIndex, 1);
                delList.push(rItems[0]);
              }
              const afIndex = $xeTable.findRowIndexOf(afterFullData, row);
              if (afIndex > -1) {
                // 刷新单元格合并
                mergeBodyList.forEach(mergeItem => {
                  const {
                    row: mergeRowIndex,
                    rowspan: mergeRowspan
                  } = mergeItem;
                  if (mergeRowIndex > afIndex) {
                    mergeItem.row = mergeRowIndex - 1;
                  } else if (mergeRowIndex + mergeRowspan > afIndex) {
                    mergeItem.rowspan = mergeRowspan - 1;
                  }
                });
                afterFullData.splice(afIndex, 1);
              }
            });
          }
        }
        // 如果当前行被激活编辑，则清除激活状态
        if (actived.row && $xeTable.findRowIndexOf(rows, actived.row) > -1) {
          editMethods.clearEdit();
        }
        // 从新增中移除已删除的数据
        rows.forEach(row => {
          const rowid = (0, _util.getRowid)($xeTable, row);
          if (insertRowMaps[rowid]) {
            delete insertRowMaps[rowid];
          }
          if (pendingRowMaps[rowid]) {
            delete pendingRowMaps[rowid];
          }
        });
        reactData.removeRowFlag++;
        reactData.insertRowFlag++;
        reactData.pendingRowFlag++;
        $xeTable.cacheRowMap(false);
        $xeTable.handleTableData(treeConfig && transform);
        $xeTable.updateFooter();
        $xeTable.handleUpdateBodyMerge();
        if (!(treeConfig && transform)) {
          $xeTable.updateAfterDataIndex();
        }
        $xeTable.checkSelectionStatus();
        if (reactData.scrollYLoad) {
          $xeTable.updateScrollYSpace();
        }
        return (0, _vue.nextTick)().then(() => {
          $xeTable.updateCellAreas();
          return $xeTable.recalculate(true);
        }).then(() => {
          return {
            row: delList.length ? delList[delList.length - 1] : null,
            rows: delList
          };
        });
      },
      /**
       * 删除复选框选中的数据
       */
      removeCheckboxRow() {
        return editMethods.remove($xeTable.getCheckboxRecords()).then(params => {
          $xeTable.clearCheckboxRow();
          return params;
        });
      },
      /**
       * 删除单选框选中的数据
       */
      removeRadioRow() {
        const radioRecord = $xeTable.getRadioRecord();
        return editMethods.remove(radioRecord || []).then(params => {
          $xeTable.clearRadioRow();
          return params;
        });
      },
      /**
       * 删除当前行选中的数据
       */
      removeCurrentRow() {
        const currentRecord = $xeTable.getCurrentRecord();
        return editMethods.remove(currentRecord || []).then(params => {
          $xeTable.clearCurrentRow();
          return params;
        });
      },
      /**
       * 获取表格数据集，包含新增、删除、修改、标记
       */
      getRecordset() {
        const removeRecords = editMethods.getRemoveRecords();
        const pendingRecords = $xeTable.getPendingRecords();
        const delRecords = removeRecords.concat(pendingRecords);
        // 如果已经被删除，则无需放到更新数组
        const updateRecords = editMethods.getUpdateRecords().filter(row => {
          return !delRecords.some(item => $xeTable.eqRow(item, row));
        });
        return {
          insertRecords: editMethods.getInsertRecords(),
          removeRecords,
          updateRecords,
          pendingRecords
        };
      },
      /**
       * 获取新增的临时数据
       */
      getInsertRecords() {
        const {
          fullAllDataRowIdData,
          insertRowMaps
        } = internalData;
        const insertRecords = [];
        _xeUtils.default.each(insertRowMaps, (row, rowid) => {
          if (fullAllDataRowIdData[rowid]) {
            insertRecords.push(row);
          }
        });
        return insertRecords;
      },
      /**
       * 获取已删除的数据
       */
      getRemoveRecords() {
        const {
          removeRowMaps
        } = internalData;
        const removeRecords = [];
        _xeUtils.default.each(removeRowMaps, row => {
          removeRecords.push(row);
        });
        return removeRecords;
      },
      /**
       * 获取更新数据
       * 只精准匹配 row 的更改
       * 如果是树表格，子节点更改状态不会影响父节点的更新状态
       */
      getUpdateRecords() {
        const {
          keepSource,
          treeConfig
        } = props;
        const {
          tableFullData,
          tableFullTreeData
        } = internalData;
        const treeOpts = computeTreeOpts.value;
        const updateRecords = [];
        if (keepSource) {
          syncActivedCell();
          if (treeConfig) {
            const childrenField = treeOpts.children || treeOpts.childrenField;
            _xeUtils.default.eachTree(tableFullTreeData, row => {
              if ($xeTable.isUpdateByRow(row)) {
                updateRecords.push(row);
              }
            }, {
              children: childrenField
            });
          } else {
            tableFullData.forEach(row => {
              if ($xeTable.isUpdateByRow(row)) {
                updateRecords.push(row);
              }
            });
          }
        }
        return updateRecords;
      },
      getActiveRecord() {
        warnLog('vxe.error.delFunc', ['getActiveRecord', 'getEditCell']);
        const {
          editStore
        } = reactData;
        const {
          fullAllDataRowIdData
        } = internalData;
        const {
          args,
          row
        } = editStore.actived;
        if (args && row && fullAllDataRowIdData[(0, _util.getRowid)($xeTable, row)]) {
          return Object.assign({}, args, {
            row
          });
        }
        return null;
      },
      getEditRecord() {
        warnLog('vxe.error.delFunc', ['getEditRecord', 'getEditCell']);
        const {
          editStore
        } = reactData;
        const {
          fullAllDataRowIdData
        } = internalData;
        const {
          args,
          row
        } = editStore.actived;
        if (args && row && fullAllDataRowIdData[(0, _util.getRowid)($xeTable, row)]) {
          return Object.assign({}, args, {
            row
          });
        }
        return null;
      },
      getEditCell() {
        const {
          editStore
        } = reactData;
        const {
          row,
          column
        } = editStore.actived;
        if (column && row) {
          return {
            row,
            rowIndex: $xeTable.getRowIndex(row),
            column,
            columnIndex: $xeTable.getColumnIndex(column)
          };
        }
        return null;
      },
      /**
       * 获取选中的单元格
       */
      getSelectedCell() {
        const {
          editStore
        } = reactData;
        const {
          row,
          column
        } = editStore.selected;
        if (row && column) {
          return {
            row,
            column
          };
        }
        return null;
      },
      clearActived(row) {
        // 即将废弃
        warnLog('vxe.error.delFunc', ['clearActived', 'clearEdit']);
        return $xeTable.clearEdit(row);
      },
      /**
       * 清除激活的编辑
       */
      clearEdit(row) {
        return handleClearEdit(null, row);
      },
      /**
       * 清除所选中源状态
       */
      clearSelected() {
        const {
          editStore
        } = reactData;
        const {
          selected
        } = editStore;
        selected.row = null;
        selected.column = null;
        removeCellSelectedClass();
        return (0, _vue.nextTick)();
      },
      isActiveByRow(row) {
        warnLog('vxe.error.delFunc', ['isActiveByRow', 'isEditByRow']);
        // 即将废弃
        return $xeTable.isEditByRow(row);
      },
      /**
       * 判断行是否为激活编辑状态
       * @param {Row} row 行对象
       */
      isEditByRow(row) {
        const {
          editStore
        } = reactData;
        return editStore.actived.row === row;
      },
      setActiveRow(row) {
        warnLog('vxe.error.delFunc', ['setActiveRow', 'setEditRow']);
        // 即将废弃
        return editMethods.setEditRow(row);
      },
      /**
       * 激活行编辑
       */
      setEditRow(row, fieldOrColumn, options) {
        const {
          visibleColumn
        } = internalData;
        let column = _xeUtils.default.find(visibleColumn, column => (0, _utils.isEnableConf)(column.editRender));
        let isPos = false;
        if (fieldOrColumn) {
          isPos = true;
          if (fieldOrColumn !== true) {
            column = _xeUtils.default.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn;
          }
        }
        return handleEditCell(row, column, Object.assign({
          isPos,
          isFocus: isPos
        }, options));
      },
      setActiveCell(row, fieldOrColumn) {
        warnLog('vxe.error.delFunc', ['setActiveCell', 'setEditCell']);
        // 即将废弃
        return editMethods.setEditCell(row, fieldOrColumn);
      },
      /**
       * 激活单元格编辑
       */
      setEditCell(row, fieldOrColumn, options) {
        return handleEditCell(row, fieldOrColumn, Object.assign({
          isFocus: true,
          isPos: true
        }, options));
      },
      /**
       * 只对 trigger=dblclick 有效，选中单元格
       */
      setSelectCell(row, fieldOrColumn) {
        const {
          tableData
        } = reactData;
        const editOpts = computeEditOpts.value;
        const column = _xeUtils.default.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn;
        if (row && column && editOpts.trigger !== 'manual') {
          const rowIndex = $xeTable.findRowIndexOf(tableData, row);
          if (rowIndex > -1 && column) {
            const cell = $xeTable.getCellElement(row, column);
            const params = {
              row,
              rowIndex,
              column,
              columnIndex: $xeTable.getColumnIndex(column),
              cell
            };
            $xeTable.handleSelected(params, {});
          }
        }
        return (0, _vue.nextTick)();
      }
    };
    editPrivateMethods = {
      /**
       * 处理激活编辑
       */
      handleEdit(params, evnt, options) {
        return handleEditActive(params, evnt, Object.assign({
          isFocus: true,
          isPos: true
        }, options));
      },
      /**
       * @deprecated
       */
      handleActived(params, evnt) {
        return editPrivateMethods.handleEdit(params, evnt);
      },
      /**
       * 处理取消编辑
       * @param evnt
       * @returns
       */
      handleClearEdit,
      /**
       * 处理聚焦
       */
      handleFocus(params) {
        const {
          row,
          column,
          cell
        } = params;
        const {
          editRender
        } = column;
        const editOpts = computeEditOpts.value;
        if ((0, _utils.isEnableConf)(editRender)) {
          const compRender = renderer.get(editRender.name);
          let autoFocus = editRender.autofocus || editRender.autoFocus;
          let autoSelect = editRender.autoSelect || editRender.autoselect;
          let inputElem;
          // 是否启用聚焦
          if (editOpts.autoFocus) {
            if (!autoFocus && compRender) {
              autoFocus = compRender.tableAutoFocus || compRender.tableAutofocus || compRender.autofocus;
            }
            if (!autoSelect && compRender) {
              autoSelect = compRender.tableAutoSelect || compRender.autoselect;
            }
            // 如果指定了聚焦 class
            if (_xeUtils.default.isFunction(autoFocus)) {
              inputElem = autoFocus(params);
            } else if (autoFocus) {
              if (autoFocus === true) {
                // 自动匹配模式，会自动匹配第一个可输入元素
                inputElem = cell.querySelector('input,textarea');
              } else {
                inputElem = cell.querySelector(autoFocus);
              }
              if (inputElem) {
                inputElem.focus();
              }
            }
          }
          if (inputElem) {
            if (autoSelect) {
              inputElem.select();
            } else {
              // 保持一致行为，光标移到末端
              if (browseObj.msie) {
                const textRange = inputElem.createTextRange();
                textRange.collapse(false);
                textRange.select();
              }
            }
          } else {
            // 是否自动定位
            if (editOpts.autoPos) {
              if (!column.fixed) {
                // 显示到可视区中
                $xeTable.scrollToRow(row, column);
              }
            }
          }
        }
      },
      /**
       * 处理选中源
       */
      handleSelected(params, evnt) {
        const {
          mouseConfig
        } = props;
        const {
          editStore
        } = reactData;
        const mouseOpts = computeMouseOpts.value;
        const editOpts = computeEditOpts.value;
        const {
          actived,
          selected
        } = editStore;
        const {
          row,
          column
        } = params;
        const isMouseSelected = mouseConfig && mouseOpts.selected;
        const selectMethod = () => {
          if (isMouseSelected && (selected.row !== row || selected.column !== column)) {
            if (actived.row !== row || (editOpts.mode === 'cell' ? actived.column !== column : false)) {
              handleClearEdit(evnt);
              $xeTable.clearSelected();
              if ($xeTable.clearCellAreas) {
                $xeTable.clearCellAreas();
                $xeTable.clearCopyCellArea();
              }
              selected.args = params;
              selected.row = row;
              selected.column = column;
              if (isMouseSelected) {
                editPrivateMethods.addCellSelectedClass();
              }
              $xeTable.focus();
              if (evnt) {
                $xeTable.dispatchEvent('cell-selected', params, evnt);
              }
            }
          }
          return (0, _vue.nextTick)();
        };
        return selectMethod();
      },
      addCellSelectedClass() {
        const {
          editStore
        } = reactData;
        const {
          selected
        } = editStore;
        const {
          row,
          column
        } = selected;
        removeCellSelectedClass();
        if (row && column) {
          const cell = $xeTable.getCellElement(row, column);
          if (cell) {
            (0, _dom.addClass)(cell, 'col--selected');
          }
        }
      }
    };
    return Object.assign(Object.assign({}, editMethods), editPrivateMethods);
  },
  setupGrid($xeGrid) {
    return $xeGrid.extendTableMethods(tableEditMethodKeys);
  },
  setupGantt($xeGantt) {
    return $xeGantt.extendTableMethods(tableEditMethodKeys);
  }
});