ZZJ
2021-12-20 d7fe3b19ab7a906b30ad8ba73e6cd56cb5deedef
src/components/giantTree/zTree/ztree.vue
@@ -1,15 +1,25 @@
<template>
  <div class="ztree" :id="ztreeId"></div>
  <div>
    <div class="search">
      <el-input placeholder="搜索" v-model="keyWord">
        <i slot="suffix" class="el-input__icon el-icon-search" id="key"></i>
      </el-input>
    </div>
    <div class="ztree" :id="ztreeId"></div>
  </div>
</template>
<script>
import * as $ from "jquery";
import { Loading } from "element-ui";
if (!window.jQuery) {
  window.jQuery = $;
}
// require("@ztree/ztree_v3/js/jquery.ztree.all");
require("./ztree_v3/jquery.ztree.all");
require("./ztree_v3/jquery.ztree.exhide");
export default {
  props: {
@@ -41,11 +51,11 @@
          showLine: true,
          showIcon: true, // default to hide icon
          addHoverDom: this.addHoverDom,
          removeHoverDom: this.removeHoverDom
          removeHoverDom: this.removeHoverDom,
        },
        check: {
          chkboxType: { "Y": "", "N": "" },
          enable: this.showCheckbox
          chkboxType: { Y: "", N: "" },
          enable: this.showCheckbox,
        },
        callback: {
          onAsyncError: (...arg) => {
@@ -84,7 +94,6 @@
          },
          onMouseUp: (...arg) => {
            this.$emit("onMouseUp", ...arg);
          },
          onRemove: (...arg) => {
            this.$emit("onRemove", ...arg);
@@ -96,6 +105,10 @@
            this.$emit("onRightClick", ...arg);
          },
        },
      },
      keyWord: "",
      options: {
        target: "",
      },
    };
  },
@@ -114,6 +127,8 @@
            Object.assign({}, this.ztreeSetting, this.setting),
            this.list
          );
          console.log("---------");
          this.fuzzySearch(this.ztreeObj, "#key", null, true); //初始化模糊搜索方法
          this.$emit("onCreated", this.ztreeObj);
        });
      },
