<template>
  <div class="aos-table clearfix" ref="aosTableContainer" :class="{'aos-table__inline-search': inlineSearch}">
    <div class="aos-table__explain" :style="{'justify-content': (!showCrossContainer && showExplainContainer) ? 'flex-end' : 'space-between'}" v-if="showExplain">
      <div class="aos-table__cross-container" v-if="showCrossContainer">
        <div
          class="aos-table__refresh"
          v-if="showRefresh"
          @click="handleDebounceRefresh">
          <i :style="{'transform': 'rotate(' + rotate+ 'deg)'}" class="el-icon-refresh" title="点击刷新"></i>
          <span class="aos-table__refresh-label">刷新</span>
        </div>
        <div class="aos-table__cross-container-main" v-if="showCrossSelection && copyTableTemplate.selection && copyTableTemplate.selection.showSelection">
          <el-checkbox class="aos-table__cross-container-checkbox" v-model="crossPageSelect" size="mini" @change="crossPageSelectChange">跨页选择</el-checkbox>
          <el-popover
            placement="right"
            title="跨页已选数据"
            width="600"
            trigger="click">
            <el-table
              :data="currentCrossSelectList"
              ref="AosTable"
              stripe
              highlight-current-row
              height="600"
              style="width: 100%"
              @row-click="handleRowClick">
              <template v-for="item in copyTableTemplate.tableItem">
                <el-table-column
                  v-if="!item.hide"
                  :key="item.prop"
                  :prop="item.prop"
                  :label="item.label"
                  :width="item.width"
                  :min-width="item.minWidth || '100px'"
                  :show-overflow-tooltip="item.showOverflowTooltip"
                  :sortable="item.sortable"
                  :align="item.align ? item.align : 'left'">
                  <template slot-scope="scope" >
                    <slot v-if="item.showSlot" :name="item.prop + '-slot'" :scope="scope"></slot>
                    <template v-else-if="item.type === 'defdoc'">
                      <aos-defdoc 
                        :value="scope.row[item.prop]"
                        :editable="false"
                        :defCode="item.defCode"
                        :tag="item.tag"
                        :customerUrl="item.customerUrl"
                        :multiple="item.multiple"
                        :no-def-code="item.noDefCode"
                        :orm-code="item.ormCode"
                        :orm-name="item.ormName"
                        :orm-status="item.ormStatus"
                        :orm-data="item.ormData"
                        :outer="item.outer"
                        :outer-options="item.outerOptions">
                      </aos-defdoc>
                    </template>
                    <template v-else-if="item.type === 'rule-defdoc'">
                      <aos-rule-defdoc :value="scope.row[item.prop]" :editable="false" :defCode="item.defCode" :multiple="item.multiple"></aos-rule-defdoc>
                    </template>
                    <template v-else-if="item.type === 'ref'">
                      <aos-ref :value="scope.row[item.prop]" :editable="false" :refCode="item.refCode" :filters="item.filters" :multiple="item.multiple" :onlyTranslate="true" :translateRefValueLable="scope.row[item.prop + 'Label']"></aos-ref>
                    </template>
                    <template v-else-if="item.type === 'money'">
                      <aos-money :editable="false" v-model="scope.row[item.prop]" :decimal="item.decimal || 2" :suffixString="item.suffixString"></aos-money>
                    </template>
                    <template v-else-if="item.type === 'city'">
                      <aos-city :customerUrl="item.customerUrl" :customerMethod="item.customerMethod"  :templateValue="scope.row" :edit="false" :province="item.province" :city="item.city" :county="item.county"></aos-city>
                    </template>
                    <template v-else-if="item.type === 'date-picker'">
                      <span>{{ $time.formatTime(scope.row[item.prop], ((item.attrs && item.attrs.format) || ''))}}</span>
                    </template>
                    <span v-else :title="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
                  </template>
                </el-table-column>
              </template>
              <el-table-column
                fixed="right"
                label="操作"
                width="100px">
                <template slot-scope="scope">
                  <el-button type="text" @click="handleDeleteCrossItem(scope)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
            <el-button size="mini" type="text" slot="reference">已选择</el-button>
          </el-popover>
        </div>
        <div class="aos-table__other-container" v-if="$slots.headerLeft || $slots['header-left']">
          <slot name="headerLeft"></slot>
          <slot name="header-left"></slot>
        </div>
      </div>
      <div class="aos-table__explain-container" v-if="showExplainContainer">
        <div v-if="inlineSearch" class="aos-table__inline-search-reset-container">
          <span class="aos-table__inline-search-reset" @click="handleInlineSearchReset">
            <span class="aos-table__inline-search-reset-icon">
              <svg t="1654067782205" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4392" width="12" height="12"><path d="M892.8 320.2H624.6V130.1c0-35.3-28.7-64-64-64h-97.2c-35.3 0-64 28.7-64 64v190.1H129.8c-35.3 0-64 28.7-64 64v97.2c0 35 28 63.4 62.9 64v312.4c0 55.2 44.8 100 100 100h568.4c55.2 0 100-44.8 100-100V545.3c33.3-2.2 59.7-29.9 59.7-63.8v-97.2c0-35.4-28.6-64.1-64-64.1z m-27.7 537.6c0 37.5-30.5 68-68 68h-84.4V781.6c0-8.8-7.2-16-16-16s-16 7.2-16 16v144.2H528.6V781.6c0-8.8-7.2-16-16-16s-16 7.2-16 16v144.2H344.5V781.6c0-8.8-7.2-16-16-16s-16 7.2-16 16v144.2h-83.8c-37.5 0-68-30.5-68-68V545.7h704.4v312.1z m59.7-376.4c0 17.6-14.4 32-32 32h-763c-17.6 0-32-14.4-32-32v-97.2c0-17.6 14.4-32 32-32h301.6V130.1c0-17.6 14.4-32 32-32h97.2c17.6 0 32 14.4 32 32v222.1h300.2c17.6 0 32 14.4 32 32v97.2z" fill="#409EFF" p-id="4393"></path></svg>
            </span>
            <span class="aos-table__inline-search-reset-label">重置</span>
          </span>
        </div>
        <div class="aos-table__operation" v-if="copyTableTemplate.operationColumn && copyTableTemplate.operationColumn.showOperation && copyTableTemplate.operationColumn.operationType === 'icon' && copyTableTemplate.operationColumn.iconList && copyTableTemplate.operationColumn.iconList.length > 0">
          <span class="aos-table__explain-title">操作列图标说明：</span>
          <span v-for="icon in copyTableTemplate.operationColumn.iconList" :key="icon.code" class="aos-table__explain-item">
            <i :class="'el-icon-'+icon.icon"></i>
            <span>：{{icon.detail ? icon.detail : icon.title}}</span>
          </span>
        </div>
        <div class="aos-table__setting" v-if="showSetting">
          <el-dropdown trigger="click" :hide-on-click="false"  @command="handleSettingItem">
            <i class="el-icon-setting" title="设置操作列的显示/隐藏"></i>
            <el-dropdown-menu slot="dropdown">
              <!-- <el-dropdown-item>
                <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
              </el-dropdown-item> -->
              <!-- <el-checkbox-group v-model="allItem" @change="handleItemChange"> -->
                <el-dropdown-item v-for="(item,index) in copyTableTemplate.tableItem" :key="item.prop">
                  <el-checkbox :value="!item.hide" :checked="!item.hide" :label="item.prop" @change="handleItemTypeChange(index)">{{item.label}}</el-checkbox>
                </el-dropdown-item>
              <!-- </el-checkbox-group> -->
            </el-dropdown-menu>
          </el-dropdown>
        </div>
      </div>
    </div>
    <div class="aos-table__container">
      <el-table
        :data="data"
        ref="AosTable"
        :stripe="stripe"
        highlight-current-row
        :height="tableHeight"
        :border="border"
        :fit="fit"
        :row-class-name="rowClassName"
        :show-summary="showSummary"
        :select-on-indeterminate="selectOnIndeterminate"
        :sum-text="sumText"
        :row-key="rowKey"
        :empty-text="emptyText"
        :default-expand-all="defaultExpandAll"
        :expand-row-keys="expandRowKeys"
        :default-sort="defaultSort"
        :tooltip-effect="tooltipEffect"
        :summary-method="summaryMethod"
        :span-method="spanMethod"
        :indent="indent"
        :lazy="lazy"
        :load="load"
        :tree-props="treeProps"
        style="width: 100%"
        @select="handleSelect"
        @selection-change="handleSelectionChange"
        @sort-change="handleSortChange"
        @row-click="handleRowClick"
        @scroll="handleScroll">
        <el-table-column
          v-if="copyTableTemplate.selection && copyTableTemplate.selection.showSelection"
          type="selection"
          :selectable="selectable"
          :min-width="copyTableTemplate.selection.minWidth"
          :width="copyTableTemplate.selection.width || '60'">
        </el-table-column>
        <template v-for="item in copyTableTemplate.tableItem">
          <el-table-column
            v-if="!item.hide"
            :key="item.prop"
            :prop="item.prop"
            :label="item.label"
            :width="item.width"
            :min-width="item.minWidth || '110px'"
            :fixed="item.fixed"
            :show-overflow-tooltip="item.showOverflowTooltip"
            :sortable="item.sortable"
            :sort-method="item.sortMethod"
            :resizable="item.resizable || true"
            :align="item.align ? item.align : 'left'">
            <template slot="header" v-if="inlineSearch">
              <div v-if="item && item.prop" class="aos-table__inline-header">
                <div :class=" { 'header-center': inlineSearch}"  class="aos-table__inline-header-label">
                  {{ item.label }}
                </div>
                <div class="aos-table__inline-header-body">
                  <template v-if="!item.hideInlineSearch && ((item.searchType ? item.searchType : item.type) === 'input' || !item.type)">
                    <inline-input
                      :ref="(item.searchProp ? item.searchProp : item.prop) + '-inline-search'"
                      :placeholder="'请输入' + item.label"
                      :value="(item.searchProp ? copySearchData[item.searchProp] : copySearchData[item.prop])"
                      @change="function(data) {handleInlineSearchChange(data, item)}">
                    </inline-input>
                  </template>
                  <template v-if="!item.hideInlineSearch && (item.searchType ? item.searchType : item.type) === 'defdoc'">
                    <aos-defdoc
                      :placeholder="'请选择'+item.label"
                      :ref="(item.searchProp ? item.searchProp : item.prop) + '-inline-search'"
                      :value="item.searchProp ? copySearchData[item.searchProp] : copySearchData[item.prop]"
                      :editable="true"
                      :defCode="item.defCode"
                      :tag="item.tag"
                      :customerUrl="item.customerUrl"
                      :multiple="item.multiple"
                      :no-def-code="item.noDefCode"
                      :orm-code="item.ormCode"
                      :orm-name="item.ormName"
                      :orm-status="item.ormStatus"
                      :orm-data="item.ormData"
                      :outer="item.outer"
                      :outer-options="item.outerOptions"
                      @change="function(data) { handleInlineSearchChange(data, item)}">
                    </aos-defdoc>
                  </template>
                  <template v-if="!item.hideInlineSearch && (item.searchType ? item.searchType : item.type) === 'ref'">
                    <aos-ref
                      :placeholder="'请选择'+item.label"
                      :ref="(item.searchProp ? item.searchProp : item.prop) + '-inline-search'"
                      :value="item.searchProp ? copySearchData[item.searchProp] : copySearchData[item.prop]"
                      :editable="true"
                      :refCode="item.refCode"
                      :multiple="item.multiple"
                      :filters="item.filters"
                      @change="function(data) { handleInlineSearchChange(data, item)}">
                    </aos-ref>
                  </template>
                  <template v-if="!item.hideInlineSearch && (item.searchType ? item.searchType : item.type) === 'date'">
                    <inline-date :ref="(item.searchProp ? item.searchProp : item.prop) + '-inline-search'" :value="item.searchProp ? copySearchData[item.searchProp] : copySearchData[item.prop]" :format="item.format" :type="item.searchType || 'date'" @end="function(data) { handleInlineSearchChange(data, item)}"></inline-date>
                  </template>
                  <template v-if="!item.hideInlineSearch && (item.searchType ? item.searchType : item.type) === 'number-range'">
                    <inline-number-range :ref="(item.searchProp ? item.searchProp : item.prop) + '-inline-search'" :value="item.searchProp ? copySearchData[item.searchProp] : copySearchData[item.prop]" :precision="item.precision" @change="function(data) { handleInlineSearchChange(data, item)}"></inline-number-range>
                  </template>
                  <template v-if="!item.hideInlineSearch && (item.searchType ? item.searchType : item.type) === 'money'">
                    <inline-number-range :ref="(item.searchProp ? item.searchProp : item.prop) + '-inline-search'" :value="item.searchProp ? copySearchData[item.searchProp] : copySearchData[item.prop]" :precision="item.precision || 2" @change="function(data) { handleInlineSearchChange(data, item)}"></inline-number-range>
                  </template>
                  <template v-if="!item.hideInlineSearch && (item.searchType ? item.searchType : item.type) === 'number'">
                    <el-input-number :ref="(item.searchProp ? item.searchProp : item.prop) + '-inline-search'" :value="item.searchProp ? copySearchData[item.searchProp] : copySearchData[item.prop]" :step="item.step" step-strictly @change="function(data) { handleInlineSearchChange(data, item)}"></el-input-number>
                  </template>
                </div>
              </div>
            </template>
            <template slot-scope="scope" >
              <slot v-if="item.showSlot" :name="item.prop + '-slot'" :scope="scope"></slot>
              <template v-else-if="item.type === 'defdoc'">
                <aos-defdoc 
                  :value="scope.row[item.prop]"
                  :editable="false"
                  :defCode="item.defCode"
                  :tag="item.tag"
                  :customerUrl="item.customerUrl"
                  :multiple="item.multiple"
                  :no-def-code="item.noDefCode"
                  :orm-code="item.ormCode"
                  :orm-name="item.ormName"
                  :orm-status="item.ormStatus"
                  :outer="item.outer"
                  :outer-options="item.outerOptions"
                  :orm-data="item.ormData">
                </aos-defdoc>
              </template>
              <template v-else-if="item.type === 'remote-select'">
                <aos-select :value="scope.row[item.prop]" :editable="false" :url="item.url" :multiple="item.multiple"></aos-select>
              </template>
              <template v-else-if="item.type === 'rule-defdoc'">
                <aos-rule-defdoc :value="scope.row[item.prop]" :editable="false" :defCode="item.defCode" :multiple="item.multiple"></aos-rule-defdoc>
              </template>
              <template v-else-if="item.type === 'ref'">
                <aos-ref :value="scope.row[item.prop]" :editable="false" :refCode="item.refCode" :filters="item.filters" :multiple="item.multiple" :onlyTranslate="true" :translateRefValueLable="scope.row[item.prop + 'Label']"></aos-ref>
              </template>
              <template v-else-if="item.type === 'money'">
                <aos-money :editable="false" v-model="scope.row[item.prop]" :decimal="item.decimal || 2" :suffixString="item.suffixString"></aos-money>
              </template>
              <template v-else-if="item.type === 'city'">
                <aos-city :templateValue="scope.row" :edit="false" :province="item.province" :city="item.city" :county="item.county" :customerUrl="item.customerUrl" :customerMethod="item.customerMethod"></aos-city>
              </template>
              <template v-else-if="item.type === 'date-picker'">
                <span>{{ $time.formatTime(scope.row[item.prop], item.format || (((item.attrs && item.attrs.format)) || ''))}}</span>
              </template>
              <template v-else-if="item.type === 'date'">
                <span>{{ $time.formatTime(scope.row[item.prop], item.format || '')}}</span>
              </template>
              <template v-else-if="item.type === 'select'">
                <span>{{ getSelectLabel(item, scope.row[item.prop])}}</span>
              </template>
              <span v-else :title="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
            </template>
          </el-table-column>
        </template>
        <el-table-column
          v-if="copyTableTemplate.operationColumn && copyTableTemplate.operationColumn.showOperation"
          :fixed="copyTableTemplate.operationColumn.fixed || 'right'"
          :label="copyTableTemplate.operationColumn.label || '操作'"
          :width="copyTableTemplate.operationColumn.width || operationColumnMinWidth+ 'px'"
          :min-width="copyTableTemplate.operationColumn.minWidth">
          <template v-if="inlineSearch" slot="header">
            <div class="aos-table__inline-header">
              <div v-if="copyTableTemplate.operationColumn.label" class="aos-table__inline-header-label">{{ copyTableTemplate.operationColumn.label }}</div>
              <div v-else class="aos-table__inline-header-label">操作</div>
            </div>
          </template>
          <template slot-scope="scope">
            <div class="aos-table__operation">
              <slot v-if="copyTableTemplate.operationColumn.showOperationSlot" name="operation-slot" :scope="scope"></slot>
              <template v-if="copyTableTemplate.operationColumn.operationType === 'icon' && copyTableTemplate.operationColumn.iconList && copyTableTemplate.operationColumn.iconList.length > 0">
                <span v-for="icon in copyTableTemplate.operationColumn.iconList" :key="icon.code" v-auth="icon.auth">
                  <i class="aos-table-icon"
                    :class="'el-icon-'+icon.icon" 
                    :title="icon.title"
                    v-if="iconable(scope.row, icon.code)"
                    @click="handleIconClick(icon.code,scope)">
                  </i>
                </span>
              </template>
              <template v-else-if="copyTableTemplate.operationColumn.operationType === 'button' && copyTableTemplate.operationColumn.iconList && copyTableTemplate.operationColumn.iconList.length > 0">
                <span v-for="icon in copyTableTemplate.operationColumn.iconList" :key="icon.code">
                  <span v-if="iconable(scope.row, icon.code)">
                    <el-button
                      class="aos-table-button"
                      type="text"
                      :text-type="icon.type ? icon.type : 'primary'"
                      v-auth="icon.auth"
                      @click="handleIconClick(icon.code,scope)">{{icon.title}}</el-button>
                  </span>
                </span>
                <el-dropdown trigger="click" v-if="copyTableTemplate.operationColumn.moreIconList" @command="function (command) {handleIconClick(command,scope)}">
                  <el-button type="text">
                    更多<i class="el-icon-arrow-down el-icon--right"></i>
                  </el-button>
                  <el-dropdown-menu slot="dropdown" ref="">
                    <span v-for="item in copyTableTemplate.operationColumn.moreIconList" :key="item.code">
                      <span v-if="iconable(scope.row, item.code)">
                        <el-dropdown-item
                          :class="'aos-table__operation-button--'+ (item.type ? item.type : 'primary')"
                          :command="item.code"
                          v-auth="item.auth"
                          >{{item.title}}</el-dropdown-item>
                      </span>
                    </span>
                    </el-dropdown-menu>
                </el-dropdown>
              </template>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
          class="aos-table-pagination"
          v-if="showPagination"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          @prev-click="handlePrevClick"
          @next-click="handleNextClick"
          :current-page="currentPage"
          :page-sizes="pageSizes"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total">
      </el-pagination>
    </div>
