<!--
 * @Descripttion: 
 * @version: 
 * @Author: congsir
 * @Date: 2022-08-05 09:44:49
 * @LastEditors: fakerwu fakerwu@msi.com
 * @LastEditTime: 2023-11-24 10:49:49
-->
<template>
  <div class="table_outer" :class="{ is_full_screen: ifFullScreen }" v-loading="loading">
    <div class="table_top" v-if="(!allHide || isSort || showSearch) && !loading">
      <div class="btn_list">
        <template v-if="showBaseBtn">
          <el-button type="primary" icon="el-icon-search" @click="handleToDealWidthSearchBar('search')" :loading="loading">查询</el-button>
          <el-button type="primary" icon="el-icon-refresh-left" @click="handleToDealWidthSearchBar('reset')">重置</el-button>
        </template>
        <slot name="lineBtns"></slot>
        <template v-for="item in lineBtns">
          <el-button
            v-if="!item.slot && showBtn(item.checkKey)"
            :type="getTypeByButtonText(item.checkKey, item)"
            :icon="getIconByButtonText(item.checkKey, item)"
            v-bind="item.checkKey && item.checkKey()"
            :key="item.text"
            @click="item.event()"
          >
            {{ showText(item.checkKey, '', item) }}
          </el-button>
        </template>
      </div>
      <div class="table_do" :class="{ table_showSort: isSort, table_showSort_download: exportDownloadShow }" v-if="showSearch">
        <el-input placeholder="请输入内容" v-model="input3" suffix-icon="el-icon-search"></el-input>
      </div>
    </div>
    <div class="table_tips" v-if="isSelect && showTips && selectRow.length">
      <i class="el-icon-warning corlor_icon"></i>
      <span class="choose_cell">
        已选择
        <span class="choose_num">{{ selectRow.length }}</span>
        项
      </span>
      <span class="choose_total_bum" v-if="tipsInfo.unit && tipsInfo.text">
        {{ tipsInfo.text }}
        <span class="choose_result">{{ totalresult }} {{ tipsInfo.unit }}</span>
      </span>
      <el-button type="text" size="mini" @click="toggleSelection">清空</el-button>
    </div>
    <!-- 右上角按钮组 -->
    <div class="leftTopBtnWarp">
      <div class="printBox printBoxLeft" @click="printDialogVisible = true" v-if="exportPrintShow">
        <i class="el-icon-s-print" />
      </div>
      <div class="printBox printBoxLeft" @click="handleToDealWidthSearchBar('search')" v-if="showBaseBtn">
        <i class="el-icon-refresh" />
      </div>
      <div class="downloadBox" @click="openExportDownload" v-if="exportDownloadShow">
        <i class="el-icon-download" />
      </div>
      <el-popover placement="bottom-end" trigger="click" popper-class="fixedPopper" v-show="isSort">
        <div class="printBox printBoxLeft" slot="reference">
          <i class="el-icon-s-flag" />
        </div>

        <div class="show_title">固定列</div>

        <el-checkbox-group v-model="selectFixArr" @change="fixHeader">
          <el-checkbox v-for="item in fixedCol" :key="item.prop" :label="item.prop" style="display: block">
            {{ item.label }}
          </el-checkbox>
        </el-checkbox-group>
      </el-popover>

      <div class="printBox printBoxLeft" @click="fullScreen">
        <i :class="[ifFullScreen ? 'el-icon-empty-screen' : 'el-icon-full-screen']" />
      </div>
    </div>
    <el-popover placement="bottom-end" trigger="click" popper-class="settingPopper" v-show="isSort">
      <div class="settingBox" slot="reference">
        <i class="el-icon-a-s-columnsettings" />
      </div>

      <div class="show_title">展示列</div>

      <el-checkbox-group v-model="selectArr" :class="groupClassName">
        <el-checkbox v-for="item in initCol" :key="item.prop" :label="item.prop" :disabled="selectArr.length <= 3 && item.checked" style="display: block">
          {{ item.label }}
        </el-checkbox>
      </el-checkbox-group>
    </el-popover>

    <el-table
      ref="table"
      v-if="totalCount || !loading"
      :header-cell-style="{ 'background-color': '#F6F7F9' }"
      :max-height="maxTabelHeight || null"
      :class="{ noData: !!tableData.length, isImg: !!isImg, isBorder: !!border }"
      :data="tableData"
      border
      v-bind="$attrs"
      v-on="$listeners"
      :header-row-class-name="headerName"
      show-overflow-tooltip="false"
      :row-class-name="tableRowClassName"
      @selection-change="selectionChange"
      @cell-mouse-enter="showTooltip"
      @cell-mouse-leave="hiddenTooltip"
      style="max-width: 100%"
      header-cell-class-name="preset-header"
    >
      <template #empty>
        <el-empty :description="'暂无数据'" />
      </template>
      <el-table-column type="expand" v-bind="$attrs" v-if="isExpand">
        <template slot-scope="scope">
          <slot name="expand" :row="scope.row" :index="scope.$index"></slot>
        </template>
      </el-table-column>
      <el-table-column v-if="isSelect && tableData.length && tableHeader.length" :key="selectId" v-bind="$attrs" type="selection" width="50" fixed="left" />
      <el-table-column
        v-if="checkCol.length && totalCount"
        type="index"
        fixed="left"
        :label="'序号'"
        width="62"
        :index="(searchForm[customPage] - 1) * searchForm[customSize] + 1"
      ></el-table-column>
      <el-table-column v-if="checkCol.length && !totalCount" type="index" fixed="left" :label="'序号'" width="62"></el-table-column>
      <el-table-column
        class="table_parameter_column-drag"
        v-for="(item, index) in checkCol"
        highlight-current-row
        :key="(item.prop ? item.prop : item.slotName) + index"
        v-bind="item"
        :align="getAlign(item)"
        :header-align="getAlign(item)"
        :width="''"
        :min-width="item.width"
      >
        <template slot-scope="scope">
          <expandDom v-if="item.render" :render="item.render" :index="scope.$index" :column="item" :row="scope.row"></expandDom>
          <slot v-else-if="useSlotArr.includes(item.prop)" :name="item.prop" :row="scope.row" :index="scope.$index"></slot>
          <template v-else>{{ scope.row[item.prop] }}</template>
        </template>
      </el-table-column>
      <el-table-column v-if="btns.length && tableHeader.length > 0 && tableData.length" class="end_column" label="操作" fixed="right" :width="endWidth" min-width="60">
        <template slot-scope="scope">
          <template v-for="item in listBtns">
            <slot v-if="item.slot" :name="item.slot" :row="scope.row" :index="scope.$index"></slot>
            <el-button
              v-if="!item.slot && showBtn(item.checkKey, scope)"
              v-bind="item.checkKey && item.checkKey(scope)"
              size="mini"
              style="font-size: 14px; border: 0"
              type="text"
              :key="item.text"
              @click="item.event(scope)"
            >
              {{ showText(item.checkKey, scope, item) }}
            </el-button>
          </template>
          <el-button size="mini" class="ellipBtn" type="text" v-if="dropBtns.length">
            <el-dropdown trigger="click" placement="bottom" @command="handleCommand">
              <div class="ellipOuter">
                <div v-for="item in [1, 2, 3]" :key="item" class="ellip"></div>
              </div>
              <el-dropdown-menu slot="dropdown">
                <template v-for="(dropItem, index) in dropBtns">
                  <el-dropdown-item v-if="showBtn(dropItem.checkKey, scope)" :key="index" v-bind="dropItem.checkKey && dropItem.checkKey(scope)" :command="{ ...dropItem, scope }">
                    {{ showText(dropItem.checkKey, scope, dropItem) }}
                  </el-dropdown-item>
                </template>
              </el-dropdown-menu>
            </el-dropdown>
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <FireflyPagination
      v-if="totalCount"
      :totalCount="totalCount"
      :page-info="searchForm"
      v-bind="$attrs"
      :customPage="customPage"
      :customSize="customSize"
      :tableData="tableData"
      :pageSizes="pageSizes"
      :layout="layout"
      :background="background"
      @paginationChange="paginationChange"
    ></FireflyPagination>
    <table-tooltip :tableCellMouse="tableCellMouse" :tempDom="tempDom"></table-tooltip>
    <FireflyDialog title="导出数据" :visible.sync="downloadVisible" :show-close="false" width="660px" @close="closeExportDownload" append-to-body>
      <el-form ref="downloadForm" :model="downloadForm" label-position="top">
        <el-form-item label="文件名" prop="filename">
          <el-input v-model="downloadForm.filename"></el-input>
        </el-form-item>
        <el-form-item label="保存类型" prop="type">
          <el-select v-model="downloadForm.type" placeholder="请选择" style="width: 100%">
            <el-option key="xlsx" label="Excel 工作簿(*.xlsx)" value="xlsx" />
            <el-option disabled key="csv" label="CSV(逗号分隔)(*.csv)" value="csv" />
          </el-select>
        </el-form-item>
        <el-form-item label="标题" prop="title" v-show="downloadForm.type == 'xlsx'">
          <el-input v-model="downloadForm.title"></el-input>
        </el-form-item>
        <el-form-item label="选择数据" prop="checkData">
          <el-select v-model="downloadForm.checkData" placeholder="请选择" style="width: 100%">
            <el-option key="current" label="当前数据(当前页数据)" value="current" />
            <el-option key="selected" label="选中数据(当前页选中数据)" value="selected" />
            <el-option key="all" label="全量数据(包括分页的数据)" value="all" />
          </el-select>
        </el-form-item>
        <el-form-item label="选择字段" prop="checkField">
          <el-checkbox-group v-model="downloadForm.checkField" @change="checkDownloadFormField">
            <el-checkbox :label="item.prop" :name="item.key" v-for="(item, index) in checkCol" :key="index">{{ item.label }}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeExportDownload">取 消</el-button>
        <el-button type="primary" @click="exportDownload">确 定</el-button>
      </span>
    </FireflyDialog>

    <FireflyDialog title="打印数据" :visible.sync="printDialogVisible" :show-close="false" width="660px" @close="closePrintDialog('printForm')" append-to-body>
      <el-form ref="printForm" :model="printForm" :rules="rules" label-position="top">
        <el-form-item label="标题" prop="title">
          <el-input v-model="printForm.title" placeholder="请输入打印的标题"></el-input>
        </el-form-item>
        <el-form-item label="选择数据" prop="type">
          <el-select v-model="printForm.type" placeholder="请选择" style="width: 100%">
            <el-option :key="0" label="当前数据（当前页的数据）" :value="0" />
            <el-option :key="1" label="选中数据（当前页选中的数据）" :value="1" />
          </el-select>
        </el-form-item>

        <el-form-item label="选择字段" prop="checkField">
          <el-checkbox-group v-model="printForm.checkField">
            <el-checkbox :label="item.prop" :name="item.key" v-for="(item, index) in checkCol" :key="index">{{ item.label }}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closePrintDialog('printForm')">取 消</el-button>
        <el-button type="primary" @click="handleToPrintTable('printForm')">确 定</el-button>
      </span>
    </FireflyDialog>

    <!-- 显示要打印的表格，借用第三方组件来进行打印。 -->
    <div class="print_table_container" style="display: none">
      <vxe-table border ref="vxeTableRef" height="300" :print-config="{}" :data="tableData">
        <vxe-column type="checkbox" width="60" v-if="isSelect"></vxe-column>
        <vxe-column type="seq" width="60"></vxe-column>
        <vxe-column v-for="item in tableHeader" :key="item.prop" :field="item.prop" :title="item.label"></vxe-column>
      </vxe-table>
    </div>
  </div>
