<!-- @desc:编辑表格  @auth:周兴  @time:2022/11/15 13:06 -->
<template>
  <div :style="{height: 100 + '%',width:divWidth,paddingRight:'3px'}" ref="edit-table-div" v-if="existsFlag">
    <div v-if="title" class="table-title">{{ title }}
      <Poptip trigger="hover" transfer placement="top-start" :content="titleInfo" v-if="titleInfo">
        <Icon type="iconfont iconfont icon-question" style="cursor: pointer;font-size: 12px" color="#909399"
              ref="info-icon"/>
      </Poptip>
    </div>
    <vxe-table
      class="dk-table-scrollbar"
      header-row-class-name="header-class"
      border
      size="mini"
      show-overflow
      :cell-style="cellStyle"
      :footer-cell-style="footCellStyle"
      :height="height +'px'"
      show-footer
      align="center"
      auto-resize
      sync-resize
      :ref="name"
      :class="className"
      :row-class-name="setRowClassName"
      :edit-rules="validRules"
      :valid-config="{showMessage:false}"
      :data="tableData"
      :show-header="showHeader"
      :show-footer="showFooter"
      :highlight-current-row="highlightCurrentRow"
      :footer-method="footerMethod"
      :mouse-config="{selected: true}"
      :checkbox-config="{range: true}"
      :column-config="{resizable: true,isCurrent: true }"
      :menu-config="{body:header,header:header,visibleMethod:visibleMethod}"
      :keyboard-config="{isArrow: true, isDel: true, isEnter: true, isTab: true, isEdit: true, editMethod}"
      :edit-config="{ mode: 'row',trigger:'click',autoClear:false, enabled:enabledEdit}"
      :row-config="{isCurrent: true}"
      @contextmenu.native.prevent
      @scroll="handleScroll"
      @cell-click="handleCellClick"
      @keydown="handleTableKeyDown"
      @cell-mouseenter="handleCellMouseEnter"
      @cell-mouseleave="handleCellMouseLeave"
      @edit-closed="editClosed"
      @current-change="currentChangeGetData"
      @menu-click="menuClick"
      @footer-cell-dblclick="handleFooterCopy"
      @header-cell-click="handleHeaderCellClick"
      @click.native="handleClick"
    >
      <div v-for="(colItem,colIndex) in columnsData" :key="colIndex">
        <!--   空白 (TODO第一列留一个余白，不然顺序就会乱，没有找到原因 周兴 2022-6-11)  -->
        <vxe-column type="blank" v-if="colItem.type === 'blank'" :field="colItem.field" :width="colItem.width"
                    :resizable="false">
        </vxe-column>
        <!--校验信息-->
        <vxe-column type="info" v-if="colItem.type === 'info'" :field="colItem.field" :width="colItem.width"
                    :resizable="false">
          <template #default="{ row,rowIndex,column }">
            <Poptip trigger="hover" transfer placement="top-start" :content="row.info" v-if="row.info">
              <Icon type="iconfont iconfont icon-question" style="cursor: pointer;font-size: 14px" color="red"
                    ref="info-icon"/>
            </Poptip>
          </template>
        </vxe-column>
        <!--   序列   -->
        <vxe-column v-if="colItem.type === 'seq'" type="seq" :field="colItem.field" width="60" :title="vm.$t('seq')">
          <template #default="{row, seq, rowIndex}">
            <seq-button :delete-flag="deleteFlag && canDelete(row,colItem)" v-if="row._hover && operateFlag"
                        :add-flag="addFlag"
                        @add="add(rowIndex)" @del="del(rowIndex)"/>
            <div v-else :class="row.parentId === null ?'seq-class':'seq-class-s'">
              {{ seq }}
            </div>
          </template>
        </vxe-column>

        <!--   选取类型   -->
        <vxe-column v-if="colItem.type === 'tableSelect'" :field="colItem.field"
                    :type="colItem.type"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :title="colItem.title?colItem.title:$t(colItem.field)" :params="{type:'tableSelect'}"
                    :edit-render="{autofocus: '.vxe-input--inner'}">
          <template #header="{ row }">
            <span :ref="'title_' + colItem.field ">{{ colItem.title ? colItem.title : $t(colItem.field) }}</span>
            <!--提示信息-->
            <Poptip trigger="hover" transfer placement="top-start" :content="colItem.info" v-if="colItem.info">
              <Icon type="iconfont iconfont icon-question" style="cursor: pointer;font-size: 14px;margin-top:-1px"
                    color="#909399" ref="info-icon"/>
            </Poptip>
            <Poptip trigger="click" transfer @on-popper-hide="popperHide">
              <Icon type="iconfont iconfont icon-copy" style="cursor: pointer;" ref="down-input-icon"
                    v-if="colItem.copyVisible"/>
              <div slot="content">
                <div style="display: flex;align-items: center;justify-content: center;">
                  <TableSelect :field="colItem.field" :text="inputDownValue"
                               :dataType="colItem.dataType"
                               :sortBoolean="colItem.sortBoolean"
                               :multiple="false"
                               :showType="colItem.showType"
                               :promotionType="colItem.promotionType"
                               :searchDetailFlag="false"
                               :clickCloseFlag="false"
                               @onBatchChoose="onBatchChooseCopy($event,colItem,'batch')"
                               @onChoose="onBatchChooseCopy($event,colItem)"
                               :search-param="typeof colItem.param === 'function'? colItem.param():colItem.param"
                               :search-init-param="typeof colItem.initParam === 'function'? colItem.initParam():colItem.initParam"
                  ></TableSelect>
                  <Button type="primary" size="small" @click="inputDown(colItem)">{{ $t('filling') }}</Button>
                </div>
              </div>
            </Poptip>
            <!--冻结/解冻列-->
            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "
                  v-if="freezeData && colItem.freezeFlag"
                  type="ios-lock"
                  @click="handleFreeze(colItem.field)"/>
          </template>
          <template style="width:100%;" #edit="{ row,column,rowIndex }">
            <TableSelect :text="row[colItem.field]" :field="colItem.field" :dataType="colItem.dataType"
                         v-if="setCellCanTableSelect(row,colItem) "
                         :sortBoolean="colItem.sortBoolean"
                         :multiple="colItem.multiple"
                         :showType="colItem.showType"
                         :promotionType="colItem.promotionType"
                         :clearFlag="true"
                         :search-param="typeof colItem.param === 'function'? colItem.param():colItem.param"
                         :search-init-param="typeof colItem.initParam === 'function'? colItem.initParam():colItem.initParam"
                         :other-search-param="typeof colItem.otherSearchParam === 'function'? colItem.otherSearchParam():colItem.otherSearchParam"
                         @on-input-blur="handleSelectInputBlur($event,row,rowIndex,colItem,colIndex)"
                         @change="(val)=>inputChange(row,rowIndex,colItem,val)"
                         @keydown.stop="nextInputCellByKeyDown(Object.assign($event,{column:colItem,colIndex,rowIndex,row}))"
                         @onBatchChoose="onBatchChoose($event,column,rowIndex,colIndex,colItem.fieldUpdate,colItem)"
                         @onChoose="onChoose($event,row,column,rowIndex,colIndex,colItem.fieldUpdate,colItem)"
                         :ref="colItem.field+rowIndex"
                         :select-field="colItem.selectField"
                         :search-detail-flag="colItem.searchDetailFlag"
                         :poptipTransferClassName="colItem.poptipTransferClassName"
            ></TableSelect>
            <div class="edit-div-class" v-else @dblclick.stop="copyValue(row,colItem,rowIndex)"
                 style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;display: inline-block;width: 100%;">
              {{ row[colItem.field] }}
            </div>
          </template>
        </vxe-column>

        <!--   无法修改类型   -->
        <vxe-column v-if="colItem.type === 'disabled' && !colItem.switch" :field="colItem.field"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :formatter="formatColumn" :params="colItem"
                    :title="colItem.title?colItem.title:$t(colItem.field)">
          <!--标题-->
          <!--          <template #header="{ row,column,columnIndex }">-->
          <!--            <span>{{ colItem.title ? colItem.title : $t(colItem.field) }}</span>-->
          <!--            &lt;!&ndash;冻结/解冻列&ndash;&gt;-->
          <!--            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "-->
          <!--                  v-if="freezeData && colItem.freezeFlag"-->
          <!--                  type="ios-lock"-->
          <!--                  @click="handleFreeze(colItem.field)"/>-->
          <!--          </template>-->
          <template #default="{ row,rowIndex,column }">
            <div class="edit-div-class" @dblclick.stop="copyValue(row,colItem,rowIndex)">{{
                formatColumn({
                  column: column,
                  cellValue: row[colItem.field],
                  row: row
                })
              }}
            </div>
          </template>
        </vxe-column>

        <!--   无法修改类型 开关   -->
        <vxe-column v-if="colItem.type === 'disabled' && colItem.switch" :field="colItem.field"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.width?colItem.width:vm.$config.columnWidthMin" :params="colItem"
                    :title="colItem.title?colItem.title:$t(colItem.field)">
          <!--标题-->
          <!--          <template #header="{ row,column,columnIndex }">-->
          <!--            <span>{{ colItem.title ? colItem.title : $t(colItem.field) }}</span>-->
          <!--            &lt;!&ndash;冻结/解冻列&ndash;&gt;-->
          <!--            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "-->
          <!--                  v-if="freezeData && colItem.freezeFlag"-->
          <!--                  type="ios-lock"-->
          <!--                  @click="handleFreeze(colItem.field)"/>-->
          <!--          </template>-->
          <template #default="{ row,rowIndex }">
            <div class="switch-class">
              <i-switch size="small" :ref="colItem.field+'_default_'+rowIndex" v-model="row[colItem.field]"
                        :disabled="true"/>
            </div>
          </template>
        </vxe-column>

        <!--   文本类型   -->
        <vxe-column v-if="colItem.type === 'text'" :field="colItem.field"
                    :title="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    :params="colItem"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :edit-render="{autofocus: '.vxe-input--inner'}">
          <template #header="{ row }">
            <span :ref="'title_' + colItem.field ">{{ colItem.title ? colItem.title : $t(colItem.field) }}</span>
            <!--提示信息-->
            <Poptip trigger="hover" transfer placement="top-start" :content="colItem.info" v-if="colItem.info">
              <Icon type="iconfont iconfont icon-question" style="cursor: pointer;font-size: 14px;margin-top:-1px"
                    color="#909399" ref="info-icon"/>
            </Poptip>
            <Poptip trigger="click" transfer @on-popper-hide="popperHide">
              <Icon type="iconfont iconfont icon-copy" style="cursor: pointer;" ref="down-input-icon"
                    v-if="colItem.copyVisible"/>
              <div slot="content">
                <div style="display: flex;align-items: center;justify-content: center;">
                  <Input size="small" v-model="inputDownValue"
                         :maxlength="colItem.maxlength?colItem.maxlength:vm.$config.maxlength"
                         @keydown.13.native.stop="inputDown(colItem)" :name="colItem.field"></Input>
                  <Button type="primary" size="small" @click="inputDown(colItem)">{{ $t('filling') }}</Button>
                </div>
              </div>
            </Poptip>
            <!--冻结/解冻列-->
            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "
                  v-if="freezeData && colItem.freezeFlag"
                  type="ios-lock"
                  @click="handleFreeze(colItem.field)"/>
          </template>
          <template #edit="{ row,rowIndex }">
            <vxe-input v-model="row[colItem.field]" type="text" v-if="setCellCanInput( row ,colItem)"
                       :maxlength="colItem.maxlength?colItem.maxlength:vm.$config.maxlength"
                       :ref="colItem.field+rowIndex"
                       @dblclick.native.stop="copyValue(row,colItem,rowIndex)"
                       @change.native="changeValue(colItem,rowIndex,row)"
                       @keydown.native="nextInputCellByKeyDown(Object.assign($event,{column:colItem,colIndex,rowIndex, row}))"></vxe-input>
            <div class="edit-div-class" @dblclick.stop="copyValue(row,colItem,rowIndex)" v-else>{{
                row[colItem.field]
              }}
            </div>
          </template>
        </vxe-column>

        <!--   数值   -->
        <vxe-column v-if="colItem.type === 'number'" :field="colItem.field"
                    :title="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    class-name="number-class"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :edit-render="{autofocus: '.vxe-input--inner', autoselect: true}" :formatter="formatColumn"
                    :params="colItem">
          <template #header="{ row }">
            <span :ref="'title_' + colItem.field ">{{ colItem.title ? colItem.title : $t(colItem.field) }}</span>
            <!--提示信息-->
            <Poptip trigger="hover" transfer placement="top-start" :content="colItem.info" v-if="colItem.info">
              <Icon type="iconfont iconfont icon-question" style="cursor: pointer;font-size: 14px;margin-top:-1px"
                    color="#909399" ref="info-icon"/>
            </Poptip>
            <Poptip trigger="click" transfer @on-popper-show="popperShow(colIndex,'inputNumber')"
                    @on-popper-hide="popperHide">
              <Icon type="iconfont iconfont icon-copy" style="cursor: pointer;" ref="down-input-icon"
                    v-if="colItem.copyVisible"/>
              <div slot="content">
                <!--点回车相当于点按钮填充-->
                <div style="display: flex;align-items: center;justify-content: center;">
                  <InputNumberPop size="small" :digits="colItem.digits" v-model="inputDownValue"
                                  :ref="'pop_' + colIndex"
                                  @keydown.13.native.stop="inputDown(colItem)" :pop-visible="false"
                                  :name="colItem.field"></InputNumberPop>
                  <Button type="primary" size="small" @click="inputDown(colItem)">{{ $t('filling') }}</Button>
                </div>
              </div>
            </Poptip>
            <!--冻结/解冻列-->
            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "
                  v-if="freezeData && colItem.freezeFlag"
                  type="ios-lock"
                  @click="handleFreeze(colItem.field)"/>
          </template>
          <template #edit="{ row ,rowIndex}">
            <vxe-input v-model="row[colItem.field]" type="number"
                       :ref="colItem.field+rowIndex"
                       v-if="setCellCanInput(row,colItem)"
                       @contextmenu.native.prevent
                       :controls="false"
                       @dblclick.native.stop="copyValue(row,colItem,rowIndex)"
                       @blur="changeValue(colItem,rowIndex,row)"
                       @keydown.native="controlNumber(Object.assign($event,{column:colItem,colIndex,rowIndex, row}))"
                       @keyup.native="handleKeyup(Object.assign($event,{column:colItem,colIndex,rowIndex, row}))"></vxe-input>
            <div class="edit-div-class" @dblclick.stop="copyValue(row,colItem,rowIndex)" v-else>{{
                row[colItem.field]
              }}
            </div>
          </template>
        </vxe-column>

        <!--  非标组件-->
        <vxe-column v-if="colItem.type === 'nonStandard'" :field="colItem.field"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin" :params="colItem"
                    :formatter="formatColumn"
                    :title="colItem.title?colItem.title:$t(colItem.field)" :tree-node="colItem.treeNode">
          <!--标题-->
          <template #header="{ row,column,columnIndex }">
            <span>{{ colItem.title ? colItem.title : $t(colItem.field) }}</span>
            <!--冻结/解冻列-->
            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "
                  v-if="freezeData && colItem.freezeFlag"
                  type="ios-lock"
                  @click="handleFreeze(colItem.field)"/>
          </template>
          <template #default="{ row,rowIndex,column }">
            <vxe-pulldown transfer :ref="colItem.field+rowIndex" style="width:  300px;"
                          :destroy-on-close="false">
              <template #default>
                <div style="cursor: pointer;width: 100%;height: 30px;"
                     v-if="row.nonStandardItems && row.nonStandardItems.length > 0"
                     @click="openNonStandardForm(Object.assign($event,{colItem,rowIndex,row}))">{{ row[colItem.field] }}
                </div>
              </template>
              <template #dropdown>
                <div class="non-glass-drop-down">
                  <DkForm ref="nonGlassForm" :model="row.nonStandardForm" label-position="top" inline  :col-count="1">
                      <DkFormItem  v-for="(item,itIndex) in row.nonStandardItems" :key="itIndex" :prop="item.prop" style="width:98% ;" :label="item.label">
                        <!--文本-->
                        <InputPop v-if="item.type==='text'" v-model="row.nonStandardForm[item.code]" :ref="item.code + rowIndex"
                                  size="small" :readonly="item.readonly" @on-change="(e)=>changeNonStandard(e,row,rowIndex,colItem)">
                        </InputPop>
                        <!--数量-->
                        <InputNumberPop v-if="item.type==='number'" v-model="row.nonStandardForm[item.code]" :ref="item.code + rowIndex"
                                  size="small" :readonly="item.readonly" :digits="item.digits" @on-change="(e)=>changeNonStandard(e,row,rowIndex,colItem)">
                        </InputNumberPop>
                      </DkFormItem>
                  </DkForm>
                </div>
              </template>
            </vxe-pulldown>
          </template>
        </vxe-column>

        <!--  主从多选组件-->
        <vxe-column v-if="colItem.type === 'multiSelect'" :field="colItem.field"
                    :title="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :edit-render="{autofocus: '.vxe-input--inner'}">
          <template #default="{ row,rowIndex }">
            <div style="padding-left: 10px;">
              {{ row[colItem.field + '_Name'] }}
            </div>
          </template>
          <template #edit="{ row,rowIndex }">
            <MultiSelect v-model="row[colItem.field]"
                         main-field="ownerFlag"
                         :table-flag="true"
                         @ok="getMultiSelect(Object.assign($event,{row,rowIndex,colItem}))"
                         :default-value="row[colItem.field + '_Name']"
                         :title="$t('pdtModelName')"
                         :fromTitle="$t('staffNames')"
                         :type="vm.$config.MagnifierType.product"
            ></MultiSelect>
          </template>
        </vxe-column>

        <!--   下拉   -->
        <vxe-column v-if="colItem.type === 'select'" :field="colItem.field"
                    :title="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :edit-render="{autofocus: '.vxe-input--inner'}">
          <template #header="{ row }">
            <span :ref="'title_' + colItem.field ">{{ $t(colItem.title ? colItem.title : colItem.field) }}</span>
            <!--提示信息-->
            <Poptip trigger="hover" transfer placement="top-start" :content="colItem.info" v-if="colItem.info">
              <Icon type="iconfont iconfont icon-question" style="cursor: pointer;font-size: 14px;margin-top:-1px"
                    color="#909399" ref="info-icon"/>
            </Poptip>
            <Poptip trigger="click" transfer @on-popper-hide="popperHide">
              <Icon type="iconfont iconfont icon-copy" style="cursor: pointer;" ref="down-input-icon"
                    v-if="colItem.copyVisible"/>
              <div slot="content">
                <div style="display: flex;align-items: center;justify-content: center;">
                  <!--                {{ colItem.options() }}-->
                  <Select size="small" v-model="inputDownValue" style="width:200px" :multiple="colItem.multiple"
                          clearable>
                    <Option v-for="item in (typeof colItem.options === 'function'?colItem.options():colItem.options)"
                            :key="item[colItem.valueKey]"
                            :value="item[colItem.valueKey]?item[colItem.valueKey]:''"
                            :label="item[colItem.labelKey]">
                      {{ item[colItem.labelKey] }}
                    </Option>
                  </Select>

                  <Button type="primary" size="small" @click="inputDown(colItem)">{{ $t('filling') }}</Button>
                </div>
              </div>
            </Poptip>
            <!--冻结/解冻列-->
            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "
                  v-if="freezeData && colItem.freezeFlag"
                  type="ios-lock"
                  @click="handleFreeze(colItem.field)"/>
          </template>
          <template #default="{ row }">
            <div class="edit-div-class" @dblclick.stop="copyValue(row,colItem)">{{
                row[colItem.field + '_Name']
              }}
            </div>
          </template>

          <!--多选-->
          <template #edit="{ row,column,rowIndex }" v-if="colItem.multiple">
            <vxe-select transfer v-model="row[colItem.field]" v-show="setCellCanInput( row ,colItem)"
                        :ref="colItem.field+rowIndex"
                        @change="changeValue(colItem,rowIndex,row)"
                        :disabled="setCellDisabled(row,colItem)" placeholder="请选择下拉"
                        multiple clearable>
              <vxe-option v-for="item in typeof colItem.options === 'function'?colItem.options():colItem.options"
                          :key="item[colItem.valueKey]"
                          :value="item[colItem.valueKey]"
                          :label="item[colItem.labelKey]"></vxe-option>
            </vxe-select>
          </template>

          <template v-else #edit="{ row,column,rowIndex }">
            <TableSelect :text="row[colItem.field + '_Name']?row[colItem.field + '_Name']:row[colItem.labelKey]"
                         v-if="setCellCanInput( row ,colItem)"
                         :field="colItem.field" :dataType="colItem.dataType"
                         :ref="colItem.field + rowIndex"
                         :keyValue="colItem.valueKey"
                         :label="colItem.labelKey"
                         :title="colItem.title"
                         :clearFlag="true"
                         :options="typeof colItem.options === 'function'?colItem.options():colItem.options"
                         :searchDataFlag="false"
                         :search-detail-flag="false"
                         :sortBoolean="colItem.sortBoolean"
                         @focus="handleSelectFocus(row,rowIndex,colItem)"
                         @change="inputChange(row,rowIndex,colItem)"
                         @clear="clearSelect(Object.assign({column:colItem,colIndex,rowIndex,row}))"
                         @keydown.stop="nextInputCellByKeyDown(Object.assign($event,{column:colItem,colIndex,rowIndex,row}))"
                         @onChoose="onChoose($event,row,column,rowIndex,colIndex,colItem.fieldUpdate,colItem)"
                         :poptipTransferClassName="colItem.poptipTransferClassName"
            ></TableSelect>
            <div class="edit-div-class" @dblclick.stop="copyValue(row,colItem,rowIndex)" v-else>
              {{ row[colItem.field + '_Name'] }}
            </div>
          </template>
        </vxe-column>

        <!--  date   -->
        <vxe-column v-if="colItem.type === 'date'" :params="{type:'date'}"
                    :field="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :title="$t(colItem.field)" :edit-render="{autofocus: '.vxe-input--inner'}">
          <!--          <template #header="{ row }">-->
          <!--            <span>{{ $t(colItem.title ? colItem.title : colItem.field) }}</span>-->
          <!--            <Poptip trigger="click" transfer @on-popper-hide="popperHide">-->
          <!--              <Icon type="iconfont iconfont icon-copy" style="cursor: pointer;" ref="down-input-icon"-->
          <!--                    v-if="colItem.copyVisible"/>-->
          <!--              <div slot="content">-->
          <!--                <div style="display: flex;align-items: center;justify-content: center;">-->
          <!--                  <DatePicker transfer v-model="inputDownValue" type="date"></DatePicker>-->
          <!--                  <Button type="primary" size="small" @click="inputDown(colItem)">{{ $t('filling') }}</Button>-->
          <!--                </div>-->
          <!--              </div>-->
          <!--            </Poptip>-->
          <!--            &lt;!&ndash;冻结/解冻列&ndash;&gt;-->
          <!--            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "-->
          <!--                  v-if="freezeData && colItem.freezeFlag"-->
          <!--                  type="ios-lock"-->
          <!--                  @click="handleFreeze(colItem.field)"/>-->
          <!--          </template>-->
          <template #default="{ row }">
            <span @dblclick.stop="copyValue(row,colItem)">{{ dateFormat(row[colItem.field]) }}</span>
          </template>
          <template #edit="{ row,rowIndex }">
            <DatePicker transfer :ref="colItem.field+rowIndex" v-model="row[colItem.field]" type="date"
                        @on-change="changeValue(colItem,rowIndex,row)"
                        v-show="setCellCanInput( row ,colItem)" :disabled="setCellDisabled(row,colItem)"></DatePicker>
          </template>
        </vxe-column>

        <!--  datetime   -->
        <vxe-column v-if="colItem.type === 'datetime'" :params="{type:'datetime'}"
                    :field="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :title="$t(colItem.field)" :edit-render="{autofocus: '.vxe-input--inner'}">
          <template #default="{ row }">
            <span @dblclick.stop="copyValue(row,colItem)">{{ dateTimeFormat(row[colItem.field]) }}</span>
          </template>
          <template #edit="{ row,rowIndex }">
            <DatePicker transfer :ref="colItem.field+rowIndex" v-model="row[colItem.field]" type="datetime"
                        @on-change="changeValue(colItem,rowIndex,row)"
                        v-show="setCellCanInput( row ,colItem)" :disabled="setCellDisabled(row,colItem)"></DatePicker>
          </template>
        </vxe-column>

        <!--  选择框  -->
        <vxe-column v-if="colItem.type === 'checkbox'" :field="colItem.field"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :tree-node="colItem.treeNode">
          <template #header="{ row }">
            <div class="checkbox-class">
              <vxe-checkbox :ref="colItem.field+'_header'" v-model="colItem.chooseAllFlag"
                            @change="clickAllCheckbox(colItem)"/>
            </div>
          </template>
          <template #default="{ row,rowIndex }">
            <div class="checkbox-class">
              <vxe-checkbox v-if="colItem.controlField?row[colItem.controlField]:true" size="small"
                            :ref="colItem.field+'_default_'+rowIndex"
                            :disabled="setCellDisabled(row,colItem)"
                            v-model="row[colItem.field]" @change="changeValue(colItem,rowIndex,row)"/>
            </div>
          </template>
          <template #edit="{ row,rowIndex }">
            <div class="checkbox-class">
              <vxe-checkbox v-if="colItem.controlField?row[colItem.controlField]:true" size="small"
                            :ref="colItem.field+'_default_'+rowIndex"
                            :disabled="setCellDisabled(row,colItem)"
                            v-model="row[colItem.field]" @change="changeValue(colItem,rowIndex,row)"/>
            </div>
          </template>
        </vxe-column>

        <!-- 开关 -->
        <vxe-column v-if="colItem.type === 'switch'" :params="{type:'switch'}"
                    :title="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    :header-class-name="colItem.required?'required-class':''"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :field="$t(colItem.field)" :edit-render="{autofocus: '.vxe-input--inner'}">
          <!--          <template #header="{ row }">-->
          <!--            <span>{{ $t(colItem.title ? colItem.title : colItem.field) }}</span>-->
          <!--            <Poptip trigger="click" transfer @on-popper-hide="popperHide">-->
          <!--              <Icon type="iconfont iconfont icon-copy" style="cursor: pointer;" ref="down-input-icon"-->
          <!--                    v-if="colItem.copyVisible"/>-->
          <!--              <div slot="content">-->
          <!--                <div style="display: flex;align-items: center;justify-content: center;">-->
          <!--                  <i-switch v-model="inputDownBooleanValue"/>-->
          <!--                  <Button type="primary" style="margin-left:10px" size="small" @click="inputDown(colItem)">-->
          <!--                    {{ $t('filling') }}-->
          <!--                  </Button>-->
          <!--                </div>-->
          <!--              </div>-->
          <!--            </Poptip>-->
          <!--            &lt;!&ndash;冻结/解冻列&ndash;&gt;-->
          <!--            <Icon ref="freeze" :class="colItem.freezeFlag?'freezed-class':'freeze-class' "-->
          <!--                  v-if="freezeData && colItem.freezeFlag"-->
          <!--                  type="ios-lock"-->
          <!--                  @click="handleFreeze(colItem.field)"/>-->
          <!--          </template>-->
          <template #default="{ row,rowIndex }">
            <!--          <span>{{ row[colItem.field] ? '是' : '否' }}</span>-->
            <div class="switch-class">
              <vxe-switch :ref="colItem.field+'_default_'+rowIndex" v-model="row[colItem.field]"
                          v-show="setCellCanInput( row ,colItem)"
                          @change="changeValue(colItem,rowIndex,row)"
                          :disabled="setCellDisabled(row,colItem)"/>
            </div>
          </template>
          <template #edit="{ row,rowIndex }">
            <div class="switch-class">
              <vxe-switch :ref="colItem.field+rowIndex" v-model="row[colItem.field]"
                          v-show="setCellCanInput( row ,colItem)"
                          @change="changeValue(colItem,rowIndex,row)"
                          :disabled="setCellDisabled(row,colItem)"/>
            </div>
          </template>
        </vxe-column>

        <!-- 按钮 -->
        <vxe-column v-if="colItem.type === 'button'" :params="{type:'button'}"
                    :title="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :field="$t(colItem.field)" :edit-render="{autofocus: '.vxe-input--inner'}">
          <template #default="{ row,rowIndex }">
            <vxe-button :ref="colItem.field+'_default_'+rowIndex" v-model="row[colItem.field]"
                        v-show="setCellCanInput( row ,colItem)"
                        :content="row[colItem.field] || colItem.defaultContent"
                        @click.native="buttonClick(colItem,rowIndex,row)"
                        :disabled="setCellDisabled(row,colItem)"
                        style="display: block"
                        :className="colItem.className" class="btn-class"
            />
          </template>
          <template #edit="{ row,rowIndex }">
            <vxe-button class="edit-button" :className="colItem.className" :ref="colItem.field+'_'+rowIndex"
                        v-model="row[colItem.field]"
                        v-show="setCellCanInput( row ,colItem)"
                        :content="row[colItem.field] || colItem.defaultContent"
                        style="display: block"
                        @click.native="buttonClick(colItem,rowIndex,row)"
                        :disabled="setCellDisabled(row,colItem)"></vxe-button>
          </template>
        </vxe-column>

        <!-- 文本按钮 -->
        <vxe-column v-if="colItem.type === 'textButton'" :params="{type:'textButton'}"
                    :title="colItem.title?colItem.title:$t(colItem.field)"
                    :type="colItem.type"
                    :width="colItem.width?colItem.width:vm.$config.columnWidth"
                    :min-width="colItem.minWidth?colItem.minWidth:vm.$config.columnWidthMin"
                    :field="$t(colItem.field)" :edit-render="{autofocus: '.vxe-input--inner'}">
          <template #default="{ row,rowIndex }">
            <div style="display: flex" v-show="setCellCanInput( row ,colItem)">
              <vxe-input :ref="colItem.field+'_default_'+rowIndex" v-model="row[colItem.field]"
                         style="width: calc(100% - 108px)"
                         :content="row[colItem.field]"
                         :readonly="true"/>
              <vxe-button class-name="text-button-class" content="选择"
                          @click.native="buttonClick(colItem,rowIndex,row)"></vxe-button>
            </div>
          </template>
          <template #edit="{ row,rowIndex }">
            <div style="display: flex" v-show="setCellCanInput( row ,colItem)">
              <vxe-input :ref="colItem.field+'_default_'+rowIndex" v-model="row[colItem.field]"
                         style="width: calc(100% - 108px)"
                         :content="row[colItem.field]"
                         :readonly="true"/>
              <vxe-button class-name="text-button-class" content="选择" @click.native="buttonClick(colItem,rowIndex,row)"
                          :disabled="colItem.disabled"></vxe-button>
            </div>
          </template>
        </vxe-column>

        <!--      checkbox-->
        <!--        <vxe-column type="checkbox" width="60" v-if="colItem.type === 'checkbox'"></vxe-column>-->
      </div>
    </vxe-table>
    <div class="setting-class" v-if="showSettingFlag"
         :style="'top:' + settingTop + ';left:' + settingLeft"
         @click="showSetting">
      <Icon ref="setting" type="md-settings"/>
    </div>
  </div>
