<template>
  <div class="dg-transfer">
    <div class="dg-table-transfer">
      <!-- 左侧穿梭框 -->
      <div class="el-transfer-panel">
        <p class="el-transfer-panel__header">
          <el-checkbox :indeterminate="sourceIsIndeterminate" v-model="sourceCheckAll" @change="sourceAllBoxCheck">
            <template v-if="titles[0] !== undefined">{{ titles[0] }}</template>
          </el-checkbox>
          <slot name="title-left"></slot>
        </p>
        <!-- 内容区 -->
        <div class="el-transfer-panel__body">
          <el-input
            v-if="filterable"
            class="el-transfer-panel__filter"
            :placeholder="filterPlaceholder"
            v-model="filterFrom"
            size="small"
            :class="{ 'el-transfer-panel__search': filterable }"
          >
            <i slot="prefix" :class="['el-input__icon', 'el-icon-search']"></i>
          </el-input>
          <dg-table
            ref="multipleSourceTable"
            paging-type="client"
            border
            :data="sourceData"
            style="width: 100%"
            :header-cell-style="headerCellStyle"
            @selection-change="handleSelectionChangeSource"
          >
            <dg-table-column type="selection"></dg-table-column>
            <dg-table-column type="index" label="序号" width="65px" align="center"></dg-table-column>
            <dg-table-column
              :prop="item.val"
              :label="item.label"
              :key="'sourceId' + item.val + index"
              v-for="(item, index) in columnLabelNameList"
              show-overflow-tooltip
            >
            </dg-table-column>
          </dg-table>
        </div>
        <p class="el-transfer-panel__footer" v-if="$slots['left-footer']">
          <slot name="left-footer"></slot>
          <!-- <el-pagination :page-size="pageSize" layout="prev, pager, next" :total="sourceTotal"> </el-pagination> -->
        </p>
      </div>

      <!-- 穿梭区 按钮框 -->
      <div class="el-transfer__buttons">
        <el-button
          type="primary"
          :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
          @click.native="addToSource"
          :disabled="targetDisabled"
        >
          <i class="el-icon-arrow-left"></i>
          <span v-if="buttonTexts[0] !== undefined">{{ buttonTexts[0] }}</span>
        </el-button>
        <el-button
          type="primary"
          :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
          @click.native="addToTarget"
          :disabled="sourceDisabled"
        >
          <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[1] }}</span>
          <i class="el-icon-arrow-right"></i>
        </el-button>
      </div>

      <!-- 右侧穿梭框 -->
      <div class="el-transfer-panel">
        <p class="el-transfer-panel__header">
          <el-checkbox :indeterminate="targetIsIndeterminate" v-model="targetCheckAll" @change="targetAllBoxCheck">
            <template v-if="titles[1] !== undefined">{{ titles[1] }}</template>
          </el-checkbox>
          <slot name="title-right"></slot>
        </p>
        <!-- 内容区 -->
        <div class="el-transfer-panel__body">
          <el-input
            v-if="filterable"
            class="el-transfer-panel__filter"
            :placeholder="filterPlaceholder"
            v-model="filterTo"
            size="small"
            :class="{ 'el-transfer-panel__search': filterable }"
          >
            <i slot="prefix" :class="['el-input__icon', 'el-icon-search']"></i>
          </el-input>
          <dg-table
            ref="multipleTargetTable"
            border
            :data="targetData"
            paging-type="client"
            style="width: 100%"
            :header-cell-style="headerCellStyle"
            @selection-change="handleSelectionChangeTarget"
          >
            <dg-table-column type="selection"></dg-table-column>
            <dg-table-column type="index" label="序号" width="65px" align="center"></dg-table-column>
            <!-- <el-table-column
              :key="'targetId' + labelName + columnName"
              :prop="labelName"
              :label="columnName"
              show-overflow-tooltip
            >
            </el-table-column> -->

            <dg-table-column
              :prop="item.val"
              :label="item.label"
              :key="'targetId' + item.val + index"
              v-for="(item, index) in columnLabelNameList"
              show-overflow-tooltip
            >
            </dg-table-column>
            <template slot="empty">
              <div style="height: 100px">
                <p class="el-transfer-panel__empty">无数据</p>
              </div>
            </template>
          </dg-table>
          <!--<el-pagination-->
          <!--:page-size="pageSize"-->
          <!--small-->
          <!--layout="prev, pager, next"-->
          <!--:total="targetTotal">-->
          <!--</el-pagination>-->
        </div>
        <p class="el-transfer-panel__footer" v-if="$slots['right-footer']">
          <slot name="right-footer"></slot>
        </p>
      </div>
    </div>
  </div>