</template>

<script>
import FireflyPagination from '../../fireflyPagination/src/main.vue';
import FireflyDialog from '../../fireflyDialog/src/main.vue';
import Sortable from 'sortablejs';
import tableTooltip from './fireflyTableTooltip.vue';
import EventBus from '../../utils/EventBus';
import Vue from 'vue';
import XEUtils from 'xe-utils';
import { VXETable, Table, Export, Column } from 'vxe-table';
import zhCN from 'vxe-table/lib/locale/lang/zh-CN';
import 'vxe-table/lib/style.css';

import { buildUUID } from './uuid';

// 按需加载的方式默认是不带国际化的，自定义国际化需要自行解析占位符 '{0}'，例如：
VXETable.setup({
  i18n: (key, args) => XEUtils.toFormatString(XEUtils.get(zhCN, key), args)
});

Vue.use(Export);
// Vue.use(Table);
// Vue.use(Column);
const printStyle = `
.title {
  text-align: center;
}
.my-list-row {
  display: inline-block;
  width: 100%;
}
.my-list-col {
  float: left;
  width: 33.33%;
  height: 28px;
  line-height: 28px;
}
.my-top,
.my-bottom {
  font-size: 12px;
}
.my-top {
  margin-bottom: 5px;
}
.my-bottom {
  margin-top: 30px;
  text-align: right;
}
`;