</div>
</template>
<script>
import ElTable from '../../table';
import ElPagination from '../../pagination';
import AosForm from '../../aos-form'
import {addResizeListener,removeResizeListener} from 'aos-element/src/utils/resize-event.js'
import isEqual from 'lodash/isEqual';
import cloneDeep from 'lodash/cloneDeep';
import debounce from 'throttle-debounce/debounce';
import InlineDate from './inline-date'
import InlineInput from './inline-input.vue'
import InlineNumberRange from './inline-number-range'
export default {
  name: 'AosTable',
  components: {
    ElTable,
    ElPagination,
    AosForm,
    InlineDate,
    InlineNumberRange,
    InlineInput
  },
  props:{
    // table绑定的数据
    data: {
      type: Array,
      required: true,
      default: function(){
        return []
      }
    },
    // table构成列属性
    tableTemplate: {
      type: Object,
      required: true
    },
    // 是否显示分页
    showPagination: {
      type: Boolean,
      default: true
    },
    // 分页的当前页
    currentPage: {
      type: Number,
      default: 1
    },
    // 分页的页的数量
    pageSize: {
      type: Number,
      default: 10
    },
    // 当前table数据总共的数量
    total: {
      type: Number,
      default: 0
    },
    showType: {
      type: String,
      default: 'table'
    },
    fixedHead: {
      type: Boolean,
      default: false
    },
    maxTableHeight: {
      type: Number
    },
    // 当使用复选框是设置复选框是否可选
    selectable: {
      type: Function,
      default: function () {
        return function () { return true }
      }
    },
    // 根据条件设置icon显示或者隐藏
    iconable: {
      type: Function,
      default: function () {
        return function () {
          return true
        }
      }
    },
    // 是否开启行内搜索
    inlineSearch: {
      type: Boolean,
      default: false
    },
    // 是否显示设置列操作
    showSetting: {
      type: Boolean,
      default: true
    },
    fit: {
      type: Boolean,
      default: true
    },

    border: Boolean,
    stripe: {
      type: Boolean,
      default: true
    },

    rowKey: [String, Function],

    context: {},

    showHeader: {
      type: Boolean,
      default: true
    },

    showSummary: Boolean,

    sumText: String,

    summaryMethod: Function,

    rowClassName: [String, Function],

    rowStyle: [Object, Function],

    cellClassName: [String, Function],

    cellStyle: [Object, Function],

    headerRowClassName: [String, Function],

    headerRowStyle: [Object, Function],

    headerCellClassName: [String, Function],

    headerCellStyle: [Object, Function],

    highlightCurrentRow: Boolean,

    currentRowKey: [String, Number],

    emptyText: String,

    expandRowKeys: Array,

    defaultExpandAll: Boolean,

    defaultSort: Object,

    tooltipEffect: String,

    spanMethod: Function,

    selectOnIndeterminate: {
      type: Boolean,
      default: true
    },

    indent: {
      type: Number,
      default: 16
    },

    treeProps: {
      type: Object,
      default() {
        return {
          hasChildren: 'hasChildren',
          children: 'children'
        };
      }
    },

    lazy: Boolean,

    load: Function,
    showRefresh: {
      type: Boolean,
      default: false
    },
    showCrossSelection: {
      type: Boolean,
      default: false
    },
    inlineSearchData: {},
    id: {
      type: String
    },
    pageSizes: {
      type: Array,
      default: function () {
        return [5,10,20,30,40,50]
      },
      validator: function (value) {
        return Array.isArray(value)
      }
    }
  },
  data(){
    return {
      tableHeight: null,
      refLableList: [],
      refValueDataListObject: {},
      copyData: [],
      checkAll: false,
      copyTableTemplate: {},
      isIndeterminate: false,
      allItem: [],
      currentTableTemplate: [],
      crossPageSelect: false,
      currentCrossSelectList: [],
      currentSelectionList: [],
      rotate: 0,
      handleDebounceRefresh: '', 
      copySearchData: {},
      copyTableItemObject: {},
      handleInlineSearchChangeEmit: '',
      lastCondition: '',
      operationColumnMinWidth: 120,
      debounceSaveSetting: '',
      scrollLeft: 0,
      scrollTop: 0,
      canGetScroll: true,
      selectObject: {}
    };
  },
  computed: {
    // copyTableTemplate() {
    //   return this.tableTemplate;
    // },
    refPropList () {
      let refPropList = []
      if (this.tableTemplate && this.tableTemplate.tableItem) {
        this.tableTemplate.tableItem.forEach(item => {
          if (item.type === 'ref') {
            refPropList.push(item)
          }
        });
      }
      return refPropList
    },
    showCrossContainer () {
      return this.showRefresh || this.showCrossSelection || this.$slots.headerLeft || this.$slots['header-left']
    },
    showExplainContainer () {
      return this.inlineSearch || this.showSetting || (this.copyTableTemplate.operationColumn && this.copyTableTemplate.operationColumn.showOperation && this.copyTableTemplate.operationColumn.operationType === 'icon' && this.copyTableTemplate.operationColumn.iconList && this.copyTableTemplate.operationColumn.iconList.length > 0)
    },
    showExplain () {
      return this.showCrossContainer || this.showExplainContainer
    }
  },
  watch: {
    fixedHead(val, oldVal) {
      if (val && !this.$_.isEqual(val, oldVal)) {
        if (this.maxTableHeight) {
          this.tableHeight = this.maxTableHeight;
        } else {
          addResizeListener(this.$refs.aosTableContainer.parentElement.parentElement, this.resizeTableHeight);
        }
      }
    },
    data: {
      handler: function(val, oldVal) {
        if (val && Array.isArray(val) && !this.$_.isEqual(val, oldVal)) {
          this.translateRef(val)
        }
      },
      deep: true,
      immediate: true
    },
    tableTemplate: {
      handler: function (val, oldVal) {
        if (val && !this.$_.isEqual(val, oldVal)) {
          this.copyTableTemplate = this.$_.cloneDeep(val);
          this.copyTableTemplate.tableItem.forEach(item => {
            if (!item.hasOwnProperty('hide')) {
              this.$set(item, 'hide', false)
            }
            const prop = item.searchProp ? item.searchProp : item.prop
            this.$set(this.copySearchData, prop, '')
            this.$set(this.copyTableItemObject, prop, item)
          })
          if (this.copyTableTemplate.operationColumn && !this.copyTableTemplate.operationColumn.operationType) {
            this.copyTableTemplate.operationColumn.operationType = 'icon'
          }
          if (this.copyTableTemplate.operationColumn && this.copyTableTemplate.operationColumn.operationType === 'button' && this.copyTableTemplate.operationColumn.iconList) {
            const iconList = this.copyTableTemplate.operationColumn.iconList
            
            if (iconList.length > 3) {
              this.copyTableTemplate.operationColumn.moreIconList = iconList.splice(3)
              let allTitle = ''
              iconList.forEach(item  => {
                allTitle += item.title
              })
              this.operationColumnMinWidth = allTitle.length * 12 + 82
            } else {
              let allTitle = ''
              iconList.forEach(item  => {
                allTitle += item.title
              })
              this.operationColumnMinWidth = allTitle.length * 12 + (iconList.length+2) * 8 
            }
          }
          this.getSelectObjectFromTemplate()
        }
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    getSelectLabel (item, value) {
      let label = ''
      if (Object.keys(this.selectObject).length > 0) {
        if (![NaN, null, '', undefined].includes(value)) {
          if (Array.isArray(value) && value.length > 0) {
            const labelList = []
            value.forEach(valueItem => {
              labelList.push(this.selectObject[item.prop][valueItem])
            })
            label = labelList.join(',')
          } else {
            if (typeof value === 'string' && value.includes(',')) {
              const valueList = value.split(',')
              const labelList = []
              valueList.forEach(valueItem => {
                labelList.push(this.selectObject[item.prop][valueItem])
              })
              label = labelList.join(',')
            } else {
              label = this.selectObject[item.prop][value]
            }
          }
        }
      }
      return label
    },
    getSelectObjectFromTemplate () {
      if (this.tableTemplate && this.tableTemplate.tableItem && Array.isArray(this.tableTemplate.tableItem) && this.tableTemplate.tableItem.length > 0) {
        this.tableTemplate.tableItem.forEach(item => {
          if (item.type === 'select' && Array.isArray(item.option) && item.option.length > 0) {
            this.selectObject[item.prop] = {}
            item.option.forEach(optionItem => {
              this.selectObject[item.prop][optionItem.value] = optionItem.label
            })
          }
        })
      }
    },
    setCopyTableTemplateFromSetting (val) {
      if (val) {
        const tableItem = val.tableItem
        const itemObject = {}
        tableItem.forEach(child => {
          itemObject[child.prop] = child
        })
        this.copyTableTemplate.tableItem.forEach(item => {
          const inlineItem = itemObject[item.prop]
          if (inlineItem) {
            item.hide = inlineItem.hide
          }
        })
      }
    },
    getSetting () {
      this.$http({
        url: '/core/api/my-fe-setting',
        params: {
          key: this.id
        }
      }).then(res => {
        if (res.status === 200) {
          if (res.data) {
            this.setCopyTableTemplateFromSetting(res.data)
          }
        }
      })
    },
    saveSetting () {
      this.$http({
        url: '/core/api/my-fe-setting-update',
        method: 'post',
        data: {
          key: this.id,
          config: JSON.stringify(this.copyTableTemplate)
        }
      }).then(() => {
        
      })
    },
    handleInlineSearchReset () {
      Object.keys(this.copySearchData).forEach(item => {
        this.copySearchData[item] = ''
        const refsList = this.$refs[item + '-inline-search']
        if (refsList && Array.isArray(refsList) && refsList.length > 0) {
          refsList.forEach(refsItem => {
            if (refsItem.reset) {
              refsItem.reset()
            }
          })
        }
      })
      this.handleInlineSearchChangeEmit()
    },
    inlineSearchEmit () {
      let conditionStr = this.buildSearchCondition()
      const condition = conditionStr ? conditionStr : ''
      if (this.lastCondition === condition) {
        return
        // this.handleInlineSearchChangeEmit(condition)
      }
      this.lastCondition = condition
      this.$emit('inline-search', conditionStr, cloneDeep(this.copySearchData))
    },
    handleInlineSearchChange (data, item) {
      const prop = item.searchProp ? item.searchProp : item.prop
      this.copySearchData[prop] = data
      this.handleInlineSearchChangeEmit()
    },
    buildSearchCondition () {
      let sqlList = []
      let type = ''
      Object.keys(this.copySearchData).forEach(item => {
        if (this.copyTableItemObject[item]) {
          type = this.copyTableItemObject[item].searchType || (this.copyTableItemObject[item].type ? this.copyTableItemObject[item].type : 'default')
        }
        if (this.copySearchData[item]) {
          const sql = this.sqlMaker(type,this.copyTableItemObject[item],this.copySearchData[item])
          if (Array.isArray(sql)) {
            sqlList = sqlList.concat(sql)
          } else {
            sqlList.push(sql)
          }
        }
      })
      if (sqlList.length <= 0) {
        return ''
      } else {
        const condition = JSON.stringify(sqlList)
        return condition;
      }
    },
    sqlMaker (type, item, value) {
      const prop = item.searchProp ? item.searchProp : item.prop
      let searchData = {
        fieldName: prop,
        value: '',
        connector: ''
      }
      switch (type) {
        case 'defdoc':
          if (item.multiple) {
            const data = value.split(',')
            searchData.value = data
          } else {
            searchData.value = [value]
          }
          searchData.connector = 'in'
          break;
        case 'ref':
          if (item.multiple) {
            const data = value.split(',')
            searchData.value = data
          } else {
            searchData.value = value
          }
          searchData.connector = 'in'
          break;
        case 'date':
          const dateData = cloneDeep(searchData)
          searchData = []
          if (value[0]) {
            const data = cloneDeep(dateData)
            data.value = value[0]
            data.connector = '>='
            data.format = item.format || 'yyyy-mm-dd hh24:mi:ss'
            searchData.push(data)
          }
          if (value[1]) {
            const data = cloneDeep(dateData)
            data.value = value[1]
            data.connector = '<='
            data.format = item.format || 'yyyy-mm-dd hh24:mi:ss'
            searchData.push(data)
          }
          break;
        case 'number-range':
        case 'money':
          const numberData = cloneDeep(searchData)
          searchData = []
          if (value[0]) {
            const data = cloneDeep(numberData)
            data.value = value[0]
            data.connector = '>='
            searchData.push(data)
          }
          if (value[1]) {
            const data = cloneDeep(numberData)
            data.value = value[1]
            data.connector = '<='
            searchData.push(data)
          }
          break;
        case 'input':
          searchData.value = value
          searchData.connector = 'like'
          break;
        default:
          searchData.value = value
          searchData.connector = 'like'
          break;
      }
      return searchData;
    },
    handleDeleteCrossItem (scope) {
      this.$confirm('确认删除当前数据?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.currentCrossSelectList.splice(scope.$index, 1)
        this.handleSelectionChange(this.currentSelectionList)
      })
    },
    handleSettingItem () {},
    crossPageSelectChange (value) {
      if (!value) {
        this.currentCrossSelectList = []
      }
    },
    handleCheckAllChange (val) {
      const propList = []
      this.copyTableTemplate.tableItem.forEach(item => {
        item.hide = !item.hide
        propList.push(item.prop)
      })
      this.allItem = val ? propList : []
      this.isIndeterminate = false;
    },
    handleItemTypeChange(index) {
      this.copyTableTemplate.tableItem[index].hide = !this.copyTableTemplate.tableItem[index].hide
      if (this.id && this.showSetting) {
        this.debounceSaveSetting()
      }
    },
    handleItemChange (value) {
      const checkedCount = value.length;
      this.checkAll = checkedCount === this.copyTableTemplate.tableItem.length
      this.isIndeterminate = checkedCount > 0 && checkedCount === this.copyTableTemplate.tableItem.length
    },
    handleSelect(selection, row) {
      // console.log('select', selection, row)
    },
    // 多选框选择事件TODO:翻页触发事件问题
    handleSelectionChange(data){
      this.currentSelectionList = cloneDeep(data)
      const selectionList = cloneDeep(data)
      if (this.crossPageSelect) {
        const list = cloneDeep(this.currentCrossSelectList)
        selectionList.forEach(item => {
          let flag = true
          for (let index = 0; index < this.currentCrossSelectList.length; index++) {
            const element = this.currentCrossSelectList[index];
            if (isEqual(element, item)) {
              flag = false
              break
            }
          }
          if (flag) {
            list.push(item)
          }
        })
        this.$emit('table-selection-change', list);
      } else {
        this.$emit('table-selection-change', data);
      }
    },
    handleCrossSelectionChange(array){
      if(Array.isArray(array)){
        this.currentCrossSelectList = array
        this.$emit('table-selection-change', this.currentCrossSelectList);
      }
    },
    handleSortChange (data) {
      this.$emit('sort-change', data)
    },
    handleRowClick(row,column,event){
      this.$emit('table-row-click',row,column,event);
    },
    handleScroll (scrollLeft, scrollTop) {
      if (this.canGetScroll) {
        this.scrollLeft = scrollLeft
        this.scrollTop = scrollTop
      }
    },
    // 抛出操作列点击按钮
    handleIconClick(type,scope){
      this.$emit('table-'+type+'-click',scope)
    },
    // 当前数量改变
    handleSizeChange(size){
      this.$emit('table-size-change',size);
    },
    // 当前页数改变
    handleCurrentChange(page){
      if (this.crossPageSelect) {
        const currentCrossSelectList = this.currentCrossSelectList.concat(this.currentSelectionList)
        for (let index = 0; index < currentCrossSelectList.length; index++) {
          const element = currentCrossSelectList[index];
          for (let j = index + 1; j < currentCrossSelectList.length; j++) {
            const childElement = currentCrossSelectList[j];
            if (isEqual(element, childElement)) {
              currentCrossSelectList.splice(j, 1)
            }
          }
        }
        this.currentCrossSelectList = cloneDeep(currentCrossSelectList)
      }
      this.$emit('table-current-change',page);
    },
    // 点击上一页
    handlePrevClick(page){
      this.$emit('table-prev-click',page);
    },
    // 点击下一页
    handleNextClick(page){
      this.$emit('table-next-click',page);
    },
    resizeTableHeight(){
      const self = this;
      this.$nextTick(() => {
        let boxHeight
        if (self.$refs && self.$refs.aosTableContainer && self.$refs.aosTableContainer.parentElement && self.$refs.aosTableContainer.parentElement.parentElement) {
          boxHeight = self.$refs.aosTableContainer.parentElement.parentElement.offsetHeight;
        }
        // if (!boxHeight) {
        //   const totalHeight = document.body.clientHeight
        //   boxHeight = totalHeight - 160
        // }
        if(boxHeight < 400){
          self.tableHeight = 400
        } if (boxHeight > 1200) {
          self.tableHeight = 1200
        } else {
          if (self.showPagination) {
            self.tableHeight  = boxHeight - 136;
          } else {
            self.tableHeight = boxHeight - 71;
          }
        }
      });
    },
    setRefObject (val, item) {
      val.forEach((dataItem) => {
        if (dataItem && !dataItem[item.prop + 'Label']) {
          this.$set(dataItem, item.prop + 'Label', '');
        }
        if (!this.refValueDataListObject[item.prop].valueList) {
          this.$set(this.refValueDataListObject[item.prop], 'valueList', [])
        }
        if (!this.refValueDataListObject[item.prop].labelValueList) {
          this.$set(this.refValueDataListObject[item.prop], 'labelValueList', [])
        }
        if (!this.refValueDataListObject[item.prop].labelValueObject) {
          this.$set(this.refValueDataListObject[item.prop], 'labelValueObject', {})
        }
        if (dataItem[item.prop]) {
          if (this.refValueDataListObject[item.prop].valueList.indexOf(dataItem[item.prop]) === -1) {
            this.refValueDataListObject[item.prop].valueList.push(dataItem[item.prop])
          }
        }
        if (this.treeProps && dataItem[this.treeProps.children]) {
          this.setRefObject(dataItem[this.treeProps.children], item)
        }
      });
    },
    setRefLabel (val, item) {
      val.forEach((dataItem) => {
        if (this.refValueDataListObject[item.prop].labelValueObject[dataItem[item.prop]]) {
          dataItem[item.prop + 'Label'] = this.refValueDataListObject[item.prop].labelValueObject[dataItem[item.prop]]
        } else {
          dataItem[item.prop + 'Label'] = dataItem[item.prop]
        }
        if (this.treeProps && dataItem[this.treeProps.children]) {
          this.setRefLabel(dataItem[this.treeProps.children], item)
        }
      });
    },
    translateRef (val) {
      if (val.length > 0 && this.refPropList.length > 0) {
        // 拿到对应prop列的值
        this.refPropList.forEach(item => {
          this.$set(this.refValueDataListObject, item.prop, {})
          this.setRefObject(val, item)
        });
        let allGetLabel = []
        this.refPropList.forEach(item => {
          // this.getRefLabel(item.refCode, this.refValueDataListObject[item.prop])
          allGetLabel.push(this.getRefLabel(item.refCode, this.refValueDataListObject[item.prop]))
        })
        window.Promise.allSettled(allGetLabel).then(() => {
          this.refPropList.forEach(item => {
            this.setRefLabel(val, item)
          });
          this.$emit('update: data', val)
        }).catch(error => {
          console.log('error===>', error)
        })
      }
    },
    getRefLabel(refCode, refValueDataListObject) {
      if (!refCode) {
        this.$message({
          type: 'error',
          message: '参照对应的 refCode 不能为空.'
        });
        return;
      }
      const paramsData = refValueDataListObject.valueList.join(',')
      if (!paramsData) {
        return;
      }
      return this.$optimizeHttp({
        url: '/core/api/ref/translate/' + refCode,
        method: 'get',
        params: {
          code: paramsData
        }
      }).then(res => {
        refValueDataListObject.labelValueList = cloneDeep(res.data);
        refValueDataListObject.labelValueObject = this.arrayToObject(refValueDataListObject.labelValueList)
      })
    },
    arrayToObject (array) {
      if (!array && !Array.isArray(array))  return {}
      let object = {}
      array.forEach(item => {
        object[item.code] = item.value
      })
      return object
    },
    refreshClick() {
      this.rotate += 180
      this.$emit('refresh')
    },
    getCopySearchData () {
      if (this.inlineSearchData && Object.prototype.toString.call(this.inlineSearchData) === '[object Object]') {
        const keyList = Object.keys(this.inlineSearchData)
        if (keyList.length > 0) {
          keyList.forEach(key => {
            this.$set(this.copySearchData, key, this.inlineSearchData[key])
          })
        }
      }
    }
  },
  created () {
    this.handleDebounceRefresh = debounce(50,this.refreshClick)
    this.debounceSaveSetting = debounce(1000, this.saveSetting)
    this.handleInlineSearchChangeEmit = debounce(800, this.inlineSearchEmit)
    this.getCopySearchData()
    if (this.id && this.showSetting) {
      this.getSetting()
    }
  },
  mounted(){
    if(this.fixedHead){
      if (this.maxTableHeight) {
        this.tableHeight = this.maxTableHeight
      } else {
        addResizeListener(this.$refs.aosTableContainer.parentElement.parentElement,this.resizeTableHeight);
      }
    }
  },
  beforeDestroy(){
    if(this.fixedHead && !this.maxTableHeight){
      removeResizeListener(this.$refs.aosTableContainer.parentElement.parentElement,this.resizeTableHeight);
    }
  },
  activated () {
    this.$refs.AosTable.setBodyWrapperScroll(this.scrollLeft, this.scrollTop)
    this.canGetScroll = true
  },
  deactivated () {
    this.canGetScroll = false
  }

};
</script>