</template>

<script>

import XEUtils from "xe-utils";
import SeqButton from '_c/sub/seq-button'
import Sortable from "sortablejs";
import TableSelect from '_c/business/table-select'
import {mapActions} from "vuex";

export default {
  name: 'EditTable',
  components: {SeqButton, TableSelect},
  props: {
    value: {
      type: Array,
      default: () => {
      }
    },
    // 表格标题
    title: {
      type: String,
      default: undefined,
    },
    // 标题说明
    titleInfo: {
      type: String,
      default: undefined,
    },
    // 数据源
    data: {
      type: Array,
      default: () => {
      }
    },
    // 列数据源
    columns: {
      type: Array,
      default: () => []
    },
    // 列表的高度
    height: {
      type: [String, Number],
      default: 300
    },
    // 列表的宽度
    divWidth: {
      type: String,
      default: '100%'
    },
    // 是否允许重复
    enabledRepeat: {
      type: Boolean,
      default: false
    },
    // 允许重复的列名称
    enabledRepeatId: {
      type: [String, Array],
      default: ''
    },
    //该行数据有值其他可输入单元格才能进行
    controlId: {
      type: String,
      default: ''
    },
    // 是否显示新增按钮
    addFlag: {
      type: Boolean,
      default: true
    },
    //是否显示删除按钮
    deleteFlag: {
      type: Boolean,
      default: true
    },
    // 控制删除按钮是否可见（外部传入的方法）
    canDelete: {
      type: Function,
      default: () => {
        return true
      }
    },
    // 唯一勾选的列表（用于switch,数据中只有一个勾选值）
    defaultField: {
      type: String,
      default: ''
    },
    //操作标识（新增、删除)是否可见
    operateFlag: {
      type: Boolean,
      default: true
    },
    // 是否显示新行
    newRowFlag: {
      type: Boolean,
      default: true
    },
    // 新增新行，不判断是否有数据
    newRowAlwaysFlag: {
      type: Boolean,
      default: false
    },
    //光标是否进入新增行
    focusFlag: {
      type: Boolean,
      default: false
    },
    //是否显示表头
    showHeader: {
      type: Boolean,
      default: true
    },
    //是否显示合计行
    showFooter: {
      type: Boolean,
      default: false
    },
    //表格名字
    name: {
      type: String,
      default: 'xTable'
    },
    //是否高亮显示
    highlightCurrentRow: {
      type: Boolean,
      default: false
    },
    requiredColumn: {
      type: Array,
      default: () => []
    },
    //主键Id
    majorField: {
      type: String,
      default: ''
    },
    //是否只读
    readonly: {
      type: Boolean,
      default: false
    },
    // 是否显示设置按钮
    showSettingFlag: {
      type: Boolean,
      default: true
    },
    // 是否开启冻结
    freeze: {
      type: Boolean,
      default: true,
    },
    // 鼠标移入进行编辑的标识
    mouseEnterEditFlag: {
      type: Boolean,
      default: true,
    },
    // 是否自动跳转到下一个可输入框
    autoNextFlag: {
      type: Boolean,
      default: true,
    },
    // 是否自动聚焦一行
    autoFocus: {
      type: Boolean,
      default: false,
    },
    // 错误提示信息显示列
    errorInfoFlag: {
      type: Boolean,
      default: false
    },
    // 表格样式
    className: {
      type: String,
      default: null
    },
    // 允许行移动
    rowDropFlag: {
      type: Boolean,
      default: true
    },
  },
  provide() {
    return {
      dkEditTable: this
    }
  },
  data() {
    const vm = window.vm;
    return {
      vm: vm,
      rowIndex: -1,
      colIndex: -1,
      existsFlag: true,  // 存在标识，用于销毁内部组件
      visibleRows: [],// 可见的行，用于控制
      header: {
        options: [
          [
            // <!--冻结-->
            {
              code: 'freeze', name: vm.$t('freeze'), disabled: false, visible: false, children: [
                {code: 'colFreeze', name: vm.$t('freeze'), disabled: false, visible: true},
                {code: 'clearFreeze', name: vm.$t('clearFreeze'), disabled: false, visible: false},
              ]
            },
            // <!--定位-->
            {
              code: 'position', name: vm.$t('positionItem'), disabled: false, visible: true, children: [
                {code: 'rowPosition', name: vm.$t('rowPosition'), disabled: false, visible: true},
                {code: 'exchange', name: '替换', disabled: false, visible: true},
                {code: 'colPosition', name: vm.$t('colPosition'), disabled: false, visible: true},
              ]
            },
            // <!--自适应列宽-->
            {
              code: 'adaption', name: vm.$t('adaption'), disabled: false, visible: true, children: [
                {code: 'selfAdaptionOne', name: vm.$t('selfAdaptionOne'), disabled: false, visible: true},
                {code: 'selfAdaption', name: vm.$t('selfAdaption'), disabled: false, visible: true},
              ]
            },
          ]
        ]
      },
      freezeData: false, // 是否开启冻结
      enabledEdit: true, //是否启用编辑模式
      modal1: true,
      filterWrapper: true,
      inputDownValue: null,
      inputDownBooleanValue: false,
      tableData: [],
      tableDataChange: [],  //改变集合
      isScroll: false,
      validRules: {},    //校验的规则
      deleteData: [],     //删除的数据
      columnsData: [],   //记录列
      currentRowIndex: 0,      // 当前行
      settingLeft: null,          // 设置图标居左的位置
      settingTop: null,           // 设置图标居上的位置
      clickShiftFlag: false,      // 是否点击shift按键
    }
  },
  watch: {
    newRowFlag(n, o) {
      if (n) {
        this.add();
      } else {
        this.tableData = []
      }
    },
    data(n, o) {
      // 编辑
      if (n && n.length > 0) {
        this.tableData = n
        this.handleSelectData();
      } else {
        this.tableData = []
        this.tableDataChange = []
        if (this.newRowFlag) {
          //新建时增加行
          this.add()
        }
      }
    },
    tableData(n, o) {
      if (n) {
        this.$emit('input', n)
      }
    },
  },
  methods: {
    ...mapActions([
      'setUserTableSettingAfter'
    ]),
    /**
     * @desc   : 给行赋值是否可以拖动
     * @author : 周兴
     * @date   : 2023/7/11 15:59
     */
    setRowClassName({row, rowIndex}) {
      let className = 'row_drop_class'
      if (this.$refs[this.name] && this.$refs[this.name].isActiveByRow(row)) {
        className = ''
      }
      return className;
    },
    /**
     * @desc   : 重新加载列
     * @author : 周兴
     * @date   : 2023/4/4 16:24
     */
    loadColumn(columns) {
      if (columns) {
        return this.$refs[this.name].loadColumn(columns);
      } else {
        const tableColumns = this.$refs[this.name].getTableColumn();
        this.$refs[this.name].loadColumn(tableColumns.fullColumn);
      }
    },
    /**
     * @desc   : 复制单元格
     * @author : 周兴
     * @date   : 2022/6/9 9:31
     */
    copyValue(row, colItem) {
      let field = colItem.field;
      if (row && row[field]) {
        let value = row[field];
        // 如果是下拉，需要读取_Name字段的值
        if (colItem.type === 'select') {
          if (row[field + '_Name'] != undefined) {
            value = row[field + '_Name']
          }
        }
        this.$message.success(vm.$t('copySuccess') + '：' + value);
        //创建一个input框
        const input = document.createElement("input");
        //将指定的DOM节点添加到body的末尾
        document.body.appendChild(input);
        //设置input框的value值为直播地址
        input.setAttribute("value", value);
        //选取文本域中的内容
        input.select();
        //copy的意思是拷贝当前选中内容到剪贴板
        //document.execCommand（）方法操纵可编辑内容区域的元素
        //返回值为一个Boolean，如果是 false 则表示操作不被支持或未被启用
        if (document.execCommand("copy")) {
          document.execCommand("copy");
        }
        //删除这个节点
        document.body.removeChild(input);
      }
    },
    /**
     * @desc   : 合计行的复制
     * @author : 周兴
     * @date   : 2022/8/6 11:15
     */
    handleFooterCopy(e) {
      if (e && e.items && e.items[e.itemIndex]) {
        let value = e.items[e.itemIndex] + '';
        value = value.replaceAll(',', '');
        this.$message.success(vm.$t('copySuccess') + '：' + value);
        //创建一个input框
        const input = document.createElement("input");
        //将指定的DOM节点添加到body的末尾
        document.body.appendChild(input);
        //设置input框的value值为直播地址
        input.setAttribute("value", value);
        //选取文本域中的内容
        input.select();
        //copy的意思是拷贝当前选中内容到剪贴板
        //返回值为一个Boolean，如果是 false 则表示操作不被支持或未被启用
        if (document.execCommand("copy")) {
          document.execCommand("copy");
        }
        //删除这个节点
        document.body.removeChild(input);
      }
    },
    /**
     * @desc   : 单元格样式
     * @author : 周兴
     * @date   : 2022/8/6 11:15
     */
    cellStyle({row, rowIndex, column}) {
      //序号居中
      if (column.type === 'seq' || column.field === 'seq' || column.type === 'checkbox' || column.type === 'date'
        || column.type === 'switch' || (column.params && column.params.type === 'disabled' && column.params.switch)) {
        return {textAlign: 'center'}
      } else if (column.type === 'number' || (column.params && column.params.type === 'disabled' && column.params.number)) {
        return {textAlign: 'right'}
      } else {
        return {textAlign: 'left'}
      }
    },
    /**
     * @desc   : 合计行的样式
     * @author : 周兴
     * @date   : 2022/8/3 15:31
     */
    footCellStyle({row, rowIndex, column}) {
      if (column.type === 'number' || column.number) {
        return {textAlign: 'right', background: '#FFF8E1', cursor: 'pointer'}
      } else {
        return {textAlign: 'left', background: '#FFF8E1'}
      }
    },
    /**
     * @desc   : 点击右键
     * @author : 周兴
     * @date   : 2022/12/19 11:12
     */
    closeAllPop(e) {
      this.$refs[this.name].$el.click(); //关闭表头的pop
    },
    /**
     * @desc   : 右键菜单
     * @author : 沈博
     * @date   : 2022/3/13 10:55
     */
    visibleMethod(e) {
      // 表格可以冻结
      if (this.freeze) {
        this.header.options[0].update({code: 'freeze', visible: true}, 'code', 'visible');
      }
      return true
    },
    /**
     * @desc   : 获取当前行
     * @author : 周兴
     * @date   : 2022/5/3 17:51
     */
    getCurrentRow() {
      return this.$refs[this.name].getCurrentRecord()
    },
    /**
     * @desc   : 获取当前列
     * @author : 周兴
     * @date   : 2023/12/18 16:37
     */
    getCurrentColumn() {
      return this.$refs[this.name].getCurrentColumn()
    },
    /**
     * @desc   : 获取当前列号
     * @author : 周兴
     * @date   : 2022/5/3 17:51
     */
    getCurrentColumnIndex() {
      let col = this.$refs[this.name].getCurrentColumn()
      if (col) {
        return this.$refs[this.name].getColumnIndex(col)
      }
    },
    /**
     * @desc   : 获取当前行号
     * @author : 周兴
     * @date   : 2022/5/3 17:51
     */
    getCurrentRowIndex() {
      let row = this.$refs[this.name].getCurrentRecord()
      if (row) {
        return this.$refs[this.name].getRowIndex(row)
      }
    },
    /**
     * @desc   : 点击右键按钮
     * @author : 周兴
     * @date   : 2022/3/30 17:24
     */
    menuClick(e) {
      if (e.menu.code == 'selfAdaption') {
        this.autoWidthHandle()
      } else if (e.menu.code == 'selfAdaptionOne') {
        this.autoWidthHandle(e)
      } else if (e.menu.code == 'export') {
        this.export(e.column.property)
      } else if (e.menu.code == 'rowPosition' || e.menu.code == 'exchange') {   // 行定位及替换
        this.showRowPosition(e, e.menu.code);
      } else if (e.menu.code == 'colPosition') {   // 列定位
        this.showColPosition(e);
      } else if (e.menu.code == 'colFreeze') { // 列冻结
        this.handleFreeze(e);
      } else if (e.menu.code == 'clearFreeze') {  // 解除冻结
        this.unFreeze(e);
      }
    },
    /**
     * @desc   : 显示行定位定位框
     * @author : 周兴
     * @date   : 2022/11/30 13:00
     */
    showRowPosition(e, code) {
      let tabValue = code == 'exchange' ? 'exchange' : 'search'
      this.$Position({component: this.$refs[this.name], tabValue, title: this.$t('findAndExchange')},
        {
          // 切换查询出的数据
          change: ({field, column, rowIndex, fields, equalFlag, searchText, noSelectAll, type}) => {
            // 没有查出数据
            if (noSelectAll) {
              this.changeFind(fields, equalFlag, searchText, type);// 查找下一条
            } else {
              // 定位当前行
              this.$refs[this.name].setCurrentRow(this.tableData[rowIndex]);
              // 定位当前列
              // this.$refs[this.name].setCurrentColumn(column);
              this.$nextTick(() => {
                this.$refs[this.name].scrollToRow(this.tableData[rowIndex]);
                this.$refs[this.name].scrollToColumn(column)
              });
            }
          },
          // 替换全部
          exchangeAll: (searchText, replaceText, fields, equalFlag) => {
            this.exchangeAll(searchText, replaceText, fields, equalFlag);
          },
          // 替换
          exchange: (searchText, replaceText, fields, equalFlag) => {
            this.exchange(searchText, replaceText, fields, equalFlag);
          },
        })
    },
    /**
     * @desc   : 改变列的标题
     * @author : 周兴
     * @date   : 2023/5/29 14:25
     */
    changeColumnTitle(field, title) {
      if (this.$refs['title_' + field] && this.$refs['title_' + field].length > 0) {
        this.$refs['title_' + field][0].innerText = title;
      }
    },
    /**
     * @desc   : 改变查找的行
     * @author : 周兴
     * @date   : 2023/2/16 13:05
     */
    changeFind(fields, equalFlag, searchText, type) {
      // 获取当前行
      let currentIndex = this.getCurrentRowIndex()
      if (!currentIndex && currentIndex != 0) {
        currentIndex = -1;
      }
      let table = this.tableData
      // 向下
      if (type === 'next') {
        for (let i = currentIndex + 1; i < table.length; i++) {
          let flag = this._changeFindItem(table[i], fields, equalFlag, searchText)
          if (flag) {
            return
          }
        }
      } else {
        // 向前
        for (let i = currentIndex - 1; i >= 0; i--) {
          let flag = this._changeFindItem(table[i], fields, equalFlag, searchText)
          if (flag) {
            return
          }
        }
      }
    },
    /**
     * @desc   : desc
     * @author : 周兴
     * @date   : 2023/2/16 13:09
     */
    _changeFindItem(item, fields, equalFlag, searchText) {
      // 模糊查询
      for (let it of fields) {
        // 值等
        if (equalFlag) {
          if ((item[it.field] + '') == searchText) {
            // 定位当前行
            this.$refs[this.name].setCurrentRow(item);
            this.$nextTick(() => {
              this.$refs[this.name].scrollToRow(item);
            });
            return true;
          }
        } else {
          // 模糊
          if ((item[it.field] + '').indexOf(searchText) >= 0) {
            // 定位当前行
            this.$refs[this.name].setCurrentRow(item);
            this.$nextTick(() => {
              this.$refs[this.name].scrollToRow(item);
            });
            return true;
          }
        }
      }
      return false;
    },
    /**
     * @desc   : 替换全部数据
     * @author : 周兴
     * @date   : 2023/2/15 14:49
     */
    exchangeAll(searchText, replaceText, fields, equalFlag) {
      let table = this.tableData
      let count = 0;
      for (let i = 0; i < table.length; i++) {
        // 模糊查询
        fields.forEach(it => {
          // 值等
          if (equalFlag) {
            if ((table[i][it.field] + '') == searchText) {
              this.$set(table[i], it.field, replaceText);
              this.setTableChange(table[i]); // 设置改变数据
              count++;
            }
          } else {
            // 模糊
            if ((table[i][it.field] + '').indexOf(searchText) >= 0) {
              let value = (table[i][it.field] + '').replaceAll(searchText, replaceText)
              this.$set(table[i], it.field, value);
              this.setTableChange(table[i]); // 设置改变数据
              count++;
            }
          }
        })
      }
      if (count > 0) {
        this.$message.success("已经完成查找并进行" + count + '处替换');
      }
    },
    /**
     * @desc   : 替换数据
     * @author : 周兴
     * @date   : 2023/2/15 14:49
     */
    exchange(searchText, replaceText, fields, equalFlag) {
      let table = this.tableData
      if (!table || table.length == 0) return;
      // 获取当前行
      let currentIndex = this.getCurrentRowIndex()
      if (!currentIndex && currentIndex != 0) {
        currentIndex = 0;
      }
      let checkFlag = false;
      // 判断当前有可以替换的数据
      // 值等
      if (equalFlag) {
        fields.forEach(it => {
          if ((table[currentIndex][it.field] + '') == searchText) {
            this.$set(table[currentIndex], it.field, replaceText);
            this.setTableChange(table[currentIndex]); // 设置改变数据
            checkFlag = true;
          }
        })
      } else {
        // 模糊
        fields.forEach(it => {
          // 模糊
          if ((table[currentIndex][it.field] + '').indexOf(searchText) >= 0) {
            let value = (table[currentIndex][it.field] + '').replaceAll(searchText, replaceText)
            this.$set(table[currentIndex], it.field, value);
            this.setTableChange(table[currentIndex]); // 设置改变数据
            checkFlag = true;
          }
        })
      }
      // 如果到最后一行，需要切换到第一行有数据的
      if (currentIndex === table.length - 1) {
        currentIndex = -1;
      }
      // 如果当前行没有数据，就跳转到下一行有匹配数据的行
      if (!checkFlag) {
        for (let i = currentIndex + 1; i < table.length; i++) {
          // 模糊查询
          for (let it of fields) {
            // 值等
            if (equalFlag) {
              if ((table[i][it.field] + '') == searchText) {
                // 定位当前行
                this.$refs[this.name].setCurrentRow(this.tableData[i]);
                this.$nextTick(() => {
                  this.$refs[this.name].scrollToRow(this.tableData[i]);
                });
                return;
              }
            } else {
              // 模糊
              if ((table[i][it.field] + '').indexOf(searchText) >= 0) {
                // 定位当前行
                this.$refs[this.name].setCurrentRow(this.tableData[i]);
                this.$nextTick(() => {
                  this.$refs[this.name].scrollToRow(this.tableData[i]);
                });
                return;
              }
            }
          }
        }
      }
    },
    /**
     * @desc   : 设置改变表格
     * @author : 周兴
     * @date   : 2023/2/15 14:56
     */
    setTableChange(row) {
      let rows = this.tableDataChange.filter(it => it['_X_ID'] === row['_X_ID']);
      //说明已经存在
      if (rows && rows.length > 0) {
        this.tableDataChange = this.tableDataChange.filter(it => it['_X_ID'] !== row['_X_ID']).map(it => it);
      }
      this.tableDataChange.push(row);
    },
    /**
     * @desc   : 显示列定位定位框
     * @author : 周兴
     * @date   : 2022/11/30 13:00
     */
    showColPosition(e) {
      let event = e.$event
      this.$Position({left: event.clientX, top: event.clientY},
        {
          ok: (searchText) => {
            this.handleColPosition(searchText);   // 执行列定位方法
          },
        })
    },
    /**
     *   @author : 寇珊珊
     *   @date   : 2022/3/23 16:29
     *   @desc   : 自适应全部列宽
     */
    autoWidthHandle(e) {
      if (this.tableData && this.tableData.length > 0) {
        let data = this.tableData.copy();
        if (e && e.column) {
          // 当前列的自适应
          let columnValues = data.map(it => {
            if (typeof it[e.column.field] == 'boolean') {
              return ''
            } else if (it[e.column.field] == null || it[e.column.field] == undefined) {
              return ''
            } else {
              return it[e.column.field]
            }
          });
          columnValues.push(e.column.title + '占')  // 把每列的表头也加进去算
          let width = this.getMaxLength(columnValues) + 30 // 每列内容最大的宽度 + 表格的内间距(依据实际情况而定)
          // this.$set(e.column, 'width', width)
          // 取这个宽度和最小宽度的最大值
          let minWidth = (e.column.minWidth + '')?.replace('px', '').toNum(0);
          this.$set(e.column, 'width', [width, minWidth].max())
        } else {
          // 全部可见列的自适应
          let columns = this.$refs[this.name].getColumns();
          columns.forEach(col => {
            if (col.type !== 'seq' && col.type !== 'radio' && col.type !== 'checkbox'
              && col.type !== 'operate' && col.type !== 'info'
              && col.type !== 'blank') {
              let columnValues = data.map(it => {
                if (typeof it[col.field] == 'boolean') {
                  return ''
                } else if (it[col.field] == null || it[col.field] == undefined) {
                  return ''
                } else {
                  return it[col.field]
                }
              });
              columnValues.push(col.title + '占')  // 把每列的表头也加进去算
              let width = this.getMaxLength(columnValues) + 30 // 每列内容最大的宽度 + 表格的内间距(依据实际情况而定)
              // this.$set(col, 'width', width)
              // 取这个宽度和最小宽度的最大值
              let minWidth = (col.minWidth + '')?.replace('px', '').toNum(0);
              this.$set(col, 'width', [width, minWidth].max())
            }
          })
        }
        this.$nextTick(() => {
          this.$refs[this.name].resetColumn({resizable: true})
          this.$refs[this.name].recalculate()
        })
      }
    },
    /**
     * @desc   : 打开非标的窗体
     * @author : 周兴
     * @date   : 2024/5/24 14:17
     */
    openNonStandardForm(e){
      setTimeout(() => {
        if (this.$refs[e.colItem.field + e.rowIndex] && this.$refs[e.colItem.field + e.rowIndex].length > 0) {
          this.$refs[e.colItem.field + e.rowIndex][0].togglePanel()
        }
      }, 30)
    },
    /**
     * @desc   : 修改非标类组件的值
     * @author : 周兴
     * @date   : 2024/5/24 14:54
     */
    changeNonStandard(e,row,rowIndex,colItem){
      this.$emit('changeNonStandard',{row,rowIndex,field:colItem.field})
    },
    /**
     * @desc   : 解除冻结
     * @author : 周兴
     * @date   : 2022/12/1 13:30
     */
    unFreeze() {
      const tableColumns = this.$refs[this.name].getTableColumn()
      if (tableColumns && tableColumns.visibleColumn) {
        tableColumns.visibleColumn.forEach(it => {
          if (it.type != 'seq' && it.type != 'radio' && it.type != 'checkbox') {
            it.fixed = ''
          }
        })
        this.columnsData.forEach(it => {
          it.freezeFlag = false;
        })
        // 清空冻结不可见
        // this.header.options[0].update({code: 'clearFreeze', visible: false}, 'code', 'visible');
        let filters = this.header.options[0].filter(it => it.code === 'freeze');
        if (filters && filters.length > 0) {
          filters[0].children.update({code: 'clearFreeze', visible: false}, 'code', 'visible');
        }
        this.$refs[this.name].refreshColumn();
      }
    },
    /**
     * @desc   : 冻结列
     * @author : 周兴
     * @date   : 2022/11/30 17:28
     */
    handleFreeze(e) {
      let field = e.column.field;
      const tableColumns = this.$refs[this.name].getTableColumn()
      if (tableColumns && tableColumns.visibleColumn) {
        let columnIndex = 0;
        tableColumns.visibleColumn.forEach((it, index) => {
          it.fixed = ''
          if (it.field === field) {
            columnIndex = index;
          }
        })
        // 冻结该列之前的列，包括这列
        for (let i = 0; i <= columnIndex; i++) {
          tableColumns.visibleColumn[i].fixed = 'left'
        }
        // 先把所有的冻结标识都去掉
        this.columnsData.forEach(it => {
          it.freezeFlag = false;
        })
        // 找到当前列，给其赋值冻结标识
        let colItems = this.columnsData.filter(it => it.field === field);
        if (colItems && colItems.length > 0) {
          colItems[0].freezeFlag = true;
        }
        // 清空冻结可见
        // this.header.options[0].update({code: 'clearFreeze', visible: true}, 'code', 'visible');
        let filters = this.header.options[0].filter(it => it.code === 'freeze');
        if (filters && filters.length > 0) {
          filters[0].children.update({code: 'clearFreeze', visible: true}, 'code', 'visible');
        }
        this.$refs[this.name].refreshColumn();
      }
    },
    /**
     * @desc   : 下拉聚焦事件
     * @author : 周兴
     * @date   : 2022/4/22 9:10
     */
    handleSelectFocus(row, rowIndex, colItem) {
      this.$emit('on-select-focus', colItem.field, row, rowIndex)
    },
    /**
     * @desc   : 给下拉数据源增加Name列
     * @author : 周兴
     * @date   : 2022/4/22 9:02
     */
    handleSelectData() {
      let options = []
      //记录下拉的列
      this.columns.forEach(col => {
        if (col.type === 'select') {
          if (this.tableData && this.tableData.length > 0) {
            //获取下拉数据源
            if (typeof col.options === 'function') {
              options = col.options()
            }
            this.tableData.forEach(row => {
              if (row[col.field]) {
                if (col.multiple) {
                  let selectVal = options.filter(it => row[col.field].includes(it[col.valueKey]));
                  if (selectVal) {
                    this.$set(row, col.field + '_Name', selectVal.map(it => {
                      return it[col.labelKey]
                    }).toString())
                  }
                } else {
                  let selectVal = options.filter(it => row[col.field] === it[col.valueKey])[0];
                  if (selectVal) {
                    this.$set(row, col.field + '_Name', selectVal[col.labelKey])
                  }
                }
              }
            })
          }
        }
      })
    },
    /**
     * @desc   : 点击表格的keydown自动进入第一个单元格
     * @author : 周兴
     * @date   : 2022/4/19 13:17
     */
    handleTableKeyDown(e) {
      // console.log('bbbb', e)
      if (e.$event.key === 'Enter') {
        this.$refs[this.name].setActiveCell(this.tableData[0], this.columns[0].field);
        this.handleFocus(this.columns[0], 0);
      } else if (e.$event.key === 'ArrowDown') {
        // 向下
        let rowIndex = this.getCurrentRowIndex();
        // console.log('rrrd', rowIndex, this.tableData.length)
        if (rowIndex < this.tableData.length - 1) {
          this.$refs[this.name].setActiveRow(this.tableData[rowIndex + 1])
          this.$refs[this.name].setCurrentRow(this.tableData[rowIndex + 1])
          this.$refs[this.name].setActiveCell(this.tableData[rowIndex + 1], e.$event.column.field);
          this.handleFocus(e.$event.column, rowIndex + 1);
        }
      } else if (e.$event.key === 'ArrowUp') {
        // 向上
        let rowIndex = this.getCurrentRowIndex();
        if (rowIndex > 0) {
          this.$refs[this.name].setActiveRow(this.tableData[rowIndex - 1])
          this.$refs[this.name].setCurrentRow(this.tableData[rowIndex - 1])
          this.$refs[this.name].setActiveCell(this.tableData[rowIndex - 1], e.$event.column.field);
          this.handleFocus(e.$event.column, rowIndex - 1);
        }
      }
    },

    /**
     * @desc   : 点击单元格
     * @author : 周兴
     * @date   : 2023/5/16 9:32
     */
    handleCellClick(e) {
      this.$emit('cell-click', e)
    },
    /**
     * @desc   : 点击事件
     * @author : 周兴
     * @date   : 2023/10/16 14:48
     */
    handleClick(e) {
      this.$emit('click', e)
    },
    /**
     * @desc   : 表头点击事件
     * @author : 周兴
     * @date   : 2023/10/16 15:29
     */
    handleHeaderCellClick(e) {
      this.$emit('header-cell-click', e)
    },
    /**
     * @desc   : 增加当前行hover
     * @author : 周兴
     * @date   : 2023/5/17 16:39
     */
    addHover(rowIndex) {
      if (this.readonly) {
        return;
      }
      if (this.operateFlag) {
        // 如果行不变，不用执行
        if (rowIndex != this.rowIndex) {
          if (this.tableData && this.tableData.length > 0) {
            this.tableData.forEach(it => {
              this.$set(it, '_hover', false)
            })
          }
        }
        setTimeout(() => {
          if (rowIndex >= 0 && this.tableData[rowIndex]) {
            this.$set(this.tableData[rowIndex], '_hover', true)
          }
        }, 30)
      }
    },
    /**
     * @desc   : 鼠标移入增加新增和删除按钮
     * @author : 周兴
     * @date   : 2022/4/19 10:56
     */
    handleCellMouseEnter(e) {
      // if (this.readonly) {
      //   return;
      // }
      // if (this.operateFlag) {
      //   // 如果行不变，不用执行
      //   if (e && (e.rowIndex != this.rowIndex)) {
      //     if (this.tableData && this.tableData.length > 0) {
      //       this.tableData.forEach(it => {
      //         this.$set(it, '_hover', false)
      //       })
      //     }
      //   }
      //   setTimeout(() => {
      //     if (e.rowIndex >= 0 && this.tableData[e.rowIndex]) {
      //       this.$set(this.tableData[e.rowIndex], '_hover', true)
      //     }
      //   }, 300)
      // }
      // // 鼠标移入后，当前行变为编辑状态
      // if (e && e.row) {
      //   this.colIndex = e.columnIndex;
      //   // 鼠标移入自动进行行切换
      //   if (this.mouseEnterEditFlag) {
      //     // this.$refs[this.name].setActiveRow(e.row)
      //     // // console.log('ttt',e.row,e.rowIndex,this.currentRowIndex)
      //     // this.$refs[this.name].setCurrentRow(e.row)
      //     // if(this.rowIndex !== e.rowIndex){
      //     //   this.currentChangeGetData({ oldRowIndex:this.rowIndex,rowIndex:e.rowIndex })
      //     // }
      //   }
      //   this.rowIndex = e.rowIndex;
      // }
    },
    /**
     * @desc   : 鼠标移出删除新增和删除按钮
     * @author : 周兴
     * @date   : 2022/4/19 10:56
     */
    handleCellMouseLeave(e) {
      // if (this.operateFlag) {
      //   setTimeout(() => {
      //     if (e && e.rowIndex != this.rowIndex) {
      //       if (e.rowIndex >= 0 && this.tableData[e.rowIndex]) {
      //         this.$set(this.tableData[e.rowIndex], '_hover', false)
      //       }
      //     }
      //   }, 300)
      // }
    },
    /**
     * @desc   : 开关控制
     * @author : 周兴
     * @date   : 2022/6/23 9:09
     */
    switchValue(colItem, rowIndex, row) {
      if (colItem.switchField) {
        if (colItem.type === 'switch') {
          // 如果开关开启，那么相关列修改为0
          if (row[colItem.field] && this.tableData[rowIndex][colItem.switchField]) {
            this.tableData[rowIndex][colItem.switchField] = 0;
            // 重新计算
            this.calc(colItem.switchField, rowIndex);
          }
        } else {
          let flag = false;
          // 控制开关列
          if (row[colItem.field] && row[colItem.field] != 0) {
            flag = false;
            this.tableData[rowIndex][colItem.switchField] = false;
          } else {
            flag = true;
            this.tableData[rowIndex][colItem.switchField] = true;
          }
        }
      }
    },
    /**
     * @desc   : 值改变
     * @author : 周兴
     * @date   : 2022/4/10 14:21
     */
    changeValue(colItem, rowIndex, row) {
      let field = colItem.field;
      //数值
      if (colItem.type === 'number') {
        //TODO 负号设置
        // 如果是这里必须是负数，需要自动转为负数
        let neg = typeof colItem.negative == 'function' ? colItem.negative() : colItem.negative;
        let number = parseFloat(row[field]);
        if (neg && number > 0) {
          this.tableData[rowIndex][field] = -1 * number;
        }
        this.tableData[rowIndex][field] = row[field] ? parseFloat(row[field]) : undefined;
        // 判断最大值最小值
        let max = colItem.max?colItem.max:this.$config.maxNumber;
        if(number > max){
          // 大于最大值取最大值
          this.tableData[rowIndex][field] = max;
        }
        let min = colItem.min?colItem.min:this.$config.minNumber;
        if(number < min){
          // 小于最小值取最小值
          this.tableData[rowIndex][field] = min;
        }
        this.calc(field, rowIndex);      //计算
      } else if (colItem.type === 'text') { // 文本
        if (colItem.field != 'remarks' && (colItem.upperFlag == undefined || colItem.upperFlag)) {
          row[field] = row[field]?.toUpperCase();  // 备注默认转大写
        }
      } else if (colItem.type === 'select' && colItem.multiple) {
        let options = typeof colItem.options === 'function' ? colItem.options() : colItem.options;
        let selectVal = options.filter(it => row[field].includes(it[colItem.valueKey]));
        if (selectVal) {
          this.$set(row, field + '_Name', selectVal.map(it => {
            return it[colItem.labelKey]
          }).toString())
        }
      }
      //开关
      this.switchValue(colItem, rowIndex, row);
      // 有联动，数据改变需要清空对应的列数据
      this.columns.forEach(it => {
        if (it.controlIds && it.controlIds.length > 0) {
          //说明这列管控其他列
          if (it.controlIds.includes(field)) {
            row[it.field] = null;
          }
        }
      })
      // 如果勾选的是指定的列
      if (this.defaultField && colItem.field === this.defaultField) {
        this.changeDefaultFieldValue(row);
      }
      //把改变的行加入到tableDataChange中
      // console.log('row',this.tableDataChange,row)
      let rows = this.tableDataChange.filter(it => it['_X_ID'] === row['_X_ID']);
      //说明已经存在
      if (rows && rows.length > 0) {
        this.tableDataChange = this.tableDataChange.filter(it => it['_X_ID'] !== row['_X_ID']).map(it => it);
      }
      this.tableDataChange.push(row);
      this.$emit('changeValue', field, row, rowIndex);
      // 更新合计行
      this.$refs[this.name].updateFooter();
    },
    /**
     * @desc   : 改变值
     * @author : 周兴
     * @date   : 2022/8/5 13:38
     */
    changeDefaultFieldValue(row) {
      // 如果勾选这条，那么其他条要设置为不勾选
      if (row[this.defaultField]) {
        this.tableData.forEach(it => {
          if (it['_X_ID'] !== row['_X_ID']) {
            it[this.defaultField] = false;
          }
        })
      } else {
        // 如果去掉本条勾选，那么默认第一条作为勾选项
        for (let i = 0; i < this.tableData.length; i++) {
          if (this.tableData[i]['_X_ID'] !== row['_X_ID']) {
            this.tableData[i][this.defaultField] = true;
            break;
          }
        }
      }
    },
    /**
     * @desc   : 设置单元格是否可以输入
     * @author : 周兴
     * @date   : 2022/4/7 15:20
     */
    setCellCanInput(row, column) {
      // 如果已经在可视范围内，不用再走
      let flag = false;
      if (this.controlId) {
        //console.log('ttt',this.controlId,row[this.controlId],row)
        //看这列是否需要进行管控
        if (column.controlId && this.controlId === column.controlId) {
          flag = true;
        } else {
          //如果该行controlId有值，不管控
          if (row[this.controlId]) {
            flag = true;
          }
        }
      } else {
        flag = true;
        // 如果列设置了管控
        if (column.controlIds && column.controlIds.length > 0) {
          for (let i in column.controlIds) {
            //如果有任意一个没有数据，那么就不允许
            if (!row[column.controlIds[i]]) {
              flag = false;
              break;
            }
          }
        }
      }
      /* 除了controlId之外，还有新的校验 */
      if (flag) {
        if (column.editStatus) {
          // console.log('订制品',column.editStatus(row),row)
          flag = column.editStatus(row)
        }
      }

      // 在disbaled中控制
      if (flag && (column.type === 'select' || column.type === 'text' || column.type === 'number'
        || column.type === 'button')) {
        //列设置为只读
        if (column.readOnly) {
          flag = false;
        }
        if (row['readOnly']) {
          let readOnly = row['readOnly']
          if (readOnly.indexOf(column.field) >= 0) {
            flag = false;
          }
          // 如果是整行，那么就直接禁用
          if (readOnly === 'all') {
            flag = false;
          }
        }
      }
      return flag;
    },
    /**
     * @desc   : 控制下拉选择是否出现
     * @author : 周兴
     * @date   : 2022/6/6 14:39
     */
    setCellCanTableSelect(row, column) {
      //如果这列是否禁用的，就不能选择
      if (this.readonly) {
        return false;
      } else if (typeof column.disabled === 'function' ? column.disabled() : column.disabled) {
        return false;
      } else {
        if (this.controlId) {
          //看这列是否需要进行管控
          if (column.controlId) {
            if (this.controlId !== column.controlId) {
              return false;
            }
          } else {
            if (!row[this.controlId]) {
              return false;
            }
          }
        }
        if (row['readOnly']) {
          let readOnly = row['readOnly']
          if (readOnly.indexOf(column.field) >= 0) {
            return false;
          }
          // 如果是整行，那么就直接禁用
          if (readOnly === 'all') {
            return false;
          }
        }
      }
      return true;
    },
    /**
     * @desc   : 设置是否只读
     * @author : 周兴
     * @date   : 2022/4/11 14:22
     */
    setCellDisabled(row, column) {
      // 按照行进行控制列
      if (row && row.readOnly) {
        let readOnly = row.readOnly
        // console.log('eee',readOnly,column.field,readOnly.indexOf(column.field))
        if (readOnly.indexOf(column.field) >= 0) {
          return true;
        }
        // 如果是整行，那么就直接禁用
        if (readOnly === 'all') {
          return false;
        }
      }
      return false;
    },
    /**
     * @desc   : 点击表头的checkbox全选/全不选
     * @author : 周兴
     * @date   : 2023/5/9 13:30
     */
    clickAllCheckbox(colItem) {
      if (this.tableData && this.tableData.length > 0) {
        this.tableData.forEach(it => {
          it[colItem.field] = colItem.chooseAllFlag
        })
      }
    },
    /**
     * @desc   : 点击按钮
     * @author : 周兴
     * @date   : 2023/3/26 16:11
     */
    buttonClick(colItem, rowIndex, row) {
      this.$emit('button-click', row, rowIndex, colItem)
    },
    /**
     * @desc   : 控制跳转到下一个输入格
     * @author : 周兴
     * @date   : 2022/4/9 13:40
     */
    nextInputCellByKeyDown(e) {
      //如果点击回车需要进入下一个可输入单元格
      // console.log('eeee',e)
      if (e.keyCode === 16) {
        this.clickShiftFlag = true;
        // 1分钟失效，
        setTimeout(() => {
          this.clickShiftFlag = false;
        }, 1000)
      }
      if (e.keyCode === 13 || (e.keyCode === 9 && !this.clickShiftFlag)) {
        //回车的时候阻止冒泡事件
        e.stopPropagation();
        //如果是点击过去的，就不用再走一次
        if (e.type === 'keyup') return;
        //跳转到下一个可输入单元格
        this.nextInputCell(e.row, e.rowIndex, e.colIndex, e.column.field, e.column);
      }
    },
    /**
     * @desc   : 控制数值的输入
     * @author : 周兴
     * @date   : 2022/4/5 22:28
     */
    controlNumber(e) {
      this.$emit('on-keydown', e)
      //回车和tab的时候阻止冒泡事件
      if (e.keyCode === 13) {
        e.stopPropagation();
      }
      //控制跳转到下一个输入格
      this.nextInputCellByKeyDown(e);
      //backspace,delete,enter，左右不控制
      if (e.keyCode === 8 || e.keyCode === 46 || e.keyCode === 37
        || e.keyCode === 39 || e.keyCode === 13) {
        return;
      }
      // 获取小数位数
      let digits = 0;
      if (e.column.digits) {
        digits = e.column.digits;
      } else {
        //如果没有设置小数位数，那么就读取商品中的计量单位
        if (e.row.decimalPlaces) {
          digits = e.row.decimalPlaces;
        }
      }
      //ctrl+v,ctrl+c不控制
      if ((e.key === 'v' || e.key === 'c') && e.ctrlKey) {
        return;
      }
      //查看是否有选中数据，再输入的情况
      let selectedLength = e.target.selectionEnd - e.target.selectionStart;
      if (selectedLength > 0) {
        return;
      }
      let num = e.target.value + "" + e.key;
      //说明是插入到字符串中的
      if (e.target.selectionEnd < e.target.value.length) {
        num = this.$libaray.insertStr(e.target.value, e.target.selectionEnd, e.key)
      }
      // let negativeFlag = e.column.negative ? true : false;
      // let negativeFlag = e.column.negative ? true : false;
      // if (!this.$libaray.getRegex(digits, negativeFlag).test(num)) {
      //   e.preventDefault();
      // } else {
      // //如果有最大值，需要判断不要超过最大值
      // let max = e.column.max ? e.column.max : this.$config.maxNumber;
      // if (num >= parseFloat(max)) {
      //   e.preventDefault();
      // }
      // // 如果有最小值，需要判断不小于最小值
      // let min = e.column.min ? e.column.min : this.$config.minNumber;
      // if (num <= parseFloat(min)) {
      //   e.preventDefault();
      // }
      // }
    },
    /**
     * @desc   : 控制数值的输入
     * @author : 周兴
     * @date   : 2022/4/5 22:28
     */
    handleKeyup(e) {
      // 获取小数位数
      let digits = 0;
      if (e.column.digits) {
        digits = e.column.digits;
      } else {
        //如果没有设置小数位数，那么就读取商品中的计量单位
        if (e.row.decimalPlaces) {
          digits = e.row.decimalPlaces;
        }
      }
      //复制时调用改变事件
      if (e.key === 'v' && e.ctrlKey) {
        this.changeValueByCtrlV(e, digits);
      }
    },
    /**
     * @desc   : 值改变
     * @author : 周兴
     * @date   : 2022/4/10 14:21
     */
    changeValueByCtrlV(e, digits) {
      let value = e.target.value
      if (Number.isNaN(Number(value))) {
        e.target.value = null;
        this.tableData[e.rowIndex][e.column.field] = null;
      } else {
        //正则表达式去控制输入
        if (!this.$libaray.getRegex(digits).test(value)) {
          value = XEUtils.toFixed(XEUtils.round(value, digits), digits);
        }
        //判断是否超过最大值，如果超过最大值，就取最大值
        let max = e.column.max ? e.column.max : this.$config.maxNumber;
        if (parseFloat(value) >= max) {
          //获取最大值
          let maxValue = this.$libaray.getMaxValue(max, digits);
          e.target.value = maxValue;
          this.tableData[e.rowIndex][e.column.field] = maxValue;
        } else {
          e.target.value = value;
          this.tableData[e.rowIndex][e.column.field] = value;
        }
      }
    },
    /**
     * @desc   : 格式化列
     * @author : 周兴
     * @date   : 2022/4/4 13:40
     */
    formatColumn({column, cellValue, row}) {
      //默认显示空值
      if (cellValue === undefined || !column.params) {
        return null;
      }
      let param = column.params
      // 只有数值类型，或者是diable类型中数值的需要进行处理
      if (param.type === 'number' || param.number) {
        //获取小数位数
        let digits = 0;

        if (param.digits || param.digits == 0) {
          digits = param.digits;
        } else {
          //如果没有设置小数位数，那么就读取商品中的计量单位
          if (row.decimalPlaces) {
            digits = row.decimalPlaces;
          }
        }
        // 数值列开启千分位过滤 (默认开启千分位)
        if (param.formatThousandth == undefined || param.formatThousandth) {
          if (cellValue != null) {
            //没有开启千分位
            return XEUtils.commafy(Number(cellValue), {digits});
          }
        } else {
          if (cellValue != null) {
            //没有开启千分位
            return XEUtils.toFixed(XEUtils.round(cellValue, digits), digits);
          }
        }
      } else {
        //日期
        if (param.date && cellValue != null) {
          return new Date(cellValue).format('yyyy-MM-dd');
        } else {
          // 如果不是数值，就直接返回
          return cellValue;
        }
      }
    }
    ,
    /**
     * @desc   : 合计行运算
     * @author : 周兴
     * @date   : 2022/3/31 11:28
     */
    footerMethod({data}) {
      //如果不开启合计行，那么就不走该方法
      if (!this.showFooter) return;
      let total = this.$t('totalSum');
      const sums = []
      if (sums.indexOf(total) < 0) {
        sums.push(total)
      }
      let sumCell = null;
      // this.$nextTick(() => {
      for (let column of this.columns) {
        sumCell = null;
        if ((column.type === vm.$config.columnType.number
          || column.number) && column.sum) {
          let digits = 0;
          //小数位数
          if (column.digits) {
            digits = column.digits;
          }
          data.forEach(item => {
            sumCell += Number(item[column.field] == undefined ? 0 : item[column.field])
          })
          //格式化金额开启(默认开启)
          if (column.formatThousandth == undefined || column.formatThousandth) {
            sumCell = XEUtils.commafy(Number(sumCell), {digits})
          }
        }
        sums.push(sumCell);
      }
      // })
      return [sums]
    }
    ,
    /**
     * @desc   : poper隐藏事件
     * @author : 沈博
     * @date   : 2022/3/13 10:10
     */
    popperHide() {
      this.inputDownValue = null
    },
    /**
     * @desc   : poper显示事件 TODO
     * @author : 周兴
     * @date   : 2022/4/11 11:37
     */
    popperShow(colIndex, type) {
      // console.log('field', this.$refs['pop_' + colIndex], this.columns)
      this.$nextTick(() => {
        if (!type) {
          this.$refs['pop_' + colIndex][0].$refs.input.focus();
        } else {
          this.$refs['pop_' + colIndex][0].$refs.inputNumber.focus();
        }
      })
    },
    /**
     * @desc   : 获取删除的数据
     * @author : 周兴
     * @date   : 2022/6/18 16:32
     */
    getDeleteData() {
      let table = this.deleteData ? this.deleteData.copy() : []
      return table;
    },
    /**
     * @desc   : 获取数据
     * @author : 周兴
     * @date   : 2022/4/10 11:38
     */
    getTableData() {
      let table = this.tableData ? this.tableData.copy() : []
      return table;
    },
    /**
     * @desc   : 获取过滤掉主键数据没有选择的信息
     * @author : 周兴
     * @date   : 2022/4/10 11:39
     */
    getTableDataFilter() {
      let table = this.tableData ? this.tableData.copy() : []
      if (this.controlId) {
        table = table.filter(it => it[this.controlId]);
        table.forEach((it, index) => {
          this.$set(it, 'itemIndex', index + 1);
        });
      }
      return table;
    },
    /**
     * @desc   : 获取改变的数据
     * @author : 周兴
     * @date   : 2022/4/10 11:38
     */
    getTableChangeData() {
      let table = this.tableDataChange ? this.tableDataChange.copy() : []
      return table;
    },
    /**
     * @desc   : 清除掉变化数据
     * @author : 周兴
     * @date   : 2022/4/21 17:24
     */
    clearTableChangeData() {
      this.tableDataChange = [];
    },
    /**
     * @desc   : 清空数据
     * @author : 周兴
     * @date   : 2022/4/21 17:24
     */
    clearTable() {
      this.tableData = [];
      this.tableDataChange = [];
      if (this.operateFlag && this.newRowFlag) {
        // 新增一行
        this.add();
      }
    },
    /**
     * @desc   : 文本输入后执行的事件
     * @author : 周兴
     * @date   : 2022/4/6 13:52
     */
    editClosed(e) {
      this.$emit('editClosed', e, this.tableData)
    },
    /**
     * @desc   : 点击行执行事件
     * @author : 于继渤
     * @date   : 2022/4/21 13:43
     */
    currentChangeGetData(e) {
      e.oldRowIndex = this.currentRowIndex;
      this.$emit('current-change', e, this.tableData);
      this.currentRowIndex = e.rowIndex;
      // 给当前行增加hover
      this.addHover(this.currentRowIndex);
    },
    /**
     * @desc   : 根据field获取
     * @author : 周兴
     * @date   : 2022/6/16 8:44
     */
    getColumnByField(field) {
      for (let i = 0; i < this.columns.length; i++) {
        if (this.columns[i].field === field) {
          return this.columns[i];
        }
      }
    },
    /**
     * @desc   : 根据field获取
     * @author : 周兴
     * @date   : 2022/6/16 8:44
     */
    getColumnIndexByField(columns, field) {
      for (let i = 0; i < columns.length; i++) {
        if (columns[i].property === field) {
          return i;
        }
      }
    },
    /**
     * @desc   : 设置主从数据赋值
     * @author : 周兴
     * @date   : 2023/5/9 15:53
     */
    getMultiSelect(e) {
      if (this.tableData[e.rowIndex]) {
        this.$set(this.tableData[e.rowIndex], e.colItem.field, e.rows)
        this.$set(this.tableData[e.rowIndex], e.colItem.field + '_Name', e.display)
      }
    },
    /**
     * @desc   : 跳转到下一个可输入单元格
     * @author : 周兴
     * @date   : 2022/4/7 15:36
     */
    nextInputCell(row, rowIndex, columnIndex, field, colItem) {
      //如果下拉选择数据没有选择，点回车光标不离开 用columnIndex去查不对，因为位置可能会移动，并且column的列也可能跟列表的顺序不一致
      let filterColumn = this.getColumnByField(field);
      if (filterColumn && filterColumn.controlId && row[field] === null) {
        this.$refs[this.name].setActiveCell(this.tableData[rowIndex], field);
        this.handleFocus(filterColumn, rowIndex);
        return;
      }
      let visibleColumns = this.$refs[this.name].getTableColumn().visibleColumn;
      this.isScroll = true;
      let currentColumnIndex = columnIndex;
      //如果是最后一列那么跳转到下一行
      if (field === visibleColumns[visibleColumns.length - 1].field) {
        rowIndex = parseInt(rowIndex) + 1
        columnIndex = 0;
      } else {
        // 根据field后去列的顺序
        columnIndex = this.getColumnIndexByField(visibleColumns, field) + 1;
      }
      //设置单元格激活状态
      for (let i = rowIndex; i < this.tableData.length; i++) {
        for (let j = columnIndex; j < visibleColumns.length; j++) {
          filterColumn = this.getColumnByField(visibleColumns[j].field);
          //列只读以及行单元格只读
          if (filterColumn && filterColumn.type !== 'disabled' && filterColumn.type !== 'switch') {
            // 不能从同一个controlId的列跳转到下一列
            if (filterColumn.controlId && colItem.controlId
              && filterColumn.controlId === colItem.controlId) {
              continue;
            } else {
              // console.log('bbb', rowIndex, visibleColumns[j].field, filterColumn)
              this.$refs[this.name].setActiveRow(this.tableData[i])
              this.$refs[this.name].setCurrentRow(this.tableData[i])
              this.$refs[this.name].setActiveCell(this.tableData[i], visibleColumns[j].field);
              // 焦点落在各控件上
              this.handleFocus(filterColumn, i);
            }
            // 如果是第一列，需要设置滚动，不然不会回到第一个列的位置
            if (j === 0) {
              this.$refs[this.name].scrollTo(0, 0);
            }
            // 延迟更新不然就会让 滚动先执行
            setTimeout(() => {
              this.isScroll = false;
            }, 500)
            return;
          }
        }
      }
      this.isScroll = false;
    },
    /**
     * @desc   : 单元格编辑结束后，光标停留在对应的位置
     * @author : 周兴
     * @date   : 2022/4/10 14:02
     */
    handleFocus(column, rowIndex) {
      setTimeout(() => {
        // console.log(e)
        if (column.type) {
          switch (column.type) {
            case 'date':
            case 'number':
            case 'text':
              if (this.$refs[column.field + rowIndex] && this.$refs[column.field + rowIndex].length > 0) {
                this.$refs[column.field + rowIndex][0].focus()
                this.$refs[column.field + rowIndex][0].$refs['input'].focus()
              }
              break;
            case 'switch':
              this.$refs[column.field + rowIndex][0].$el.focus()
              break;
            // case 'select':
            //   console.log('res',column.field + rowIndex)
            //   // this.$refs[column.field + rowIndex][0].focus()
            //   this.$refs[column.field + rowIndex][0].isActivated = true
            //   this.$refs[column.field + rowIndex][0].$refs.input.focus()
            //   break;
            case 'tableSelect':
            case 'select':
              // console.log('bb4', this.$refs[column.field + rowIndex], rowIndex)
              if (this.$refs[column.field + rowIndex] && this.$refs[column.field + rowIndex].length > 0) {
                if (this.$refs[column.field + rowIndex][0].$refs['input']) {
                  this.$refs[column.field + rowIndex][0].$refs['input'].$el.click()
                  this.$refs[column.field + rowIndex][0].$refs['input'].focus()
                }
                if (this.$refs[column.field + rowIndex][0].$refs['table']) {
                  this.$refs[column.field + rowIndex][0].$refs['table'].focus()
                }
              }
              break;
          }
        }
      }, 200)
    },
    /**
     * @desc   : desc
     * @author : 周兴
     * @date   : 2022/6/16 10:45
     */
    calcColumns(rowIndex) {
      this.columns.forEach(it => {
        //数值
        if (it.type === 'number' || it.number) {
          this.calc(it.field, rowIndex,true)               //计算
        }
      })
    },
    /**
     * @desc   : 计算
     * @author : 周兴
     * @date   : 2022/4/6 13:59
     */
    calc(field, rowIndex,formulaLateFlag) {
      // console.log('e', e)
      //获取当前列的名
      let currentColumn = this.columns.filter(col => col.field === field);
      if (!currentColumn) return;
      let formula = currentColumn[0].formula;
      //如果没有公式就推出
      if (!formula || !Object.keys(formula)) {
        return;
      }
      let row = this.tableData[rowIndex]
      let keys = Object.keys(formula)
      for (let i in keys) {
        if (formulaLateFlag && currentColumn[0].formulaLate) {
          continue
        }
        // 按照公式进行计算
        this.calcItem(formula, keys[i], row, field, rowIndex)
      }
    },
    /**
     * @desc   : 计算明细
     * @author : 周兴
     * @date   : 2022/6/16 10:34
     */
    calcItem(formula, key, row, field, rowIndex) {
      //获取需要计算的列
      let countColumn = this.columns.filter(col => col.field === key)
      if (!countColumn) return
      let values = formula[key]
      if (values && values.length > 0) {
        let formu = values[0]
        for (let i = 1; i < values.length; i++) {
          if (row[values[i]]) {
            formu = formu.replace(values[i], row[values[i]])
          } else {
            // 如果不是非标，面积要进行替换为1
            if (values[i] == 'nonStandardArea') {
              formu = formu.replace('nonStandardArea', 1)
            } else {
              formu = formu.replace(values[i], 0)
            }
            // formu = formu.replace(values[i], 0);
          }
        }
        try {
          // 获取小数位数
          let digits = 0
          if (countColumn[0].digits) {
            digits = countColumn[0].digits
          }
          //用eval进行计算
          let tValue = eval(formu)
          //说明除数为0，那么金额清空
          if ('Infinity' == tValue || '-Infinity' == tValue || isNaN(tValue)) {
            // row[field] = null;
            this.$set(row, key, 0)
          } else {
            //对计算出来的数据进行处理
            this.$set(row, key, XEUtils.toFixed(XEUtils.round(tValue, digits), digits))
          }
        } catch (err) {
          this.$set(row, key, 0)
          // row[key] = 0
        }
      }
    },
    /**
     * @desc   : 表格向下{{ $t('filling') }}
     * @author : 沈博
     * @date   : 2022/3/13 9:56
     */
    inputDown(column) {
      let field = column.field
      //获取当前列的名
      let currentColumn = this.columns.filter(col => col.field === field);
      if (!currentColumn) return;
      //console.log('d',currentColumn,column.type)
      // 数值
      if (column.type === 'number') {
        let formula = currentColumn[0].formula;
        //如果没有公式就推出
        if (formula && Object.keys(formula)) {
          let key = Object.keys(formula)[0];
          //获取需要计算的列
          let countColumn = this.columns.filter(col => col.field === key);
          if (countColumn) {
            let values = formula[key];
            if (values && values.length > 0) {
              let formu = values[0];
              //给你当前单元格赋值
              this.tableData.forEach(it => {
                // 如果有controlId，那么只能赋值有值的行
                if (this.controlId && it[this.controlId]) {
                  formu = values[0];
                  for (let i = 1; i < values.length; i++) {
                    if (it[values[i]]) {
                      formu = formu.replace(values[i], it[values[i]]);
                    } else {
                      formu = formu.replace(values[i], 0);
                    }
                  }
                  try {
                    //用eval进行计算
                    let tValue = eval(formu)
                    //说明除数为0，那么金额清空
                    if ('Infinity' == tValue) {
                      this.$set(it, field, null)
                    } else {
                      // 获取小数位数
                      let digits = 0;
                      if (countColumn[0].digits) {
                        digits = countColumn[0].digits
                      } else {
                        //如果没有设置小数位数，那么就读取商品中的计量单位
                        if (it.decimalPlaces) {
                          digits = it.decimalPlaces;
                        }
                      }
                      //对计算出来的数据进行处理
                      this.$set(it, key, XEUtils.toFixed(XEUtils.round(tValue, digits), digits))
                    }
                  } catch (err) {
                    this.$set(it, key, 0)
                  }
                }
              })
            }
          }
        } else {
          //给你当前单元格赋值
          // 获取小数位数
          let digits = 0;
          if (currentColumn[0].digits) {
            digits = currentColumn[0].digits
          }
          this.tableData.forEach(it => {
            // 如果有controlId，那么只能赋值有值的行
            if ((this.controlId && it[this.controlId]) || !this.controlId) {
              //如果没有设置小数位数，那么就读取商品中的计量单位
              if (digits === 0) {
                digits = it.decimalPlaces;
              }
              this.$set(it, field, XEUtils.toFixed(XEUtils.round(this.inputDownValue, digits), digits))
            }
          })
        }
      } else if (column.type === 'text') {
        //文本
        this.tableData.forEach(it => {
          // 如果有controlId，那么只能赋值有值的行
          if ((this.controlId && it[this.controlId]) || !this.controlId) {
            this.$set(it, field, this.inputDownValue);
          }
        })
      } else if (column.type === 'switch') {
        this.tableData.forEach(it => {
          // 如果有controlId，那么只能赋值有值的行
          if ((this.controlId && it[this.controlId]) || !this.controlId) {
            this.$set(it, field, this.inputDownBooleanValue);
          }
        })
      } else if (column.type === 'select') {
        this.tableData.forEach(it => {
          // 如果有controlId，那么只能赋值有值的行
          if ((this.controlId && it[this.controlId]) || !this.controlId) {
            this.$set(it, field, this.inputDownValue);
            let list = typeof column.options === 'function' ? column.options() : column.options
            this.$set(it, field + '_Name', list.filter(it => it[column.valueKey] === this.inputDownValue)[0][column.labelKey]);
          }
        })
      } else if (column.type === 'tableSelect') {
        if (currentColumn && currentColumn.length > 0) {
          let col = currentColumn[0]
          let row = col[col.field + '_copy']
          this.tableData.forEach(it => {
            col.fieldUpdate.forEach(it2 => {
              if (it[this.controlId] || it.controlId !== this.controlId) {
                this.$set(it, it2.updateField, row[it2.valueFiled])
              }
            })
          })
        }
      }
      this.$refs['down-input-icon'][0].$el.click()
    }
    ,
    /**
     * @desc   : 新增一行
     * @author : 周兴
     * @date   : 2022/4/7 14:36
     */
    add(rowIndex) {
      let obj = {};
      this.columnsData.forEach(it => {
        //开关时，默认是true,如果要是false需要在列中给其传值
        if (it.type === 'switch') {
          this.$set(obj, it.field, it.value === undefined || it.value === null ? true : it.value);
          if (this.defaultField && it.field == this.defaultField) {
            this.$set(obj, it.field, false);
          }
        } else {
          // 如果是显示顺序需要自增
          if (it.field === 'displayNo') {
            let arr = this.tableData.map(m => m[it.field]);
            let cMax = Math.max.apply(null, arr);
            if (cMax && cMax != '-Infinity') {
              this.$set(obj, it.field, cMax + 1);
            } else {
              this.$set(obj, it.field, 1);
            }
          } else {
            //读取列的默认值，如果有设置，那么需要设置上
            if (it.value && it.value != null) {
              if (it.type === 'select') {
                setTimeout(() => {
                  let options = it.options();
                  let filters = options.filter(item => item[it.valueKey] === it.value);
                  if (filters && filters.length > 0) {
                    this.$set(obj, it.field, it.value);
                    this.$set(obj, it.field + '_Name', filters[0][it.labelKey]);
                  }
                }, rowIndex ? 0 : 300)
              } else {
                this.$set(obj, it.field, it.value);
              }
            } else {
              this.$set(obj, it.field, null);
            }
          }
        }
      })
      //说明是手动新增的
      let curorRowIndex = 0;
      if (rowIndex || rowIndex === 0) {
        this.tableData.splice(rowIndex + 1, 0, obj)
        curorRowIndex = rowIndex + 1;
      } else {
        this.tableData.push(obj)
        curorRowIndex = 0;
      }
      //设置光标位置
      if (this.focusFlag) {
        this.$nextTick(() => {
          for (let j in this.columnsData) {
            if (this.columnsData[j].type !== 'disabled' && this.columnsData[j].type !== 'switch' &&
              (!this.tableData[curorRowIndex].readOnly || this.tableData[curorRowIndex].readOnly.indexOf(this.columnsData[j].field) < 0)) {
              this.$refs[this.name].setActiveCell(this.tableData[curorRowIndex], this.columnsData[j].field);
              // console.log('ttt',this.focusFlag,)
              this.handleFocus(this.columnsData[j], curorRowIndex);
              break;
            }
          }
        })
      }
      this.$emit('addRow', rowIndex)
    },
    /**
     * @desc   : 删除一行
     * @author : 周兴
     * @date   : 2022/4/11 9:13
     */
    del(rowIndex) {
      // console.log('del',rowIndex)
      let row = {...this.tableData[rowIndex]}
      // 记录删除的数据
      if (this.majorField && row[this.majorField]) {
        this.deleteData.push(row);
      }
      this.tableData = [...this.tableData.filter((it, index) => {
        return index !== rowIndex
      })]
      //如果删完了，那么就要新增新行
      if (this.operateFlag && this.newRowFlag && (!this.tableData || this.tableData.length === 0)) {
        this.add(0);
      }
      this.$refs[this.name].reloadData(this.tableData)
      this.$emit('delRow', row, rowIndex)
      this.setDefaultFlag(row, true);
    },
    /**
     * @desc   : TableSelect输入框离开焦点事件
     * @author : 周兴
     * @date   : 2022/5/26 16:40
     */
    handleSelectInputBlur(e, row, rowIndex, colItem, colIndex) {
      // 把值恢复回去
      if (this.$refs[colItem.field + rowIndex] && row[colItem.field]) {
        this.$refs[colItem.field + rowIndex][0].$refs.input.$refs.input.value = row[colItem.field];
      }
    },
    /**
     * @desc   : 清空选择
     * @author : 周兴
     * @date   : 2022/9/23 17:39
     */
    clearSelect(e) {
      if (this.tableData && this.tableData[e.rowIndex] && this.tableData[e.rowIndex][e.column.field]) {
        this.tableData[e.rowIndex][e.column.field] = null;
        this.tableData[e.rowIndex][e.column.field + '_Name'] = null;
      }
      this.$emit('clear-select', e)
    },
    /**
     * @desc   : desc
     * @author : 周兴
     * @date   : 2022/4/10 14:22
     */
    inputChange(row, rowIndex, colItem, val) {
      // 更新需要更新的列
      this.columns.forEach((it, index) => {
        //如果这里是controlId
        if (this.controlId) {
          if (colItem.type === 'tableSelect') {
            if (colItem.controlId && it.field == colItem.field && this.controlId === colItem.controlId) {
              this.tableData[rowIndex][it.field] = null;
            }
          }
        } else {
          //说明这列受管控
          if (it.controlIds && it.controlIds.length > 0 && it.controlIds.includes(colItem.field)) {
            this.tableData[rowIndex][it.field] = null;
            if (this.tableData[rowIndex][it.field + '_Name']) {
              this.tableData[rowIndex][it.field + '_Name'] = null;
            }
          }
        }
      })
      this.$emit('changeValue', colItem.field, row, rowIndex, val);
    },
    /**
     * @desc   : 批量选择数据
     * @author : 周兴
     * @date   : 2022/5/26 16:54
     */
    onBatchChoose(e, column, rowIndex, colIndex, fieldUpdate, colItem) {
      // 单选
      if (colItem.multiple !== undefined && !colItem.multiple) {
        this.onChoose(e.batchRows[0], e.batchRows[0], column, rowIndex, colIndex, fieldUpdate, colItem)
      } else {
        // 多选
        let {batchRows, batchKeys} = e;
        if (batchRows && batchRows.length > 0) {
          let deleteCurrentFlag = false;
          let index = 0;

          for (let i = 0; i < batchRows.length; i++) {
            // 只有控制主键的列才会这么操作
            if (colItem.controlId) {
              // 判断是否重复
              this.checkRepeat(batchRows[i], batchRows[i], rowIndex, colItem, false).then(isRepeat => {
                // 如果重复就不进行后续
                if (isRepeat) {
                  //只要重复就不允许删除当前行了
                  deleteCurrentFlag = true;
                  // index = index + 1;
                } else {
                  // 如果第一行是新行，那么就要把deleteCurrentFlag设置为true,不然第二行就要删除掉之前的数据
                  if (i === 0 && this.controlId && !this.tableData[rowIndex][this.controlId]) {
                    deleteCurrentFlag = true;
                  }
                  //如果当前行有值，先删除当前行 (当前行只能删除一次)
                  if (!deleteCurrentFlag && this.controlId && this.tableData[rowIndex][this.controlId]) {
                    // 记录删除的数据
                    if (this.majorField && colItem.field == this.majorField && this.tableData[rowIndex][this.majorField]) {
                      this.deleteData.push(this.tableData[rowIndex]);
                    }
                    //删除当前数据
                    this.tableData = this.tableData.filter((it, cIndex) => {
                      return cIndex !== rowIndex
                    })
                    deleteCurrentFlag = true;
                  }
                  //新增行(判断行是否是新行，新行要新增
                  this.addNewRow(rowIndex + index);
                  // 设置需要更新的数据
                  this.setTableData(batchRows[i], batchRows[i], rowIndex + index, colItem, fieldUpdate);
                  // 计算公式
                  this.calcColumns(rowIndex + index)
                  index = index + 1;
                }
              });
            }
          }
          if (this.autoNextFlag) {
            // 跳转到第一行的可输入单元格
            this.nextInputCell(batchRows[0], rowIndex, colIndex, colItem.field, colItem);
          }
          this.$emit('onBatchChoose', batchRows, rowIndex)
          this.$emit('chooseData', batchRows, rowIndex, colItem)
        }
      }
    },
    /**
     * @desc   : 批量赋值
     * @author : 周兴
     * @date   : 2022/11/15 13:04
     */
    onBatchChooseCopy(e, colItem, type) {
      let row = type === 'batch' ? e.batchRows[0] : e
      // this.tableData.forEach(it => {
      //   colItem.fieldUpdate.forEach(it2 => {
      //     if (it[this.controlId] || it.controlId !== this.controlId) {
      //       this.$set(it, it2.updateField, row[it2.valueFiled])
      //     }
      //   })
      // })
      this.$set(colItem, colItem.field + '_copy', row)
      this.inputDownValue = row[colItem.selectField] ? row[colItem.selectField] : null;
    },
    /**
     * @desc   : 增加新行（【批量选择数据后增加】）
     * @author : 周兴
     * @date   : 2022/5/27 9:13
     */
    addNewRow(rowIndex) {
      // console.log('ttt',rowIndex)
      if (!this.tableData[rowIndex]) {
        this.add(rowIndex);
      } else {
        // 如果多行增加时，这行有值，需要增加
        if (this.controlId && this.tableData[rowIndex][this.controlId]) {
          this.add(rowIndex);
        }
      }
    },
    /**
     * @desc   : 选择数据
     * @author : 周兴
     * @date   : 2022/4/7 16:02
     */
    onChoose(e, row, column, rowIndex, columnIndex, fieldUpdate, colItem) {
      this.chooseData(e, row, column, rowIndex, columnIndex, fieldUpdate, colItem, true);
      setTimeout(() => {
        if (this.autoNextFlag) {
          this.$refs[this.name].clearActived()
          // 跳转到下一个可输入单元格
          this.nextInputCell(row, rowIndex, columnIndex, colItem.field, colItem);
        }
      }, 300)
    },
    /**
     * @desc   : 设置默认标识
     * @author : 周兴
     * @date   : 2022/8/5 9:28
     */
    setDefaultFlag(row, deleteFlag) {
      if (this.defaultField && row) {
        // 删除
        if (deleteFlag) {
          // 如果删除的是默认行，那么需要指定第一行为默认
          if (row[this.defaultField] && this.tableData && this.tableData.length > 0) {
            this.$set(this.tableData[0], this.defaultField, true);
          }
        } else {
          // 判断是否有标识已经勾选上了
          let filterRows = this.tableData.filter(it => it[this.defaultField]);
          if (!filterRows || filterRows.length == 0) {
            this.$set(row, this.defaultField, true);
          } else {
            this.$set(row, this.defaultField, false);
          }
        }
      }
    },
    /**
     * @desc   : 选择数据（私有方法）
     * @author : 周兴
     * @date   : 2022/5/26 16:39
     */
    chooseData(e, row, column, rowIndex, columnIndex, fieldUpdate, colItem, showMessage) {
      let eRow = e == null ? row : e;
      // 判断是否重复
      this.checkRepeat(eRow, row, rowIndex, colItem, showMessage).then(res => {
        if (res) {
          return;
        }
        //记录删除的行
        if (this.majorField && colItem.field == this.majorField && row[this.majorField]) {
          this.deleteData.push(row);
        }
        // 设置需要更新的数据
        this.setTableData(eRow, row, rowIndex, colItem, fieldUpdate);
        // 计算公式
        this.calcColumns(rowIndex)
        this.$emit('chooseData', row, rowIndex, colItem)
      });
    },
    /**
     * @desc   : 如果最后一行不为空，需要增加一个空行
     * @author : 周兴
     * @date   : 2023/10/26 11:28
     */
    addTableNewRow() {
      if (this.newRowFlag && this.tableData) {
        if (this.tableData.length > 0) {
          if (this.tableData[this.tableData.length - 1][this.controlId]) {
            this.add(this.tableData.length)
          }
        } else {
          this.add(0)
        }
      }
    },
    /**
     * @desc   : 设置需要更新的数据
     * @author : 周兴
     * @date   : 2022/5/27 8:48
     */
    setTableData(eRow, row, rowIndex, colItem, fieldUpdate) {
      //说明是下拉，需要赋值
      if (colItem.valueKey) {
        //先把labelKey赋值给field,方便显示
        if (eRow[colItem.valueKey]) {
          this.$set(this.tableData[rowIndex], colItem.field, eRow[colItem.valueKey].toString())
          this.$set(this.tableData[rowIndex], colItem.field + '_Name', eRow[colItem.labelKey])
          // this.tableData[rowIndex][colItem.field] = eRow[colItem.valueKey].toString();
          // this.tableData[rowIndex][colItem.field + '_Name'] = eRow[colItem.labelKey];
        }
      } else {
        // 更新需要更新的列
        if (fieldUpdate) {
          fieldUpdate.forEach(it => {
            this.$set(this.tableData[rowIndex], it.updateField, eRow[it.valueFiled])
            // 如果这个数值没有，并且有默认值，那么就赋值上默认值
            if (!eRow[it.valueFiled] && it.defaultValue) {
              this.tableData[rowIndex][it.updateField] = it.defaultValue
            }
            // this.tableData[rowIndex][it.updateField] = eRow[it.valueFiled]
          })
        }
        // 设置默认值
        this.setDefaultFlag(this.tableData[rowIndex]);
      }
      // 给id赋值
      // this.tableData[rowIndex]['id'] = eRow['id']
      //把改变的行加入到tableDataChange中
      let rows = this.tableDataChange.filter(it => it['_X_ID'] === row['_X_ID']);
      //说明已经存在
      if (rows && rows.length > 0) {
        this.tableDataChange = this.tableDataChange.filter(it => it['_X_ID'] !== row['_X_ID']).map(it => it);
      }
      this.tableDataChange.push(row);
    },
    /**
     * @desc   : 判断是否重复
     * @author : 周兴
     * @date   : 2022/5/27 8:46
     */
    checkRepeat(eRow, row, rowIndex, colItem, showMessage) {
      return new Promise(resolve => {
        //如果需要进行唯一性判断
        if (!this.enabledRepeat && this.enabledRepeatId) {
          //不是数组
          if (!Array.isArray(this.enabledRepeatId)) {
            //判断是否有重复的数据
            let tmpRows = this.tableData.filter(it => it[this.controlId] == eRow[this.enabledRepeatId]);
            // console.log('3343', this.enabledRepeat, this.tableData, this.enabledRepeatId, eRow,tmpRows)
            if (tmpRows && tmpRows.length > 0) {
              //判断是否是同一行的
              if (row['_X_ID'] != tmpRows[0]['_X_ID']) {
                //提示信息重复
                if (showMessage) {
                  this.$Message.warning(vm.$t('W_018'))
                }
                resolve(true);
              }
            }
          } else {
            let data = [...this.tableData];
            let currentRow = data[rowIndex];
            for (let col = 0; col < this.enabledRepeatId.length; col++) {
              // for (let col in this.enabledRepeatId) {
              data = this.filterData(data, eRow, this.enabledRepeatId[col], currentRow, colItem);
              // 说明没有重复
              if (!data || data.length === 0) {
                break;
              }
            }
            if (data && data.length > 0) {
              //提示信息重复
              if (showMessage) {
                this.$Message.warning(vm.$t('W_018'))
              }
              resolve(true);
            }
          }
        }
        resolve(false);
      })
    },
    /**
     * @desc   : 过滤数据
     * @author : 周兴
     * @date   : 2022/5/13 16:27
     */
    filterData(data, eRow, col, currentRow, column) {
      //说明是当前列，当前列从下拉中取值
      if (column.field === col) {
        if (column.valueKey) {
          return data.filter(it => it[col] == eRow[column.valueKey]);
        }
      } else {
        if (currentRow && currentRow[col]) {
          return data.filter(it => it[col] == currentRow[col] && it['_X_ID'] != currentRow['_X_ID']);
        }
      }
      return null;
    },
    /**
     * @desc   : 校验数据
     * @author : 周兴
     * @date   : 2022/4/7 16:02
     */
    validCheck() {
      return new Promise((resolve, reject) => {
        const $table = this.$refs[this.name]
        $table.fullValidate(true).then(() => {
          resolve(true)
        }).catch(errMap => {
          resolve(false)
        })
      })
    },
    /**
     * @desc   : 日期格式
     * @author : 周兴
     * @date   : 2022/4/24 17:13
     */
    dateFormat(val) {
      if (!val) {
        return ''
      }
      return val.format('yyyy-MM-dd')
    },
    /**
     * @desc   : 时间格式
     * @author : 洪旭东
     * @date   : 2023-12-21 13:42
     */
    dateTimeFormat(val) {
      if (!val) {
        return ''
      }
      return val.format()
    },
    /**
     * @desc   : 单元格编辑结束后，光标停留在对应的位置
     * @author : 周兴
     * @date   : 2022/4/10 14:02
     */
    editMethod(e) {
    },
    /**
     * @desc   : 滚动就隐藏pop
     * @author : 周兴
     * @date   : 2022/4/19 9:21
     */
    handleScroll(e) {
      if (!this.isScroll) {
        if (e.isY) {
          //模拟点击表格
          e.$event.target.click()
          // this.$refs[this.name].clearActived(); //关闭行激活状态
        }
        this.$refs[this.name].$el.click(); //关闭表头的pop
      }
    },
    /**
     * @desc   : 移动行
     * @author : 周兴
     * @date   : 2022/12/15 16:28
     */
    rowDrop() {
      this.$nextTick(() => {
        let xTable = this.$refs[this.name];
        this.sortable = Sortable.create(
          xTable.$el.querySelector(".body--wrapper>.vxe-table--body tbody"),
          {
            handle: ".row_drop_class",
            animation: 150,
            onEnd: ({newIndex, oldIndex}) => {
              let tableData = this.tableData.copy();
              tableData.splice(newIndex, 0, tableData.splice(oldIndex, 1)[0]);
              let newArray = tableData.slice(0);
              this.tableData = [];
              this.$nextTick(function () {
                this.tableData = newArray;
              });
            },
          }
        );
      });
    },
    /**
     * @desc   : 表格设置
     * @author : 周兴
     * @date   : 2022/12/1 15:11
     */
    showSetting(e) {
      const tableColumns = this.$refs[this.name].getTableColumn()
      if (tableColumns) {
        let columns = tableColumns.fullColumn
        columns = columns.filter(it => it.type != 'seq' && it.type != 'blank' && it.type != 'info')
        this.$TableFilter({tableData: columns},
          {
            ok: (val, userTableSetting) => {
              // this.unFreeze();
              // 去掉选择的标题
              let filterRows = val.filter(it => it.type == 'checkbox' || it.type == 'radio');
              if (filterRows && filterRows.length > 0) {
                filterRows.forEach(it => {
                  it.title = '';
                })
              }
              // 加入序号
              val.splice(0, 0, tableColumns.fullColumn[0])
              // 加入校验信息
              val.splice(1, 0, tableColumns.fullColumn[1])
              // 加入blank
              val.push(tableColumns.fullColumn[tableColumns.fullColumn.length - 1])
              // 加载列
              this.$refs[this.name].loadColumn(val);
              // 用户隐藏列
              if (userTableSetting) {
                this.setUserTableSettingAfter(userTableSetting);
              }
            },
          })
      }
    },
    /**
     * @desc   : 根据requiredColumn进行validRules设置
     * @author : 周兴
     * @date   : 2022/4/25 15:13
     */
    setRequiredColumn() {
      if (this.requiredColumn && this.requiredColumn.length > 0) {
        let validRules = {}
        this.requiredColumn.forEach(col => {
          let tempCol = this.columns.filter(it => it.field === col);
          if (tempCol && tempCol.length > 0) {
            tempCol[0].required = true;
          }
          // if (tempCol) {
          //   validRules[col] = [{
          //     required: true,
          //     // message: vm.$t('inputWords', {'search-name': tempCol[0].title ? tempCol[0].title : vm.$t(tempCol[0].field)})
          //   }]
          // }
        })
        // this.validRules = validRules;
      }
    },
    /**
     * @desc   : 刷新表的列
     * @author : 周兴
     * @date   : 2023/3/17 14:41
     */
    refreshTableColumns(columns) {
      this.columnsData = []
      //如果列中没有序号要加上
      let filterColumns = columns.filter(it => it.field === 'seq');
      if (!filterColumns || filterColumns.length === 0) {
        columns.splice(0, 0, {type: 'seq', field: 'seq', fixed: 'left'})
        if (this.errorInfoFlag) {
          columns.splice(1, 0, {type: 'info', field: 'info', fixed: 'left', width: '15'})
        }
        columns.splice(0, 0, {type: 'blank', field: 'blank', width: '1'})
      }
      this.columnsData = columns;
    },
    /**
     * @desc   : 初始化列
     * @author : 周兴
     * @date   : 2022/6/11 10:42
     */
    initColumn() {
      let columns = [...this.columns]
      //如果列中没有序号要加上
      let filterColumns = columns.filter(it => it.field === 'seq');
      if (!filterColumns || filterColumns.length === 0) {
        columns.splice(0, 0, {type: 'seq', field: 'seq', fixed: 'left'})
        if (this.errorInfoFlag) {
          columns.splice(1, 0, {type: 'info', field: 'info', fixed: 'left', width: '15'})
        }
        columns.splice(0, 0, {type: 'blank', field: 'blank', width: '1'})
      }
      this.columnsData = columns;
    },
    /**
     * @desc   : 固定列
     * @author : 周兴
     * @date   : 2022/6/8 20:29
     */
    toggleFixedColumn() {
      const xTable = this.$refs[this.name]
      if (!xTable) return;
      const tableColumns = xTable.getTableColumn()
      if (tableColumns && tableColumns.visibleColumn
        && tableColumns.visibleColumn.length > 0) {
        let refreshFlag = false;
        for (let i in this.columnsData) {
          // 查看是否有列设置了固定
          if (this.columnsData[i].fixed) {
            let col = tableColumns.visibleColumn.filter(it => it.property === this.columnsData[i].field)
            if (col && col.length > 0) {
              col[0].fixed = this.columnsData[i].fixed;
              refreshFlag = true;
            }
          }
        }
        if (refreshFlag) {
          // 刷新列
          xTable.refreshColumn();
        }
      }
    },
    /**
     * @desc   : 改变设置的位置
     * @author : 周兴
     * @date   : 2023/1/29 16:55
     */
    changeSettingLocation() {
      let self = this;
      this.$nextTick(() => {
        setTimeout(() => {
          self.settingLeft = self.$refs[self.name] ? (self.$refs[self.name].$el.offsetWidth + self.$refs[self.name].$el.offsetLeft - 26) + 'px' : 0// 设置图标居左的位置
          self.settingTop = self.$refs[self.name] ? (self.$refs[self.name].$el.offsetTop + 1) + 'px' : 0;           // 设置图标居上的位置
        }, 700)
      })
    },
  },
  mounted() {
    let self = this;
    setTimeout(() => {
      self.toggleFixedColumn();  // 冻结列
    }, 300)
    if (self.rowDropFlag) {
      self.rowDrop();  //行移动
    }
    //监听窗口变化
    window.addEventListener('resize', self.changeSettingLocation)
    self.handleSelectData()
    self.changeSettingLocation();
  },
  beforeDestroy() {
    if (this.sortable) {
      this.sortable.destroy();
    }
    this.sortable = null;
    window.removeEventListener('resize', this.changeSettingLocation)
    this.existsFlag = null
  },
  created() {
    // 初始化列
    this.initColumn();
    this.tableData = this.data;
    //设置新行
    if (!this.data || this.data.length === 0 || this.newRowAlwaysFlag) {
      this.tableData = []
      this.tableDataChange = []
      if (this.newRowFlag) {
        //新建时增加行
        this.add()
      }
      // 聚焦到第一行
      if (this.autoFocus) {
        setTimeout(() => {
          this.$refs[this.name]?.setActiveRow(this.tableData[0])
        }, 300)
      }
    }
    // 根据列表是否只读，判断是否开启编辑模式
    if (this.readonly) {
      this.enabledEdit = false;
    }
    // 设置必须输入项
    this.setRequiredColumn();
    this.freezeData = this.freeze;
  }
}
</script>