export default {
  name: 'FireflyTable',
  props: {
    /* table数据 */
    tableData: {
      type: Array,
      default: [],
      required: true
    },
    /* 最大操作列按钮个数 */
    bigBtn: {
      type: Boolean | String,
      default: 5
    },
    /* [{text(按钮名称): ''， event(点击触发的回调函数): ((这是解构赋值获取的参数，当前列和对应的下标){row, $index}) => {}}] */
    btns: {
      type: Array,
      default: () => []
    },
    /* table上方的按钮列，[{text(按钮名称): ''， event(点击触发的回调函数): () => {}}]  */
    lineBtns: {
      type: Array,
      default: () => []
    },
    /* 是否显示选择时候出现的提示 */
    showTips: {
      type: Boolean,
      default: true
    },
    /* 是否开启表格头部下载Excel按钮 */
    exportDownloadShow: {
      type: Boolean,
      default: false
    },
    /* 是否开启表头头部打印按钮 */
    exportPrintShow: {
      type: Boolean,
      default: false
    },
    /* 需要提示的时候，需要传入需要提示的内容，和单位 */
    tipsInfo: {
      type: Object,
      default: () => {
        return {
          text: '',
          unit: ''
        };
      }
    },
    showBaseBtn: {
      type: Boolean,
      default: true
    },
    /* 是否要显示搜索框， 功能未完善 */
    showSearch: {
      type: Boolean,
      default: false
    },
    /* table的表头 */
    tableHeader: {
      type: Array,
      default: () => [],
      required: true
    },
    /* table的loading */
    loading: {
      type: Boolean,
      default: false
    },
    /* 这个要传一个动态的值，当页面被布局发生变化的时候，需要传递进来新的状态值，重新计算table高度 */
    isOpen: {
      type: Boolean
    },
    /*isOpen 为true的时候 控制是否需要固定table最大高度 true是 默认会重新计算table最高高度*/
    fixTable: {
      type: Boolean,
      default: false
    },
    /* 是否需要显示边框 */
    border: {
      type: Boolean,
      default: false
    },
    /* 搜索栏参数 */
    searchForm: {
      type: Object,
      default: () => {
        return {
          pageIndex: 1,
          pageSize: 10
        };
      }
    },
    /* table总条数 */
    totalCount: {
      type: Number,
      default: 0
    },
    /* 自定义page参数 */
    customPage: {
      type: String,
      default: 'pageIndex'
    },
    /* 自定义Size参数 */
    customSize: {
      type: String,
      default: 'pageSize'
    },
    scrollBar: {
      type: String | Number,
      default: 8
    },
    /* 开启选择列 */
    isSelect: {
      type: Boolean,
      default: false
    },
    /* 是否需要显示表格拖拉拽 */
    isSort: {
      type: Boolean,
      default: () => true
    },
    /* 是否有img */
    isImg: {
      type: Boolean,
      default: () => false
    },
    /* 表格展开 */
    isExpand: {
      type: Boolean,
      default: () => false
    },
    /* 表格最高高度 */
    maxHeight: {
      default: ''
    },
    /* 分液器页码数 */
    pageSizes: {
      type: Array,
      default() {
        return [10, 20, 50, 100];
      }
    },
    excludeHeight: {
      type: String | Number,
      default: 76
    },
    layout: {
      type: String,
      default: 'total,sizes, prev, pager, next, jumper'
    },
    background: {
      type: Boolean,
      default: false
    }
  },

  components: {
    expandDom: {
      functional: true,
      props: {
        row: Object,
        render: Function,
        index: Number,
        column: {
          type: Object,
          default: null
        }
      },
      render: (h, ctx) => {
        const params = {
          row: ctx.props.row,
          index: ctx.props.index
        };
        if (ctx.props.column) params.column = ctx.props.column;
        return ctx.props.render(h, params);
      }
    },
    FireflyPagination,
    tableTooltip,
    FireflyDialog,
    [Table.name]: Table,
    [Column.name]: Column
  },

  created() {
    this.createDiv();
  },

  mounted() {
    this.comptedPosition();
    if (this.tableHeader.length) {
      if (this.isSort) {
        this.tableHeader.forEach(item => {
          if (this.isSort) {
            this.$set(item, 'checked', true);
          }
        });
        setTimeout(() => {
          this.columnDrop();
        }, 100);
        this.lineDrop();
      }
      this.initFixedCol();
      this.initHead(this.tableHeader);
    }

    EventBus.$on('ChangeOpen', val => {
      this.comptedPosition(this.fixTable);
    });

    // 阻止默认行为
    document.body.ondrop = function (event) {
      event.preventDefault();
      event.stopPropagation();
    };
    // if (this.maxHeight) {
    //    this.maxTabelHeight = this.maxHeight
    // } else {
    //    let oTableHeight, bodyHeight
    //     oTableHeight = document.querySelector('.table_outer') && document.querySelector('.table_outer').getBoundingClientRect().top
    //     bodyHeight = document.body.offsetHeight
    //     this.maxTabelHeight = bodyHeight - oTableHeight - 100
    // }
  },

  computed: {
    selectArr: {
      get() {
        let arr = this.initCol.filter(item => item.checked);
        this.checkCol = this.isSort ? arr : this.initCol;
        return arr.map(item => item.prop);
      },
      set(val) {
        if (this.isSort) {
          this.initCol.forEach(item => {
            if (val.includes(item.prop)) {
              item.checked = true;
            } else {
              item.checked = false;
            }
          });
        }
      }
    },

    headerName() {
      return `el-header-${buildUUID(6)}`;
    },

    groupClassName() {
      return `el-popper-${buildUUID(6)}`;
    },

    allHide() {
      let slotArr = Object.keys(this.$scopedSlots);
      let someShow = this.lineBtns.some(item => {
        let hasShow;
        let hasKey = item.hasOwnProperty('hasKey');
        let itemKey = hasKey ? item.hasKey : true;
        if (item.checkKey) {
          let flang = item.checkKey().hasOwnProperty('show');
          if (flang) {
            hasShow = item.checkKey().show;
          } else {
            hasShow = true;
          }
        } else {
          hasShow = true;
        }
        return itemKey && hasShow;
      });
      return !someShow && !slotArr.includes('lineBtns');
    },
    useSlotArr() {
      return Object.keys(this.$scopedSlots);
    },
    newbtns() {
      let indexArr = [];
      this.btns.forEach((item, index) => {
        indexArr.push(index);
      });

      let hideArr = this.tableData.reduce((pre, tableItem) => {
        let arr = [];
        this.btns.forEach((btnItem, btnIndex) => {
          let keyFlang = btnItem.hasOwnProperty('hasKey');
          let obj = btnItem.checkKey ? btnItem.checkKey({ row: tableItem, $index: '' }) : {};
          let flang = obj.hasOwnProperty('show');

          if (pre.includes(btnIndex)) {
            if (keyFlang && !btnItem.hasKey) {
              arr.push(btnIndex);
            } else {
              if (flang && !obj.show) {
                arr.push(btnIndex);
              }
            }
          }
        });
        return arr;
      }, indexArr);
      return this.btns.filter((item, index) => {
        return !hideArr.includes(index);
      });
    },
    listBtns() {
      let isMaxLenth = this.newbtns.length > this.bigBtn;
      let newArr = [...this.newbtns];
      if (isMaxLenth) {
        newArr = newArr.slice(0, this.bigBtn - 1);
      }
      return newArr;
    },
    dropBtns() {
      let isMaxLenth = this.newbtns.length > this.bigBtn;
      let newArr = [...this.newbtns];
      if (isMaxLenth) {
        newArr = newArr.slice(this.bigBtn - 1);
      } else {
        newArr = [];
      }
      return newArr;
    },
    endWidth() {
      let arr = this.newbtns.map(item => item.text);
      let isMaxLenth = this.newbtns.length > this.bigBtn;
      let textWidth, endWidth, marginWidth;
      if (isMaxLenth) {
        let compuArr = arr.slice(0, this.bigBtn - 1);
        textWidth = compuArr.reduce((pre, item) => {
          return (pre += this.getTextWidth(item));
        }, 0);
        endWidth = 16;
        marginWidth = (this.bigBtn - 1) * 12;
      } else {
        textWidth = arr.reduce((pre, item) => {
          return (pre += this.getTextWidth(item));
        }, 0);
        endWidth = 0;
        marginWidth = (arr.length - 1) * 12;
      }
      return textWidth + endWidth + marginWidth + 34;
    }
  },

  beforeDestroy() {
    const oBox = document.body;
    if (this.isSort) {
      const popover = document.querySelector('.settingPopper');
      if (popover) {
        popover.parentNode.removeChild(popover);
      }
    }
    oBox.removeChild(this.tempDom);
    EventBus.$off('ChangeOpen');
  },

  data() {
    return {
      ifFullScreen: false,
      searchBarList: [],
      selectFixArr: [],
      checkCol: [],
      totalresult: 0,
      selectId: buildUUID(6),
      tempDom: null,
      downloadForm: {
        type: null, //保存类型
        filename: null, //文件名
        title: null, //保存类型
        checkData: null, //选择数据
        checkField: [], //选择字段
        pageSize: this.searchForm[this.customSize],
        totalCount: this.totalCount,
        pageIndex: this.searchForm[this.customPage]
      },
      printForm: {
        title: '',
        type: '',
        checkField: []
      },
      rules: {
        title: [{ required: true, message: '请输入打印标题', trigger: 'change' }],
        type: [{ required: true, message: '请选择打印数据方式', trigger: 'change' }],
        checkField: [{ required: true, message: '请选择打印的字段', trigger: 'change' }]
      },
      downloadVisible: false, //导出数据弹出
      printDialogVisible: false, // 打印数据弹窗
      showPrintContainer: false, // 是否显示打印表格的内容
      input3: '',
      initCol: [],
      fixedCol: [],
      maxTabelHeight: '',
      selectRow: [],
      tableCellMouse: {
        cellDom: null, // 鼠标移入的cell-dom
        hidden: null, // 是否移除单元格
        row: null // 行数据
      }
    };
  },
  watch: {
    tableData() {
      this.$emit('update:loading', false);
    },

    tableHeader(newVal, oldVal) {
      if (!oldVal.length && newVal.length) {
        if (this.isSort) {
          newVal.forEach(item => {
            item.checked = true;
          });
          setTimeout(() => {
            this.columnDrop();
          }, 100);
          this.lineDrop();
        }
      } else if (newVal.length) {
        if (this.isSort) {
          let newArr = newVal.map(item => item.prop);
          let oldArr = oldVal.map(item => item.prop);
          if (newArr.toString() === oldArr.toString()) {
            newVal.forEach(item => {
              if (this.selectArr.includes(item.prop)) {
                item.checked = true;
              } else {
                item.checked = false;
              }
            });
          } else {
            newVal.forEach(item => {
              item.checked = true;
            });
          }
        }
      }
      this.initFixedCol();
      this.initHead(newVal);
    }
  },

  methods: {
    // 全屏铺满
    fullScreen() {
      this.ifFullScreen = !this.ifFullScreen;
    },
    initFixedCol() {
      let col = this.deepCopy(this.tableHeader);
      col.forEach(item => {
        this.$set(item, 'checked', false);
      });
      this.fixedCol = col;
    },
    fixHeader(value) {
      this.initCol.forEach(item => {
        if (value.includes(item.prop)) {
          this.$set(item, 'fixed', true);
        } else {
          this.$set(item, 'fixed', false);
        }
      });
    },
    handleToDealWidthSearchBar(type) {
      const table_outer = document.getElementsByClassName('table_outer');
      for (let i = 0; i < table_outer.length; i++) {
        if (table_outer[i].contains(this.$el)) {
          this.findAppMainComponent(this, i, type);
          break;
        }
      }
    },

    findComponentsByName(component, name) {
      let result = [];
      if (component.$options.name === name) {
        result.push(component);
      }
      for (const child of component.$children) {
        const foundComponents = this.findComponentsByName(child, name);
        result = result.concat(foundComponents);
      }
      return result;
    },

    findAppMainComponent(vueInstance, i, type) {
      if (!vueInstance.$parent) {
        const searchBarList = this.findComponentsByName(vueInstance, 'FireflySearchBar');
        const table_outer = document.getElementsByClassName('table_outer');
        if (table_outer.length <= searchBarList.length) {
          searchBarList[i] && searchBarList[i][type]();
        } else {
          searchBarList[i - (table_outer.length - searchBarList.length)] && searchBarList[i - (table_outer.length - searchBarList.length)][type]();
        }
        return true;
      }
      this.findAppMainComponent(vueInstance.$parent, i, type);
    },

    checkedSearchBarNodesByComponentName(vueInstance, componentName) {
      if (!vueInstance) return false;
      const children = vueInstance.$children;
      for (let i = 0; i < children.length; i++) {
        this.checkedChildrenSearchBarNodes(children[i], componentName);
        if (children[i].$options.name == componentName) {
          this.searchBarList.push(children[i]);
        }
      }
      const parentNodes = vueInstance.$parent;
      this.checkedSearchBarNodesByComponentName(parentNodes, componentName);
    },

    checkedChildrenSearchBarNodes(children, componentName) {
      if (!children) return;
      for (let i = 0; i < children.length; i++) {
        if (children[i].$options.name == componentName) {
          this.searchBarList.push(children[i]);
        }
      }
      const nextChildren = children.$children;
      this.checkedChildrenSearchBarNodes(nextChildren);
    },

    //打开导出数据
    openExportDownload() {
      (this.downloadForm.checkField = this.checkCol.map(item => item.prop)), //默认全选
        (this.downloadVisible = true);
    },
    //关闭导出数据
    closeExportDownload() {
      this.$refs['downloadForm'].resetFields();
      this.downloadVisible = false;
    },
    //导出数据选择字段勾选
    checkDownloadFormField(data) {},
    // 导出数据
    exportDownload() {
      const data = { ...this.downloadForm, pageSize: this.searchForm[this.customSize], pageIndex: this.searchForm[this.customPage] };
      this.$emit('exportDownload', data);
    },

    // 关闭打印弹窗
    closePrintDialog(formName) {
      this.$refs[formName].resetFields();
      this.printDialogVisible = false;
    },

    // 点击确定打印
    handleToPrintTable(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          const printData = this.printForm.checkField.map(item => ({ field: item }));
          printData.unshift({ type: 'seq' });
          const $table = this.$refs.vxeTableRef;
          if ($table) {
            $table.print({
              sheetName: this.printForm.title,
              mode: this.printForm.type == 0 ? '' : 'selected',
              // 打印样式设置
              style: printStyle,
              // 打印指定列
              columns: printData,
              // 打印之前拼接自定义模板
              beforePrintMethod: ({ content }) => {
                // 打印之前，返回自定义的 html 内容
                return content;
              }
            });
          }
        } else {
          return false;
        }
      });
    },

    selectionChange(selection) {
      this.$refs.vxeTableRef && this.$refs.vxeTableRef.clearCheckboxRow();
      if (this.$refs.vxeTableRef && selection.length > 0) {
        this.$refs.vxeTableRef && this.$refs.vxeTableRef.setCheckboxRow(selection, true);
      }
      if (!selection.length) this.totalresult = 0;
      let selectRow = [];
      selection.forEach(item => {
        this.totalresult += item[this.tipsInfo.prop] * 1;
        let index = this.tableData.indexOf(item);
        selectRow.push(index);
      });
      this.selectRow = selectRow;
    },
    getAlign(item) {
      let align = 'left';
      let { prop } = item;
      if (item.align) {
        align = item.align;
      } else {
        align = this.$attrs.hasOwnProperty(prop + 'Align') ? this.$attrs[prop + 'Align'] : 'left';
      }
      return align;
    },
    comptedPosition(fixTable) {
      let oTableHeight, bodyHeight;
      oTableHeight = document.querySelector('.table_outer') && this.$refs.table && this.$refs.table.$el.getBoundingClientRect().top;
      bodyHeight = document.body.offsetHeight;

      if (!fixTable) {
        this.maxTabelHeight = this.maxHeight ? this.maxHeight : bodyHeight - oTableHeight - this.scrollBar - this.excludeHeight;
      }
    },
    // 鼠标移入cell
    showTooltip(row, column, cell) {
      this.tableCellMouse.cellDom = cell;
      this.tableCellMouse.row = row;
      this.tableCellMouse.hidden = false;
    },

    // 鼠标移出cell
    hiddenTooltip() {
      this.tableCellMouse.hidden = true;
    },
    getTableEvent() {
      let { clearSelection, toggleRowSelection, toggleAllSelection, toggleRowExpansion, setCurrentRow, clearSort, clearFilter, doLayout, sort } = this.$refs.table;
      return { clearSelection, toggleRowSelection, toggleAllSelection, toggleRowExpansion, setCurrentRow, clearSort, clearFilter, doLayout, sort };
    },
    tableRowClassName({ row, rowIndex }) {
      if (this.isSelect) {
        if (this.$refs.table) {
          if (this.selectRow.includes(rowIndex)) {
            return 'selectRow';
          }
        }
      }
    },
    /* 计算宽度 */

    computedWidth() {
      this.initCol.forEach(item => {
        if (!item.width) {
          item.width = this.flexColumnWidth(item.label, item.prop, item.sortable);
        }
      });
    },
    initHead(value) {
      if (value.length) {
        value.forEach(item => {
          if (!item.hasOwnProperty('sortable')) {
            this.$set(item, 'sortable', true);
          }
        });
      }
      this.initCol = this.deepCopy(value);
      this.computedWidth();
    },
    /**
     * 遍历列的所有内容，获取最宽一列的宽度
     * @param arr
     */
    getMaxLength(arr) {
      return arr.reduce((acc, item) => {
        if (item) {
          const calcLen = this.getTextWidth(item);
          if (acc < calcLen) {
            acc = calcLen;
          }
        }
        return acc;
      }, 0);
    },
    /**
     * 使用span标签包裹内容，然后计算span的宽度 width： px
     * @param valArr
     */

    createDiv() {
      const fontSize = '14px';
      const fontFamily = "'Helvetica Neue',Helvetica,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',SimSun,sans-serif";
      const tempDom = document.createElement('div');
      const oBox = document.body;
      tempDom.style.cssText = `position: absolute;left: -999em;top:-999em;z-index: -1;font-size:${fontSize}; font-family: ${fontFamily}`;
      oBox.append(tempDom);
      this.tempDom = tempDom;
    },

    getTextWidth(text) {
      this.tempDom.textContent = text;
      const { clientWidth } = this.tempDom;
      return clientWidth;
    },

    /*  getTextWidth(str) {
      let width = 0;
      let newStr = str + '';
      if (newStr) {
        let zh = newStr.replace(/[^\u4E00-\u9FA5]/g, '');
        let en = newStr.replace(/[^a-z]/g, '');
        let Enl = newStr.replace(/[^A-Z]/g, '');
        let num = newStr.replace(/[^\d]/g, '');
        let spe = newStr.match(/[^A-Za-z0-9\u4e00-\u9fa5+]/g);
        let sym = spe ? spe.join('') : '';
        width = zh.length * 14 + en.length * 9.4 + Enl.length * 14 + num.length * 9 + sym.length * 8;
      }
      return width;
    }, */
    /**
     * el-table-column 自适应列宽
     * @param prop_label: 表名
     * @param table_data: 表格数据
     */
    flexColumnWidth(label, prop, sortable) {
      // 1.获取该列的所有数据
      let maxLength;
      const arr = this.tableData.length ? this.tableData.map(x => x[prop]) : [];
      arr.push(label); // 把每列的表头也加进去算
      // 2.计算每列内容最大的宽度 + 表格的内间距（依据实际情况而定）
      maxLength = this.$attrs.hasOwnProperty(prop + 'Width') ? this.$attrs[prop + 'Width'] : this.getMaxLength(arr) + 34 + (sortable ? 24 : 0);

      if (maxLength > 300) {
        maxLength = 300;
      }
      return maxLength + 'px';
    },

    /* 请求接口 */

    paginationChange(searchForm) {
      this.$emit('paginationChange', searchForm);
    },

    deepCopy(value) {
      if (value instanceof Function) return value;
      else if (value instanceof Array) {
        var newValue = [];
        for (let i = 0; i < value.length; ++i) newValue[i] = this.deepCopy(value[i]);
        return newValue;
      } else if (value instanceof Object) {
        var newValue = {};
        for (let i in value) newValue[i] = this.deepCopy(value[i]);
        return newValue;
      } else return value;
    },

    //列拖拽
    columnDrop() {
      const wrapperTr = document.querySelector(`.el-table .el-table__header-wrapper .${this.headerName}`);
      if (!this.isSort || !wrapperTr) return;
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        chosenClass: 'chosen',
        ghostClass: 'firefly_ghost', // drop placeholder的css类名
        onEnd: evt => {
          let fixedColum = this.isSelect ? 2 : 1;
          let newIndex = evt.newIndex - fixedColum;
          let oldIndex = evt.oldIndex - fixedColum;
          if (newIndex == oldIndex) return;
          const oldItem = this.checkCol[oldIndex];
          const newItem = this.checkCol[newIndex];

          let checkOldProp = oldItem.prop;
          let checkNewProp = newItem.prop;
          let checkOldIndex = this.initCol.findIndex(item => {
            return item.prop === checkOldProp;
          });
          let checkNewIndex = this.initCol.findIndex(item => {
            return item.prop === checkNewProp;
          });
          /* 位置互换 */
          this.initCol.splice(checkOldIndex, 1, ...this.initCol.splice(checkNewIndex, 1, this.initCol[checkOldIndex]));

          this.checkCol.splice(oldIndex, 1);
          this.checkCol.splice(newIndex, 0, oldItem);
        }
      });
    },
    /* 操作拖动 */
    lineDrop() {
      const wrapperTr = document.querySelector(`.settingPopper .${this.groupClassName}`);
      if (!this.isSort || !wrapperTr) return;
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        chosenClass: 'chosen',
        onEnd: ({ oldIndex, newIndex }) => {
          if (newIndex == oldIndex) return;
          //获取拖动后的排序
          let isBefore = newIndex < oldIndex;
          this.initCol.splice(isBefore ? newIndex : newIndex + 1, 0, this.initCol[oldIndex]);
          this.initCol.splice(isBefore ? oldIndex + 1 : oldIndex, 1);
        }
      });
    },

    // 下拉触发
    handleCommand(item) {
      let { event, scope } = item;
      event(scope);
    },

    // 清空选择
    toggleSelection() {
      this.$refs.table.clearSelection();
    },
    showText(checkKey, scope, item) {
      if (checkKey && scope && item) {
        let flang = checkKey(scope);
        if (flang.showText) {
          return flang.showText;
        }
        return item.text;
      }
      return item.text;
    },
    showBtn(checkKey, scope) {
      if (checkKey) {
        let newScope = scope ? scope : {};
        let isShow = checkKey(newScope).show;
        let flang = checkKey(newScope).hasOwnProperty('show');
        return flang ? isShow : true;
      }
      return true;
    },

    // 根据传进来的文字做判断显示按钮的不同type
    getTypeByButtonText(checkKey, item) {
      let flang = checkKey && checkKey();
      if (flang && flang.type) return flang.type;
      if ((flang && flang.showText && flang.showText.indexOf('删除') > -1) || (item.text && item.text.indexOf('删除') > -1)) return 'danger';
      return 'primary';
    },

    // 根据传进来的文字做判断显示按钮的icon
    getIconByButtonText(checkKey, item) {
      let flang = checkKey && checkKey();
      if (flang && flang.icon) return flang.icon;
      const buttonText = (flang && flang.showText) || (item.text && item.text);
      const iconObject = {
        add: 'plus',
        edit: 'edit-outline',
        delete: 'end',
        upload: 'upload',
        download: 'download',
        none: null
      };
      let iconLogotype = '';
      if (buttonText.indexOf('新增') > -1 || buttonText.indexOf('添加') > -1 || buttonText.indexOf('增加') > -1 || buttonText.indexOf('创建') > -1) {
        iconLogotype = 'add';
      } else if (buttonText.indexOf('修改') > -1 || buttonText.indexOf('编辑') > -1 || buttonText.indexOf('整改') > -1) {
        iconLogotype = 'edit';
      } else if (buttonText.indexOf('删除') > -1 || buttonText.indexOf('移除') > -1 || buttonText.indexOf('离职') > -1) {
        iconLogotype = 'delete';
      } else if (buttonText.indexOf('上传') > -1 || buttonText.indexOf('导入') > -1) {
        iconLogotype = 'upload';
      } else if (buttonText.indexOf('下载') > -1 || buttonText.indexOf('导出') > -1 || buttonText.indexOf('汇出') > -1) {
        iconLogotype = 'download';
      } else {
        iconLogotype = 'none';
      }
      return iconLogotype == 'none' ? '' : 'el-icon-' + iconObject[iconLogotype];
    }
  }
};
</script>

<style lang="scss" scoped>
@import '../../../css/fireflyTable.scss';
</style>

<style lang="scss">
.el-popover {
  &.settingPopper,
  &.fixedPopper {
    padding: 0;

    .show_title {
      padding: 6px 10px;
      line-height: 22px;
      font-size: 14px;
      border-bottom: 1px solid #eaeaec;
    }

    .el-checkbox-group {
      padding: 10px 32px;
      max-height: 500px;
      overflow-y: auto;

      .el-checkbox {
        line-height: 22px !important;
        cursor: move;
        margin-bottom: 10px;

        &:last-child {
          margin-bottom: 0;
        }

        .el-checkbox__label {
          font-size: 14px;
          color: #62606e;
        }
      }
    }
  }
}

.el-popover.fixedPopper .el-checkbox-group .el-checkbox {
  cursor: pointer;
}
</style>
