/*
 * @Author: husanfeng
 * @qq:1136014061
 * @Date: 2018-12-25 11:08:52
 * @Last Modified by: Anmin
 * @Last Modified time: 2019-06-11 11:48:37
 * @description:  业务类别树
 */
<template>
  <Row :gutter="20">
    <Col :span="12">
    <Card>
      <p slot="title">
        费用类型树
      </p>
      <div
        :class="pageClass"
        @keydown.enter="orgSearch"
      >
        <Input
          v-model="formSearch.searchVal"
          :placeholder="$t(searchInputPlaceholder)"
          @on-search="orgSearch()"
          search
        >
        </Input>
        <Tree
          v-show="!formSearch.searchVal"
          ref="treeData"
          v-bind="$attrs"
          :data="treeData"
          :show-checkbox="ShowCheckbox"
          :multiple="ShowMultiple"
          :children-key="childrenKey"
          style="overflow: auto;"
          v-on="$listeners"
          @on-check-change="checkChange"
          @on-select-change="checkChange"
        ></Tree>
        <Tree
          v-show="formSearch.searchVal"
          ref="searchTree"
          :multiple="ShowMultiple"
          :show-checkbox="ShowCheckbox"
          :children-key="childrenKey"
          :data="treeDataSearch"
          @on-check-change="handleCheckChangeSearch"
          @on-select-change="handleSelectChangeSearch"
        ></Tree>
        <Spin
          v-show="isShowLoading"
          fix
        >
          <Icon
            type="load-c"
            size="18"
            class="demo-spin-icon-load"
          ></Icon>
          <div>正在加载...</div>
        </Spin>
      </div>
    </Card>
    </Col>
    <Col :span="12">
    <Card>
      <p slot="title">
        选择的费用类型
      </p>
      <div class="fill-available-h">
        <Tree
          :data="treeDataSelect"
        ></Tree>
      </div>
    </Card>
    </Col>
  </Row>
</template>
<script>
/**
 * 业务大类(费用类别)树组件
 */
