<!--下拉树el-select+el-tree -->
<template>
  <el-select
    ref="select"
    popper-class="TREE_SELECT_POPPER"
    :value="showLabel"
    :size="size"
    allow-create
    :default-first-option="true"
    :placeholder="placeholder"
    :clearable="clearable"
    :disabled="disabled"
    :filterable="filterable"
    :filter-method="selectFilter"
    @visible-change="visibleChange"
    @change="selectChange"
    @focus="selectFocus"
    @clear="clearSelect"
  >
    <el-option class="option_li" :style="{height: optionHeight+'px'}" :value="showLabel" :label="showLabel">
      <el-scrollbar class="option_li_scroll">
        <el-tree
          ref="tree"
          show-checkbox
          :accordion="accordion"
          :data="options"
          :props="props"
          :node-key="props.value"
          :show-checkbox="multiple"
          :render-content="renderContent"
          :default-expand-all="defaultExpandAll"
          :default-expanded-keys="defaultExpanded"
          :default-checked-keys="(multiple && Array.isArray(value)) ? value : []"
          :expand-on-click-node="false"
          :check-strictly="checkStrictly"
          :filter-node-method="treeFilter"
          empty-text=""
          @node-click="nodeClick"
          @check-change="nodeCheck"
        />
        <!--        <el-button v-if="!options.length" type="primary" plain size="small" @click="addNode">+</el-button>-->
      </el-scrollbar>
    </el-option>
  </el-select>