<style scoped>
/deep/ .vxe-cell {
  display: flex;
  align-items: center;
  padding-left: 0 !important;
  padding-right: 0 !important;
}


/deep/ .vxe-cell--label {
  padding-left: 10px !important;
  padding-right: 10px !important;
}

.edit-div-class {
  padding-left: 10px !important;
  padding-right: 10px !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}


/deep/ .vxe-footer--row .vxe-cell {
  /*justify-content: left !important;*/
  display: block;
  padding-left: 10px !important;
  padding-right: 10px !important;
}

/deep/ .vxe-input {
  width: 100%;
  border: 1px solid #dcdee2;
  border-radius: 2px;
}

/deep/ .vxe-input :hover {
  /*border: 1px solid #57a3f3 !important;*/
  /*border-radius: 2px;*/
}

/deep/ .vxe-input > input:focus {
  /*border-color: #57a3f3 !important;*/
  /*border-radius: 2px;*/
  /*-webkit-box-shadow: 0 0 0 1px rgba(45, 140, 240, .2) !important;*/
  box-shadow: 0 0 0 2px rgba(45, 140, 240, 0.2);
}

/deep/ .col--valid-error .vxe-input > input {
  border-color: red !important;
}


/deep/ .vxe-cell--title {
  line-height: 0;
}