@@ -122,6 +137,10 @@
    },
    showCheckbox: {
      handler: function () {
        let top = $("#" + this.ztreeId)
          .parent()
          .scrollTop();
        this.ztreeSetting.check.enable = this.showCheckbox;
        if (this.ztreeObj) {
@@ -134,11 +153,14 @@
            Object.assign({}, this.ztreeSetting, this.setting),
            this.list
          );
          $("#" + this.ztreeId)
            .parent()
            .scrollTop(top);
          this.$emit("onCreated", this.ztreeObj);
        });
      },
      immediate: true,
    }
    },
  },
  methods: {
    addHoverDom(treeid, treeNode) {
@@ -146,103 +168,137 @@
      const item = document.getElementById(`${treeNode.tId}_a`);
      // 文件夹新增按钮
      if (item && !item.querySelector('.el-icon-circle-plus-outline') && treeNode.isParent && !this.readonly && !this.gb28181) {
        const btn = document.createElement('i');
      if (
        item &&
        !item.querySelector(".el-icon-circle-plus-outline") &&
        treeNode.isParent &&
        !this.readonly &&
        !this.gb28181
      ) {
        const btn = document.createElement("i");
        btn.id = `${treeid}_${treeNode.id}_btn`;
        btn.classList.add('el-icon-circle-plus-outline');
        btn.classList.add('primary');
        btn.classList.add("el-icon-circle-plus-outline");
        btn.classList.add("primary");
        // btn.innerText = '删除';
        btn.addEventListener('click', (e) => {
          e.stopPropagation()
        btn.addEventListener("click", (e) => {
          e.stopPropagation();
          // this.clickRemove(treeNode)
          _vue.$emit("onAddNode", treeNode);
        })
        });
        item.appendChild(btn);
      }
      // 文件夹删除按钮
      if (item && !item.querySelector('.el-icon-remove-outline') && treeNode.isParent && !this.readonly && !treeNode.children && !this.gb28181) {
        const btn = document.createElement('i');
      if (
        item &&
        !item.querySelector(".el-icon-remove-outline") &&
        treeNode.isParent &&
        !this.readonly &&
        !treeNode.children &&
        !this.gb28181
      ) {
        const btn = document.createElement("i");
        btn.id = `${treeid}_${treeNode.id}_btn`;
        btn.classList.add('el-icon-remove-outline');
        btn.classList.add('danger');
        btn.classList.add("el-icon-remove-outline");
        btn.classList.add("danger");
        // btn.innerText = '删除';
        btn.addEventListener('click', (e) => {
          e.stopPropagation()
        btn.addEventListener("click", (e) => {
          e.stopPropagation();
          // this.clickRemove(treeNode)
          _vue.$emit("onRemoveNode", treeNode);
        })
        });
        item.appendChild(btn);
      }
      // 文件夹编辑按钮
      if (item && !item.querySelector('.el-icon-edit') && treeNode.isParent && !this.readonly) {
        const btn = document.createElement('i');
      if (
        item &&
        !item.querySelector(".el-icon-edit") &&
        treeNode.isParent &&
        !this.readonly
      ) {
        const btn = document.createElement("i");
        btn.id = `${treeid}_${treeNode.id}_btn`;
        btn.classList.add('el-icon-edit');
        btn.classList.add('primary');
        btn.classList.add("el-icon-edit");
        btn.classList.add("primary");
        // btn.innerText = '删除';
        btn.addEventListener('click', (e) => {
          e.stopPropagation()
        btn.addEventListener("click", (e) => {
          e.stopPropagation();
          // this.clickRemove(treeNode)
          _vue.$emit("onRenameNode", treeNode);
        })
        });
        item.appendChild(btn);
      }
      // 添加摄像机按钮
      if (item && !item.querySelector('.iconshishishipin') && treeNode.isParent && !this.readonly && !this.gb28181) {
        const btn = document.createElement('i');
      if (
        item &&
        !item.querySelector(".iconshishishipin") &&
        treeNode.isParent &&
        !this.readonly &&
        !this.gb28181
      ) {
        const btn = document.createElement("i");
        btn.id = `${treeid}_${treeNode.id}_btn`;
        btn.classList.add('iconfont');
        btn.classList.add('iconshishishipin');
        btn.classList.add('primary');
        btn.classList.add('icon-fix');
        btn.classList.add("iconfont");
        btn.classList.add("iconshishishipin");
        btn.classList.add("primary");
        btn.classList.add("icon-fix");
        // btn.innerText = '删除';
        btn.addEventListener('click', (e) => {
          e.stopPropagation()
        btn.addEventListener("click", (e) => {
          e.stopPropagation();
          // this.clickRemove(treeNode)
          _vue.$emit("onAddDevice", treeNode.id);
        })
        });
        item.appendChild(btn);
      }
      // 导入摄像机按钮
      if (item && !item.querySelector('.icondaoru') && treeNode.isParent && !this.readonly && !this.gb28181) {
        const btn = document.createElement('i');
      if (
        item &&
        !item.querySelector(".icondaoru") &&
        treeNode.isParent &&
        !this.readonly &&
        !this.gb28181
      ) {
        const btn = document.createElement("i");
        btn.id = `${treeid}_${treeNode.id}_btn`;
        btn.classList.add('iconfont');
        btn.classList.add('icondaoru');
        btn.classList.add('primary');
        btn.classList.add('icon-fix');
        btn.classList.add("iconfont");
        btn.classList.add("icondaoru");
        btn.classList.add("primary");
        btn.classList.add("icon-fix");
        // btn.innerText = '删除';
        btn.addEventListener('click', (e) => {
          e.stopPropagation()
        btn.addEventListener("click", (e) => {
          e.stopPropagation();
          // this.clickRemove(treeNode)
          _vue.$emit("onImport", treeNode.id);
        })
        });
        item.appendChild(btn);
      }
      // 查看底图按钮
      if (item && !item.querySelector('.icontupian1') && treeNode.type == "camera") {
        const btn = document.createElement('i');
      if (
        item &&
        !item.querySelector(".icontupian1") &&
        treeNode.type == "camera"
      ) {
        const btn = document.createElement("i");
        btn.id = `${treeid}_${treeNode.id}_btn`;
        btn.classList.add('iconfont');
        btn.classList.add('icontupian1');
        btn.classList.add('primary');
        btn.classList.add('icon-fix');
        btn.classList.add("iconfont");
        btn.classList.add("icontupian1");
        btn.classList.add("primary");
        btn.classList.add("icon-fix");
        // btn.innerText = '删除';
        btn.addEventListener('click', (e) => {
          e.stopPropagation()
        btn.addEventListener("click", (e) => {
          e.stopPropagation();
          // this.clickRemove(treeNode)
          _vue.$emit("onShowPic", treeNode);
        })
        });
        item.appendChild(btn);
      }
@@ -253,38 +309,170 @@
    removeHoverDom(treeid, treeNode) {
      const item = document.getElementById(`${treeNode.tId}_a`);
      if (item) {
        let btn = item.querySelector('.el-icon-circle-plus-outline');
        let btn = item.querySelector(".el-icon-circle-plus-outline");
        if (btn) {
          item.removeChild(item.querySelector('.el-icon-circle-plus-outline'))
          item.removeChild(item.querySelector(".el-icon-circle-plus-outline"));
        }
        btn = item.querySelector('.el-icon-remove-outline');
        btn = item.querySelector(".el-icon-remove-outline");
        if (btn) {
          item.removeChild(item.querySelector('.el-icon-remove-outline'))
          item.removeChild(item.querySelector(".el-icon-remove-outline"));
        }
        btn = item.querySelector('.el-icon-edit');
        btn = item.querySelector(".el-icon-edit");
        if (btn) {
          item.removeChild(item.querySelector('.el-icon-edit'))
          item.removeChild(item.querySelector(".el-icon-edit"));
        }
        btn = item.querySelector('.iconshishishipin');
        btn = item.querySelector(".iconshishishipin");
        if (btn) {
          item.removeChild(item.querySelector('.iconshishishipin'))
          item.removeChild(item.querySelector(".iconshishishipin"));
        }
        btn = item.querySelector('.icondaoru');
        btn = item.querySelector(".icondaoru");
        if (btn) {
          item.removeChild(item.querySelector('.icondaoru'))
          item.removeChild(item.querySelector(".icondaoru"));
        }
        btn = item.querySelector('.icontupian1');
        btn = item.querySelector(".icontupian1");
        if (btn) {
          item.removeChild(item.querySelector('.icontupian1'))
          item.removeChild(item.querySelector(".icontupian1"));
        }
      }
    },
  }
    fuzzySearch(zTreeObj, searchField, isHighLight, isExpand) {
      const _this = this;
      if (!zTreeObj) {
        alert("fail to get ztree object");
      }
      var nameKey = zTreeObj.setting.data.key.name; //get the key of the node name
      isHighLight = isHighLight === false ? false : true; //default true, only use false to disable highlight
      isExpand = isExpand ? true : false; // not to expand in default
      zTreeObj.setting.view.nameIsHTML = isHighLight; //allow use html in node name for highlight use
      var metaChar = "[\\[\\]\\\\^\\$\\.\\|\\?\\*\\+\\(\\)]"; //js meta characters
      var rexMeta = new RegExp(metaChar, "gi"); //regular expression to match meta characters
      // keywords filter function
      function ztreeFilter(zTreeObj, _keywords, callBackFunc) {
        if (!_keywords) {
          _keywords = ""; //default blank for _keywords
        }
        // function to find the matching node
        function filterFunc(node) {
          if (node && node.oldname && node.oldname.length > 0) {
            node[nameKey] = node.oldname; //recover oldname of the node if exist
          }
          zTreeObj.updateNode(node); //update node to for modifications take effect
          if (_keywords.length == 0) {
            //return true to show all nodes if the keyword is blank
            zTreeObj.showNode(node);
            zTreeObj.expandNode(node, isExpand);
            return true;
          }
          //transform node name and keywords to lowercase
          if (
            node[nameKey] &&
            node[nameKey].toLowerCase().indexOf(_keywords.toLowerCase()) != -1
          ) {
            if (isHighLight) {
              //highlight process
              //a new variable 'newKeywords' created to store the keywords information
              //keep the parameter '_keywords' as initial and it will be used in next node
              //process the meta characters in _keywords thus the RegExp can be correctly used in str.replace
              var newKeywords = _keywords.replace(rexMeta, function (matchStr) {
                //add escape character before meta characters
                return "\\" + matchStr;
              });
              node.oldname = node[nameKey]; //store the old name
              var rexGlobal = new RegExp(newKeywords, "gi"); //'g' for global,'i' for ignore case
              //use replace(RegExp,replacement) since replace(/substr/g,replacement) cannot be used here
              node[nameKey] = node.oldname.replace(
                rexGlobal,
                function (originalText) {
                  //highlight the matching words in node name
                  var highLightText =
                    '<span style="color: whitesmoke;background-color: darkred;">' +
                    originalText +
                    "</span>";
                  return highLightText;
                }
              );
              zTreeObj.updateNode(node); //update node for modifications take effect
            }
            zTreeObj.showNode(node); //show node with matching keywords
            return true; //return true and show this node
          }
          zTreeObj.hideNode(node); // hide node that not matched
          return false; //return false for node not matched
        }
        var nodesShow = zTreeObj.getNodesByFilter(filterFunc); //get all nodes that would be shown
        processShowNodes(nodesShow, _keywords); //nodes should be reprocessed to show correctly
      }
      /**
       * reprocess of nodes before showing
       */
      function processShowNodes(nodesShow, _keywords) {
        if (nodesShow && nodesShow.length > 0) {
          //process the ancient nodes if _keywords is not blank
          if (_keywords.length > 0) {
            $.each(nodesShow, function (n, obj) {
              var pathOfOne = obj.getPath(); //get all the ancient nodes including current node
              if (pathOfOne && pathOfOne.length > 0) {
                //i < pathOfOne.length-1 process every node in path except self
                for (var i = 0; i < pathOfOne.length - 1; i++) {
                  zTreeObj.showNode(pathOfOne[i]); //show node
                  zTreeObj.expandNode(pathOfOne[i], true); //expand node
                }
              }
            });
          } else {
            //show all nodes when _keywords is blank and expand the root nodes
            var rootNodes = zTreeObj.getNodesByParam("level", "0"); //get all root nodes
            $.each(rootNodes, function (n, obj) {
              zTreeObj.expandNode(obj, true); //expand all root nodes
            });
          }
        }
      }
      //listen to change in input element
      $(searchField).bind("click", function () {
        _this.options.target = document.querySelector(
          "#" + _this.ztreeId
        ).parentNode.parentNode;
        console.log(_this.options.target);
        let loadingInstance = Loading.service(_this.options);
        console.log(_this.keyWord);
        // var _keywords = $(this).val();
        searchNodeLazy(_this.keyWord); //call lazy load
        loadingInstance.close();
      });
      var timeoutId = null;
      var lastKeyword = "";
      // excute lazy load once after input change, the last pending task will be cancled
      function searchNodeLazy(_keywords) {
        if (timeoutId) {
          //clear pending task
          clearTimeout(timeoutId);
        }
        timeoutId = setTimeout(function () {
          if (lastKeyword === _keywords) {
            return;
          }
          ztreeFilter(zTreeObj, _keywords); //lazy load ztreeFilter function
          // $(searchField).focus();//focus input field again after filtering
          lastKeyword = _keywords;
        }, 500);
      }
    },
  },
};
</script>
@@ -619,3 +807,18 @@
  position: absolute;
}
</style>
<style scoped lang="scss">
.search {
  width: 300px;
  ::v-deep .el-input__suffix {
    right: 0;
    width: 50px;
    background: skyblue;
    color: #fff;
    cursor: pointer;
    background-color: rgb(61, 104, 255);
  }
}
</style>