</template>
<script type="es6">
let value = 1000
export default {
  name: 'VElTreeSelect',
  props: {
    props: { // 配置项
      type: Object,
      default() {
        return {
          value: 'value',
          label: 'label',
          children: 'children'
        }
      }
    },
    options: { // 选项列表数据
      type: Array,
      default() {
        return []
      }
    },
    multiple: { // 是否可多选
      type: Boolean,
      default: false
    },
    value: { // 绑定值
      type: [String, Number, Array],
      default() {
        return this.multiple ? [] : ''
      }
    },
    accordion: { // 是否每次只展开一个同级树节点
      type: Boolean,
      default: false
    },
    size: String,
    filterable: { // 是否可搜索
      type: Boolean,
      default: false
    },
    clearable: { // 是否可清空
      type: Boolean,
      default: true
    },
    disabled: { // 是否禁用
      type: Boolean,
      default: false
    },
    placeholder: String,
    checkStrictly: { // 父子是否不互相关联
      type: Boolean,
      default: false
    },
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    defaultExpandedKeys: {
      type: Array,
      default() { return [] }
    }
  },
  data() {
    return {
      newChild: [],
      curNode: '',
      optionHeight: 247 // el-option高度
    }
  },
  computed: {
    showLabel() {
      let label = {
        a: '',
        b: ''
      }
      const value = this.value
      if (this.multiple) { // 多选
        if (Array.isArray(value) && value.length > 0) {
          const labelArr = []
          const a = []
          const b = []
          value.forEach(value => {
            if (value.self) {
              labelArr.push({ a: value.label })
            } else {
              labelArr.push(this.queryTree(this.options, value))
            }
          })
          labelArr.forEach(item => {
            a.push(item.a)
            b.push(item.b)
          })
          label.a = a.join(',')
          label.b = b.join(',')
        }
      } else { // 单选
        if (value) {
          label = this.queryTree(this.options, value)
        }
      }
      this.$emit('handleNode', label.a)
      return label.a
    },
    // 默认展开
    defaultExpanded() {
      let keys = []
      if (this.value) {
        keys = (this.multiple && Array.isArray(this.value)) ? this.value : [this.value]
      } else {
        keys = this.defaultExpandedKeys
      }
      return keys
    }
  },
  methods: {
    // 搜索树状数据中的 ID,获取label
    queryTree(tree, id) {
      let stark = []
      stark = stark.concat(tree)
      const label = {
        a: '',
        b: ''
      }
      while (stark.length) {
        const temp = stark.shift()
        if (temp[this.props.children]) {
          stark = stark.concat(temp[this.props.children])
        }
        if (temp[this.props.value] === id) {
          label.a = temp[this.props.label]
          label.b = temp[this.props.value]
        }
      }
      return label
    },
    clearSelect(val) {
      if (!val) {
        val = this.multiple ? [] : ''
      }
      this.newChild = []
      this.$emit('input', val)
    },
    // queryTree(tree, id) {
    //   let stark = []
    //   stark = stark.concat(tree)
    //   let label = ''
    //   while (stark.length) {
    //     const temp = stark.shift()
    //     if (temp[this.props.children]) {
    //       stark = stark.concat(temp[this.props.children])
    //     }
    //     if (temp[this.props.value] === id) {
    //       label = temp[this.props.label]
    //     }
    //   }
    //   return label
    // },
    // 提交值
    emitVal(val) {
      if (!val) {
        val = this.multiple ? [] : ''
      }
      this.$emit('input', val)
    },
    // select框获得焦点
    selectFocus() {
      this.$refs.tree.filter('')
    },
    // 下拉框出现/隐藏
    visibleChange(show) {
      this.$refs.tree.filter('')
      if (show) {
        this.$nextTick(() => {
          const tree_H = this.$refs.tree.$el.clientHeight
          if (tree_H < this.optionHeight) {
            this.optionHeight = tree_H
          }
        })
      }
    },
    // select option过滤
    selectFilter(label) {
      this.$refs.tree.filter(label)
      return true
    },
    // 树过滤方法
    treeFilter(query, data) {
      if (!query) {
        return true
      } else {
        const labelArray = query.split(',')
        return labelArray.some(value => {
          return value && data[this.props.label].includes(value)
        })
      }
    },
    selectChange(node) {
      const newChild = { value: value++, label: node, self: 999, children: [] }
      const keys = this.$refs.tree.getCheckedKeys()
      this.newChild = this.newChild.concat([newChild])
      const news = keys.concat(this.newChild)
      this.emitVal(news)
    },
    // 点击节点
    nodeClick(node) {
      if (!this.multiple) {
        this.emitVal(node[this.props.value])
        this.$refs.select.blur() // 使select失去焦点 隐藏下拉框
      }
    },
    // 点击复选框
    nodeCheck() {
      const keys = this.$refs.tree.getCheckedKeys()
      const news = keys.concat(this.newChild)
      this.emitVal(news)
    },
    append(data) {
      this.$emit('add', data)
    },
    remove(data) {
      this.$emit('remove', data)
    },
    renderContent(h, { node, data, store }) {
      if (node.label === '公共' || node.label === '个人') {
        return (
          <span style='flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px;'>
            <span>
              <span>{node.label}</span>
            </span>
            <span>
              <el-button icon='el-icon-plus' style='font-size: 12px;color: #409EFF' type='text' on-click={ () => this.append(data) }></el-button>
            </span>
          </span>)
      } else {
        return (
          <span style='flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px;'>
            <span>
              <span>{node.label}</span>
            </span>
            <span>
              <el-button icon='el-icon-plus' style='font-size: 12px;color: #409EFF' type='text' on-click={ () => this.append(data) }></el-button>
              <el-button icon='el-icon-delete' style='font-size: 12px;color: #F56C6C' type='text' on-click={ () => this.remove(data) }></el-button>
            </span>
          </span>)
      }
    }
  }
}
</script>

<style lang="scss" type="text/scss">
.el-scrollbar__wrap{
  background-color: white;
}
.TREE_SELECT_POPPER>.el-scrollbar {
  >.el-scrollbar__bar.is-vertical {
    .el-scrollbar__thumb,.el-scrollbar__thumb:hover {
      background-color: transparent;
    }
  }
}
</style>

<style scoped lang="scss" type="text/scss">
.el-select-dropdown__item{
  height: 175px !important;
}
.option_li {
  padding: 0;
  &.selected {
    font-weight: normal;
  }
  .option_li_scroll {
    height: 100%;
    .el-scrollbar__wrap{
      overflow-x: hidden;
    }
  }
}
.el-tree {
  box-sizing: border-box;
  padding: 0 12px;
}
</style>