</template>

<script>
import _ from 'lodash';
export default {
  name: 'TransferTable',
  data() {
    return {
      // 源数据选中key数组
      sourceCheckKeys: [],
      // 目标数据选中key数组
      targetCheckKeys: [],
      // 是否半选源列表数据状态
      sourceIsIndeterminate: false,
      // 是否半选源列表数据状态
      sourceCheckAll: false,
      // 添加按钮是否禁用
      sourceDisabled: true,
      // 移除按钮是否禁用
      targetDisabled: true,
      // 是否半选目标列表数据状态
      targetIsIndeterminate: false,
      // 是否半选目标列表数据状态
      targetCheckAll: false,
      // 右侧列名字段
      columnName: String,
      // 目标列表
      targetData: [],
      // 源列表
      sourceData: [],
      // 源数据筛选
      filterFrom: '',
      // 目标数据筛选
      filterTo: '',
      // 实际源数据
      realSourceData: [],
      // 实际目标数据
      realTargetData: []
    };
  },
  props: {
    // 默认选中值
    value: {
      type: Array,
      default() {
        return [];
      }
    },
    // 值的字段名称
    valueName: {
      type: String,
      default: 'id'
    },
    // 选项配置数据
    data: {
      type: Array,
      default() {
        return [];
      }
    },
    // 是否启用筛选
    filterable: {
      type: Boolean,
      default: false
    },
    // 筛选 filter-placeholder
    filterPlaceholder: {
      type: String,
      default: '输入关键字进行过滤'
    },
    // 标题配置
    titles: {
      type: Array,
      default: () => ['列表一', '列表二']
    },
    // 表头样式设置
    headerCellStyle: {
      type: Object,
      default: () => {}
    },
    // 按钮文本配置
    buttonTexts: {
      type: Array,
      default: () => []
    },
    // 右侧显示列名字段
    labelName: {
      type: String,
      default: 'label'
    },
    // 所有列名和参数对应字段
    columnLabelNameList: {
      type: Array,
      default: () => []
    }
  },
  methods: {
    /**
     * 源列表数据全选改变状态
     *
     * @param val
     */
    sourceAllBoxCheck(val) {
      if (this.sourceData.length == 0) {
        return;
      }
      if (val) {
        this.sourceCheckKeys = this.sourceData;
        this.$refs.multipleSourceTable.toggleAllSelection();
      } else {
        this.sourceCheckKeys = [];
        this.$refs.multipleSourceTable.clearSelection();
      }
    },
    /**
     * 目标列表数据全选改变状态
     *
     * @param val
     */
    targetAllBoxCheck(val) {
      if (this.targetData.length == 0) {
        return;
      }
      if (val) {
        this.targetCheckKeys = this.targetData;
        this.$refs.multipleTargetTable.toggleAllSelection();
      } else {
        this.targetCheckKeys = [];
        this.$refs.multipleTargetTable.clearSelection();
      }
    },
    /**
     * 加入左侧穿梭框
     *
     */
    addToSource() {
      // 初始化
      let keys = this.targetCheckKeys;
      let _newValue = _.union(this.sourceData, keys);
      this.sourceData = _newValue;
      this.realSourceData = _newValue;

      let _newTarget = _.difference(this.targetData, keys);
      this.targetData = _newTarget;
      this.realTargetData = _newTarget;
      // this.toggleSelection(this.$refs.multipleSourceTable, this.sourceCheckKeys)

      // 处理完毕按钮恢复禁用状态
      this.targetCheckKeys = [];
    },
    /**
     * 加入右侧穿梭框
     *
     */
    addToTarget() {
      let keys = this.sourceCheckKeys;
      let _newValue = _.union(this.targetData, keys);
      this.targetData = _newValue;
      this.realTargetData = _newValue;

      let _newSource = _.difference(this.sourceData, keys);
      this.sourceData = _newSource;
      this.realSourceData = _newSource;

      // 处理完毕按钮恢复禁用状态
      this.sourceCheckKeys = [];
    },
    handleSelectionChangeSource(val) {
      this.sourceCheckKeys = val;
    },
    handleSelectionChangeTarget(val) {
      this.targetCheckKeys = val;
    },
    // 获取表格选中行数
    toggleSelection(refs, rows) {
      if (rows) {
        rows.forEach((row) => {
          refs.setCurrentRow(row);
        });
      } else {
        refs.clearSelection();
      }
    }
  },
  computed: {
    /**
     * 检测按钮文本值
     *
     */
    hasButtonTexts() {
      return this.buttonTexts.length === 2;
    }
  },
  watch: {
    // 源数据 状态监测
    sourceCheckKeys(val) {
      if (val.length > 0) {
        // 穿梭按钮是否禁用
        this.sourceDisabled = false;
        // 总半选是否开启
        this.sourceIsIndeterminate = true;

        // 总全选是否开启 - 根据选中节点中为根节点的数量是否和源数据长度相等
        let allCheck = val;
        if (allCheck.length == this.sourceData.length) {
          // 关闭半选 开启全选
          this.sourceIsIndeterminate = false;
          this.sourceCheckAll = true;
        } else {
          this.sourceIsIndeterminate = true;
          this.sourceCheckAll = false;
        }
      } else {
        this.sourceDisabled = true;
        this.sourceIsIndeterminate = false;
        this.sourceCheckAll = false;
      }
    },
    // 目标树数据 状态监测
    targetCheckKeys(val) {
      if (val.length > 0) {
        // 穿梭按钮是否禁用
        this.targetDisabled = false;
        // 总半选是否开启
        this.targetIsIndeterminate = true;

        // 总全选是否开启
        let allCheck = val;
        if (allCheck.length == this.targetData.length) {
          // 关闭半选 开启全选
          this.targetIsIndeterminate = false;
          this.targetCheckAll = true;
        } else {
          this.targetIsIndeterminate = true;
          this.targetCheckAll = false;
        }
      } else {
        this.targetDisabled = true;
        this.targetIsIndeterminate = false;
        this.targetCheckAll = false;
      }
    },
    // 左侧 数据筛选
    filterFrom(val) {
      if (val.length > 0) {
        
        this.sourceData = this.realSourceData.filter((item) => {
          return item[this.labelName].indexOf(val) > -1;
        });
      } else {
        this.sourceData = this.realSourceData;
      }
    },
    // 右侧 数据筛选
    filterTo(val) {
      if (val.length > 0) {
        this.targetData = this.realTargetData.filter((item) => {
          return item[this.labelName].indexOf(val) > -1;
        });
      } else {
        this.targetData = this.realTargetData;
      }
    }
  },
  created() {
    this.realSourceData = this.data;
    // if (this.data.length > 10) {
    //   this.sourceData = _.slice(this.data, 0, this.pageSize);
    // } else {
      this.sourceData = this.data;
    // }
    if (this.value.length > 0) {
        this.sourceCheckKeys = this.value.map(item => this.data.find(i => i[this.valueName]== item));
        this.addToTarget();
    }

    this.columnLabelNameList.forEach((item) => {
      if (item.val == this.labelName) {
        this.columnName = item.label;
      }
    });
  }
};
</script>

<style scoped>
</style>