import extend from 'extend';
import { BuildCategoryTree, BuildCategoryTreeByCondition } from '../server.js';
export default {
  name: 'SelectFeeType',
  props: {
    title: {
      type: String,
      default: '选择费用类别'
    },
    searchInputPlaceholder: {
      type: String,
      default: '请输入检索内容'
    },
    len: {
      type: [String, Number]
    },
    isShowCheckbox: {
      // 是否显示复选框
      type: Boolean,
      default: false
    },
    isMultiple: {
      // 是否多选
      type: Boolean,
      default: false
    },
    hasFullPathName: {
      // 全路径
      type: Boolean,
      default: false
    },
    // true :包含选中的所有数据，false：只返回父级节点数据
    isSelectChild: {
      type: Boolean,
      default: true
    },
    itemKey: {
      type: String,
      default: 'code' // code
    },
    itemVal: {
      type: String,
      default: ''
    },
    childrenKey: {
      type: String,
      default: 'children'
    }
  },
  data() {
    return {
      isShowLoading: true,
      // selectedItem: null,
      formSearch: {
        searchVal: ''
      },
      treeData: [], // tree的展示数据
      treeDataSelect: [], // 当前已经选择的费用类型
      treeDataSearch: []
    };
  },
  computed: {
    ShowCheckbox() {
      if (this.isShowCheckbox || this.isShowCheckbox === '') {
        return true;
      } else {
        return false;
      }
    },
    pageClass() {
      return this.isShowCheckbox ? 'crc-component-ui-select-businesstype-page-checked' : '';
    },
    ShowMultiple() {
      if (this.isMultiple === '' || this.isMultiple === true) {
        return true;
      } else {
        return false;
      }
    }
  },
  created() {
    this.$emit('SetTitle', this.title);
    this.$emit('SetPageActions', [
      {
        text: '确定',
        type: 'warning',
        action: 'save',
        handle: this.saveSelect
      },
      {
        text: '关闭',
        type: 'default',
        handle: this.cancel
      }
    ]);
    this.queryAllBusinessType();
  },
  methods: {
    /**
     * 查询初始化的三层组织信息
     */
    queryAllBusinessType() {
      this.isShowLoading = true;
      BuildCategoryTree({}).then(response => {
        // 1.获取业务类别的数据
        // 2.对数据进行整理
        // 3.绑定数据渲染
        // this.treeData = this.treeHandle(response);
        if (this.isShowCheckbox) {
          this.treeData = this.treeHandle(response);
        } else {
          // 单选还是多选
          if (this.multiple) {
            this.treeData = this.selectedTreeNode(response); /// /初始化展示几级数据 并 赋值给选择树使用
          } else {
            // let id = this.item && this.item.id ? this.item.id : [];
            this.treeData = this.selectedTreeNode(response); /// /初始化展示几级数据 并 赋值给选择树使用
          }
        }
      });
      this.isShowLoading = false;
    },
    checkChange(checkNodes) {
      // this.selectedItem = checkNodes;
      this.formatCheckData(checkNodes);
      // this.$emit("selectedItem", this.selectedItem);
    },
    formatCheckData(data) {
      const ids = this.getSelectIds(data);
      if (ids.length > 0) {
        const _data = data.filter(({ code } = {}) => {
          if (ids.includes(code)) {
            return false;
          }
          return true;
        }, this);
        this.treeDataSelect = extend(true, [], _data);
      } else {
        this.treeDataSelect = extend(true, [], data);
      }
    },
    getSelectIds(data) {
      const ids = [];
      const mapFun = arr => {
        arr.forEach(item => {
          ids.push(item.code);
          if (item.children.length > 0) {
            mapFun(item.children);
          }
        });
      };
      // 只获取有children的数据
      data.forEach(item => {
        if (item.children.length > 0) {
          mapFun(item.children);
        }
      });
      return ids;
    },
    // 根据code 找出所有ID
    getIdsByCode(data) {
      // code 代表 itemVal 的内容为 code内容
      if (this.itemKey === 'code') {
        const vals = this.itemVal.length > 0 ? this.itemVal.split(',') : [];
        const selectItems = [];
        const mapFunc = arrs => {
          arrs.map(arr => {
            if (vals.includes(arr[this.itemKey])) {
              selectItems.push(arr.code);
            }
            if (arr.children.length > 0) {
              mapFunc(arr.children);
            }
          });
        };
        mapFunc(data);
        return selectItems;
      } else {
        return this.itemVal ? this.itemVal.split(',') : [];
      }
    },
    // 查询选中的数据
    handleCheckChangeSearch() {
      // data :搜索结果中选择了多少条数据,  data 为平级数据，选择多少有多少，不用取children
      this.autoCheckedTree(this.treeDataSearch);
      this.formatCheckData(this.$refs.treeData.getCheckedNodes());
    },
    // 点击元素搜索的选择
    handleSelectChangeSearch(data) {
      if (this.isShowCheckbox) return;
      this.autoSelectTree(this.treeDataSearch);
      this.checkChange(this.$refs.treeData.getSelectedNodes());
    },
    autoCheckedTree(data) {
      const self = this;
      const funcGetChild = arr => {
        arr.forEach(item => {
          const flatState = self.$refs.treeData.flatState;
          for (let i = 0; i < flatState.length; i++) {
            const node = flatState[i].node;
            const code = node.code;
            if (item.code == code) {
              self.$refs.treeData.handleCheck({ checked: item.checked, nodeKey: flatState[i].nodeKey });
              break;
            }
          }
          if (item.children.length > 0) {
            funcGetChild(item.children);
          }
        });
      };
      funcGetChild(data);
    },
    autoSelectTree(data) {
      const self = this;
      const flatState = self.$refs.treeData.flatState;
      // 数据比对
      const mapFun = params => {
        params.map(item => {
          const selectKey = flatState.filter(obj => obj.node.id === item.id);
          if (selectKey && selectKey.length > 0) {
            const sk = selectKey[0];
            const node = sk.node;
            self.$refs.treeData.$set(node, 'selected', !!item.selected);
          }
          if (item.children.length > 0) {
            mapFun(item.children);
          }
        });
      };
      mapFun(data);
    },
    checkedTreeNode(_data) {
      const ids = this.getIdsByCode(_data);
      if (ids.length <= 0) {
        return _data;
      }
      const selectEls = []; // 需要选中的数据
      const mapFun = cs => {
        return cs.map(item => {
          if (ids.includes(item.code)) {
            selectEls.push(item);
            item.checked = true;
          }
          if (item.children.length > 0) {
            item.children = mapFun(item.children);
          }
          return item;
        });
      };
      const result = mapFun(_data); // 过滤数据
      this.treeDataSelect = extend(true, [], selectEls);
      return result;
    },
    selectedTreeNode(data) {
      const ids = this.getIdsByCode(data);
      const selectItems = [];
      const mapFun = cs => {
        return cs.map(item => {
          if (ids.includes(item.code)) {
            item.selected = true;
            selectItems.push(item);
          }
          if (item.children.length > 0) {
            item.children = mapFun(item.children);
          }
          return item;
        });
      };
      const datas = mapFun(data);
      const _selectItems = extend(true, [], selectItems);
      this.treeDataSelect = _selectItems.map(item => {
        item.children = [];
        return item;
      });
      return datas;
    },
    treeHandle(data, parentNode, isExpand) {
      const self = this;
      if (data.length <= 0) return;
      const arr = data.map(element => {
        if (!element) {
          element = {};
        }
        // 给fullPathName属性赋值
        if (self.hasFullPathName || self.hasFullPathName === '') {
          if (!element.parentCode || !parentNode) {
            element.fullPathName = element.title;
            element.expand = true;
          } else {
            element.fullPathName = parentNode.fullPathName + '/' + element.title;
          }
        }
        // end
        if (element.children && element.children.length > 0) {
          element.expand = (element.level == 0 || element.level == 1) ? true : (isExpand || false);
          element.children = self.treeHandle(element.children, element, isExpand);
        } else if (element.children && element.children.length == 0) {
          element.title = `${element.title}-${element.code}`;
        } else {
          element.children = null;
        }
        return element;
      });
      const ids = this.getIdsByCode(arr);
      const selectEls = []; // 需要选中的数据
      const mapFun = cs => {
        return cs.map(item => {
          if (ids.includes(item.code)) {
            item.extend = true;
            selectEls.push(item);
            item.checked = true;
          }
          if (item.children.length > 0) {
            item.children = mapFun(item.children);
          }
          return item;
        });
      };
      mapFun(arr); // 过滤数据
      this.treeDataSelect = extend(true, [], this.treeDataSelect, selectEls);
      return arr;
    },
    // 模糊查询
    orgSearch() {
      const searchVal = this.formSearch.searchVal.trim();
      if (searchVal === '') {
        this.queryAllBusinessType();
      } else if (searchVal != '') {
        this.queryBusinessTypeForName({
          categoryNameOrCode: searchVal
        });
      }
    },
    /**
     * 根据名称查询
     */
    queryBusinessTypeForName(searchVal) {
      this.isShowLoading = true;
      BuildCategoryTreeByCondition(searchVal).then(() => {
        const results = this.searchDataByFiled(extend(true, [], this.treeData), 'title', this.formSearch.searchVal);
        this.treeDataSearch = extend(true, [], results);
      });
      this.isShowLoading = false;
    },
    searchDataByFiled(arr = [], key = '', val = '') {
      const selectItems = [];
      const searchOfKey = (datas, key, val) => {
        datas.filter(item => {
          if (item[key].indexOf(val) > -1) {
            selectItems.push(item);
            return true;
          } else {
            if (item.children.length > 0) {
              searchOfKey(item.children, key, val);
            }
          }
          return item;
        });
      };
      if (arr.length > 0 && key && val) {
        // 执行搜索后，过滤数据
        searchOfKey(arr, key, val);

        return selectItems;
      } else {
        return [];
      }
    },
    cancel() {
      this.$emit('Close');
    },
    /**
     * 选中业务类别
     * 有两种选择数据的方法
     * 1.有复选框 ，可勾选
     * 2.点击title 选中
     * 数据会有重复。
     * 默认只给 选中（1）复选框的内容
     * 如果同时设置了 勾选和选中  默认返回 复选框内容
     */
    saveSelect() {
      if (this.ShowMultiple || this.ShowCheckbox) {
        this.$emit('Close', extend(true, [], this.treeDataSelect));
      } else {
        this.$emit('Close', extend(true, {}, this.treeDataSelect[0]));
      }
    },
    // 子节点数据过滤 选中的数据包含
    getParentsNode(data) {
      function getResult(item, arr) {
        const result = [];
        arr.forEach(element => {
          if (element.parentCode !== item.code) {
            result.push(element);
          }
        });
        return result;
      }
      let result = data;
      for (var i = 0; i < result.length; i++) {
        result = getResult(result[i], result);
      }
      return result;
    }
  }
};
</script>
<style lang="less">
.crc-component-ui-select-businesstype-page-checked {
  .ivu-tree {
    ul {
      li {
        position: relative;
        line-height: 24px;
        display: inline-block;
        margin: 0px !important;
        .ivu-checkbox-wrapper {
          width: 100%;
          position: absolute;
        }
        .ivu-tree-title {
          margin-left: 15px;
        }
      }
    }
  }
}
</style>
