<template>
  <div class="sideLeftTree" ref="sideLeftTree">
    <div>
      <!-- zTree Start -->
      <ul id="sideLeftTree" class="ztree"/>
      <!-- zTree End -->
    </div>
  </div>
</template>
<script>

import {replaceNullName} from "@/utils/tree";
import AntSpinDot from "@/components/AntSpinDot/index.vue";
import {addClass, removeClass} from "@/utils";
import $ from "jquery";

export default {
  name: "LeftTree",
  components: {
    AntSpinDot,
  },
  props: {},
  data() {
    return {
      /** 加载对象 */
      loader: undefined,
      /** zTree 配置项 */
      setting: {
        data: {
          key: {
            title: "description"
          },
          simpleData: {
            enable: true,
            idKey: "id",
            pIdKey: "pid",
          }
        },
        view: {
          /** 显示 / 不显示 连线 */
          showLine: true,
          /** 显示 / 隐藏 提示信息 */
          showTitle: false,
          /** 支持 / 不支持 HTML 脚本 */
          nameIsHTML: true,
          /** 显示 / 隐藏 图标 */
          showIcon: false,
          /** 双击节点 切换 / 不切换 展开状态 */
          dblClickExpand: false,
          /** 是否允许同时选中多个节点 */
          selectedMulti: false,
          /** 是否允许可以选择 zTree DOM 内的文本 */
          txtSelectedEnable: true,
          /** 显示动画效果 */
          expandSpeed: "fast"
        },
        edit: {
          enable: true,
          drag: {
            isCopy: false,
            isMove: false,
            prev: false,
            next: false,
            inner: false
          },
          editNameSelectAll: true,
          showRenameBtn: false,
          showRemoveBtn: false,
        },
        async: {
          enable: true,
          url: "/DFMEA/mfmea/funAnalysis/rb0426314/func",
          dataType: "json",
          type: "post",
          dataFilter: this.handleDataFilter
        },
        callback: {
          beforeClick: this.handleBeforeClick,
          beforeRightClick: this.handleBeforeRightClick,
          beforeAsync: this.handleBeforeAsync,
          onAsyncSuccess: this.handleOnAsyncSuccess,
        }
      },
    };
  },
  watch: {},
  created() {
  },
  mounted() {
  },
  methods: {
    /******************************************* zTree Start **************************************************/
    /**
     * 初始化左侧树
     */
    initLeftTree(zNodes = []) {
      let _that = this;
      let settings = $.extend({}, _that.setting);
      settings.view.fontCss = _that.setNodeFontCss;
      settings.view.showTitle = true; // 设置鼠标移入显示
      settings.async.contentType = "application/json";
      settings.async.otherParam = {
        fmeaId: _that.$store.getters.sideRfmeaId,
      };
      // 初始化ztree
      $.fn.zTree.init($("#sideLeftTree"), settings, zNodes);
    },
    /**
     * 用于对 Ajax 返回数据进行预处理的函数
     * @param treeId
     * @param parentNode
     * @param responseData
     */
    handleDataFilter(treeId, parentNode, responseData) {
      let childNodes = responseData.data.mfmeaStruTreeModels;
      for (let i = 0, l = childNodes.length; i < l; i++) {
        let node = childNodes[i];
        // 设置【description】为节点的title
        node['description'] = replaceNullName(node);
        node.name = this.getNodeName(node);
      }
      return childNodes;
    },
    /**
     * 用于捕获单击节点之前的事件回调函数，并且根据返回值确定是否允许单击操作
     * @param treeId
     * @param treeNode
     * @param clickFlag
     */
    handleBeforeClick(treeId, treeNode, clickFlag) {
      let _that = this;
      // 当前节点已选中, 防止右侧树多次刷新
      if (_that.$store.getters.sideCheckedLeftNode?.id !== treeNode.id) {
        // 处理选中ZTree节点
        this.handleSelectZTreeNodes(treeId, [treeNode]);
        // 刷新右侧树
        this.initRightTree();
      }
      // 存储当前节点信息
      this.setCheckedNode(treeNode);
    },
    /**
     * 用于捕获 zTree 上鼠标右键点击之前的事件回调函数，并且根据返回值确定触发 onRightClick 事件回调函数
     * @param treeId
     * @param treeNode
     */
    handleBeforeRightClick(treeId, treeNode) {
      // 右键非节点时，忽略
      if (!treeNode) return;
      let _that = this;
      // 当前节点已选中, 防止右侧树多次刷新
      if (_that.$store.getters.sideCheckedLeftNode?.id !== treeNode.id) {
        // 处理选中ZTree节点
        this.handleSelectZTreeNodes(treeId, [treeNode]);
        // 刷新右侧树
        this.initRightTree();
      }
      // 存储当前节点信息
      this.setCheckedNode(treeNode);
      // 获取右键菜单项
      let bthMenuBtn = this.getMenuBtn();
      // 处理右键菜单
      this.handleContextMenu(treeNode, bthMenuBtn);
    },
    /**
     * 用于捕获异步加载之前的事件回调函数，zTree 根据返回值确定是否允许进行异步加载
     * @param treeId
     * @param treeNode
     */
    handleBeforeAsync(treeId, treeNode) {
      // 开启加载...
      this.handleShowHideLoading(true);
    },
    /**
     * 用于捕获异步加载正常结束的事件回调函数
     * 如果设置了 setting.callback.beforeAsync 方法，且返回 false，
     * 将无法触发 onAsyncSuccess / onAsyncError 事件回调函数。
     */
    handleOnAsyncSuccess(event, treeId, treeNode, msg) {
      let _that = this;
      // 处理选中ZTree节点
      let nodes = [_that.$store.getters.sideCheckedLeftNode];
      _that.handleSelectZTreeNodes(treeId, nodes);
      // 关闭加载...
      _that.handleShowHideLoading(false);
    },
    /**
     * 取得节点名称
     * @param node
     * @returns {string}
     */
    getNodeName(node) {
      let nodeName = '&nbsp;';
      // 附件标识 0：无，1：有
      if (node.annexFlag === '1') {
        nodeName += "<i class='iconfont iconshuxing1' onclick='handleAnnexLIconClick(\"" + node.id + "\")'></i>" + "&nbsp;";
      }
      // 评审意见
      if (node.hasStruComment) {
        nodeName += `<i class="iconfont iconxiaoxi_right"></i>` + '&nbsp;';
      }
      nodeName += node.description;
      return nodeName;
    },
    /**
     * 设置功能、失效、要求和产品特征字体着色
     * @param treeId
     * @param treeNode
     * @returns {*}
     */
    setNodeFontCss(treeId, treeNode) {
      return this.$store.getters.nodeTypeDict.zTreeLNodeColor[treeNode.struTypeCode];
    },
    /**
     * 选中ztree节点
     * @param treeId
     * @param nodes
     */
    handleSelectZTreeNodes(treeId, nodes) {
      let treeObj = $.fn.zTree.getZTreeObj(treeId);
      for (let i = 0; i < nodes.length; i++) {
        let node = treeObj.getNodeByParam("id", nodes[i]?.id, null);
        if (node) {
          treeObj.selectNode(node);
          // 重新赋值，保持缓存节点数据一致
          this.setCheckedNode(node);
        }
      }
    },
    /**
     * 单级折叠/展开
     */
    collapseExpand() {
      let _that = this;
      let checkedNode = _that.$store.getters.sideLastCheckedNode;
      let treeObj = $.fn.zTree.getZTreeObj('sideLeftTree');
      treeObj.expandNode(checkedNode, !checkedNode?.open, true, true);
    },
    /**
     * 全部折叠/展开
     */
    collapseExpandAll() {
      let _that = this;
      let checkedNode = _that.$store.getters.sideLastCheckedNode;
      let treeObj = $.fn.zTree.getZTreeObj('sideLeftTree');
      let nodes = treeObj.getNodesByParam("level", checkedNode.level, null);
      let expandFlag = checkedNode?.open;
      for (let i = 0, len = nodes.length; i < len; i++) {
        // 聚焦当前选中节点
        treeObj.expandNode(nodes[i], !expandFlag, true, checkedNode.id === nodes[i].id);
      }
    },
    /**
     * 显示、隐藏 -- 加载Loading
     * @param flag
     */
    handleShowHideLoading(flag) {
      if (flag) {
        if (this.loader) this.loader.hide();
        this.loader = this.$loading.show({
          container: this.$refs.sideLeftTree,
          color: '#1890FF',
        }, {
          // 自定义加载动画组件
          default: this.$createElement('ant-spin-dot'),
        });
      } else {
        this.loader.hide();
      }
    },
    /******************************************* zTree End **************************************************/

    /******************************************* 右键菜单 Start **************************************************/
    /**
     * 取得当前节点的右键菜单项
     */
    getCurrentNodeMenus(node) {
      let data = {};
      this.$emit('getCurrentNodeMenus', node, "sideLeftTree", val => {
        data = val;
      })
      return data;
    },
    /**
     * 获取右键菜单项
     */
    getMenuBtn() {
      return {
        "copy": {name: this.$t('global-constant.contextmenu.copy'), icon: "fas iconfont iconfuzhi4"},
        "sep": "---------",
        "collapseExpand": {
          name: this.$t('global-constant.contextmenu.collapse-expand'),
          icon: "fas iconfont iconzhedie2"
        },
        "collapseExpandAll": {
          name: this.$t('global-constant.contextmenu.collapse-expand-all'),
          icon: "fas iconfont iconzhedie111"
        },
      };
    },
    /**
     * 处理右键菜单
     * @param node 节点
     * @param items 菜单项
     */
    handleContextMenu(node, items) {
      let _that = this;
      // 隐藏上次菜单
      let selector = '#' + node.tId + '_a'
      jQuery.contextMenu('destroy', selector);
      jQuery.contextMenu({
        selector: selector,
        autoHide: true,
        zIndex: 10,
        items: items,
        callback: function (itemKey, opt) {
          let actionInfo = {key: itemKey};
          _that.menuAction(actionInfo);
        },
      });
    },
    /**
     * 右键菜单事件
     * @param actionInfo 菜单项信息
     */
    menuAction(actionInfo) {
      switch (actionInfo.key) {
        case "copy": // 复制
          this.setHighLightCopyCutNode("copy");
          break;
        case "collapseExpand": // 折叠/展开
          this.collapseExpand();
          break;
        case "collapseExpandAll": // 全部折叠/展开
          this.collapseExpandAll();
          break;
      }
    },
    /******************************************* 右键菜单 End **************************************************/

    /******************************************* 父组件方法 Start **************************************************/
    /**
     * 初始化：右侧结构树
     */
    initRightTree() {
      this.$emit("initRightTree");
    },
    /******************************************* 父组件方法 End **************************************************/
    /**
     * 存储当前节点信息
     */
    setCheckedNode(node) {
      this.$store.dispatch("fmeaTree/set", {
        key: "sideCheckedLeftNode",
        value: node
      });
      this.$store.dispatch("fmeaTree/set", {
        key: "sideLastCheckedNode",
        value: node
      });
    },
    /**
     * 设置：复制/剪切时，节点高亮
     * @param cutCopy 'copy'、'cut'
     */
    setHighLightCopyCutNode(cutCopy) {
      let sideLastCheckedNode = this.$store.getters.sideLastCheckedNode;
      if (!sideLastCheckedNode) return;
      this.clearHighLightCopyCutNode();
      addClass(document.getElementById(sideLastCheckedNode.tId + '_a'), "curCopyCutNode");
      this.$store.dispatch("fmeaTree/set", {
        key: "lastCopyOrCutNode",
        value: sideLastCheckedNode
      });
      // 存储操作树标识位：leftTree or rightTree
      this.$store.dispatch("fmeaTree/set", {
        key: "lastCopyOrCutLRTreeFlag",
        value: 'sideLeftTree'
      });
      // 存储操作类型标识位：复制=copy or 剪切=cut
      this.$store.dispatch("fmeaTree/set", {
        key: "lastCopyOrCut",
        value: cutCopy
      });
    },
    /**
     * 清除：复制/剪切时，节点高亮
     */
    clearHighLightCopyCutNode() {
      let lastCopyOrCutNode = this.$store.getters.lastCopyOrCutNode;
      let treeId = lastCopyOrCutNode?.tId.split('_')[0];
      if (lastCopyOrCutNode && treeId) {
        let treeObj = $.fn.zTree.getZTreeObj(treeId);
        let node = treeObj.getNodeByParam("id", lastCopyOrCutNode?.id, null);
        if (node) {
          removeClass(document.getElementById(node.tId + '_a'), "curCopyCutNode");
        }
        this.$store.dispatch("fmeaTree/clearCopyOrCut");
      }
    },
  },
};
</script>
<style lang="less" scoped>

@import "~@/styles/zTree";

</style>