/*
 * @desc   : TODO 不好使
 * @author : 周兴
 * @date   : 2022/4/5 16:35
 */
.number-class .vxe-cell {
  justify-content: right !important;
}

/deep/ .vxe-input--number-prev-icon {
  display: none;
}

/deep/ .vxe-input--number-next-icon {
  display: none;
}

/deep/ .vxe-input .vxe-input--extra-suffix {
  display: none;
}

.setting-class {
  position: absolute;
  z-index: 300;
  width: 25px;
  height: 28px;
  background:  rgba(245, 250, 255, 1);
  justify-content: center;
  display: flex;
  align-items: center;
  cursor: pointer;
}

.freeze-class {
  margin-top: 4px;
  margin-left: 5px;
  cursor: pointer;
  font-size: 14px;
  color: #c0c4cc;
}

.freezed-class {
  margin-top: 4px;
  margin-left: 5px;
  cursor: pointer;
  font-size: 14px;
}


.edit-button {
  border-color: #57a3f3 !important;
  display: flex;
  justify-content: center;
  align-items: center;
}

.btn-class {
  display: flex;
  justify-content: center;
  align-items: center;
}


.switch-class {
  height: calc(100% - 3px) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

.checkbox-class {
  height: 100% !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

.checkbox-class label {
  margin-bottom: 0 !important;
}

/deep/ .close-div-class .ivu-input-group {
  top: 3px !important
}

/deep/ .required-class .vxe-cell--edit-icon {
  color: red !important;
}

/deep/ .vxe-cell--edit-icon {
  margin-top: 1px !important;
}

.text-button-class {
  margin-left: 0 !important;
  width: 108px !important;
  background-color: #17a2b8 !important;
  color: white !important;
  text-align: center;
}

.vxe-table--render-default .vxe-body--row.row--current .vxe-body--column .vxe-cell .text-button-class {
  background-color: #17a2b8 !important;
  color: white !important;
}

.vxe-table--render-default .vxe-body--row.row--checked, .vxe-table--render-default .vxe-body--row.row--radio .vxe-body--column .vxe-cell .text-button-class {
  background-color: #17a2b8 !important;
  color: white !important;
}



/*table-header（无内容部分）背景色*/
/deep/ .vxe-table--render-default.border--full .vxe-table--header-wrapper{
  background: rgba(245, 250, 255, 1);
}
/*合计行（无内容部分）背景色*/
/deep/ .vxe-table--render-default .vxe-table--footer-wrapper{
  background: rgba(255 , 248, 225, 1);
  border: unset;
}


/*滚动条样式*/
.dk-table-scrollbar ::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
/*滚动条的轨道*/
.dk-table-scrollbar ::-webkit-scrollbar-track {
  /*background-color:  rgba(233, 240, 254, 1);*/
  background-color:  #FFFFFF;
  border: unset;
}
/*滚动条里面的小方块，能向上向下移动*/
.dk-table-scrollbar ::-webkit-scrollbar-thumb {
  background-color: #bfbfbf;
  border-radius: 5px;
  border: 1px solid #F1F1F1;
  box-shadow: inset 0 0 6px rgba(0,0,0,.3);
}
.dk-table-scrollbar ::-webkit-scrollbar-thumb:hover {
  background-color: #A8A8A8;
}
.dk-table-scrollbar ::-webkit-scrollbar-thumb:active {
  background-color: #787878;
}
/*边角，即两个滚动条的交汇处*/
.dk-table-scrollbar ::-webkit-scrollbar-corner {
  background-color: #FFFFFF;
}

/*去掉table底部border*/
/deep/ .vxe-table--border-line {
  border-width: 0;
}


.non-glass-drop-down{
  width: 300px !important;
  background: #F8F8FF;
  padding: 20px 0 20px 30px;
}

/deep/.close-div-class .ivu-input-group{
  top:0 !important;
}

</style>
