From d7fe3b19ab7a906b30ad8ba73e6cd56cb5deedef Mon Sep 17 00:00:00 2001
From: ZZJ <zzjdsg2300@163.com>
Date: 星期一, 20 十二月 2021 19:12:09 +0800
Subject: [PATCH] 搜索

---
 src/components/giantTree/zTree/ztree.vue |  341 +++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 286 insertions(+), 55 deletions(-)

diff --git a/src/components/giantTree/zTree/ztree.vue b/src/components/giantTree/zTree/ztree.vue
index b8e5024..147ccec 100644
--- a/src/components/giantTree/zTree/ztree.vue
+++ b/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) => {
@@ -59,6 +69,7 @@
           },
           onClick: (...arg) => {
             this.$emit("onClick", ...arg);
+            this.removeHoverIcon(...arg);
           },
           onCollapse: (...arg) => {
             this.$emit("onCollapse", ...arg);
@@ -95,6 +106,10 @@
           },
         },
       },
+      keyWord: "",
+      options: {
+        target: "",
+      },
     };
   },
   watch: {
@@ -112,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);
         });
       },
@@ -120,6 +137,10 @@
     },
     showCheckbox: {
       handler: function () {
+        let top = $("#" + this.ztreeId)
+          .parent()
+          .scrollTop();
+
         this.ztreeSetting.check.enable = this.showCheckbox;
 
         if (this.ztreeObj) {
@@ -132,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) {
@@ -144,119 +168,311 @@
       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");
+        btn.id = `${treeid}_${treeNode.id}_btn`;
+        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();
+          // this.clickRemove(treeNode)
+          _vue.$emit("onShowPic", treeNode);
+        });
 
         item.appendChild(btn);
       }
     },
+    removeHoverIcon(evt, treeId, item) {
+      this.removeHoverDom(treeId, item);
+    },
     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");
+        if (btn) {
+          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>
 
@@ -591,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>
\ No newline at end of file

--
Gitblit v1.8.0