From e37e45cfe1123928dba5d9c5a427b0ee497b7ad6 Mon Sep 17 00:00:00 2001 From: zhangzengfei <zhangzengfei@smartai.com> Date: 星期二, 23 八月 2022 03:21:32 +0800 Subject: [PATCH] 修复算法配置的字段内容 --- src/components/giantTree/zTree/ztree.vue | 477 ++++++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 325 insertions(+), 152 deletions(-) diff --git a/src/components/giantTree/zTree/ztree.vue b/src/components/giantTree/zTree/ztree.vue index c6a3b0f..b4a20f6 100644 --- a/src/components/giantTree/zTree/ztree.vue +++ b/src/components/giantTree/zTree/ztree.vue @@ -1,325 +1,457 @@ <template> - <div class="ztree" :id="ztreeId"></div> + <div> + <div class="searchTree"> + <el-input placeholder="鎼滅储" v-model="keyWord" size="mini" v-show="search"> + <i slot="suffix" class="el-input__icon el-icon-search" :id="searchBtnId"></i> + </el-input> + </div> + <div class="ztree" :id="ztreeId"></div> + </div> </template> <script> -import * as $ from "jquery"; +import * as $ from "jquery" +import { Loading } from "element-ui" + if (!window.jQuery) { - window.jQuery = $; + window.jQuery = $ } // require("@ztree/ztree_v3/js/jquery.ztree.all"); -require("./ztree_v3/jquery.ztree.all"); +require("./ztree_v3/jquery.ztree.all") +require("./ztree_v3/jquery.ztree.exhide") export default { props: { showCheckbox: { type: Boolean, default: false }, readonly: { type: Boolean, default: true }, gb28181: { type: Boolean, default: false }, + search: { type: Boolean, default: false }, setting: { type: Object, require: false, - default: function () { - return {}; - }, + default: function() { + return {} + } }, nodes: { type: Array, require: true, - default: function () { - return []; - }, - }, + default: function() { + return [] + } + } }, data() { return { ztreeId: "ztree_" + parseInt(Math.random() * 1e10), + searchBtnId: "search_" + parseInt(Math.random() * 1e10), ztreeObj: null, list: [], + loading: false, ztreeSetting: { view: { 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: "ps", N: "ps" }, + enable: this.showCheckbox }, callback: { onAsyncError: (...arg) => { - this.$emit("onAsyncError", ...arg); + this.$emit("onAsyncError", ...arg) }, onAsyncSuccess: (...arg) => { - this.$emit("onAsyncSuccess", ...arg); + this.$emit("onAsyncSuccess", ...arg) }, onCheck: (...arg) => { - this.$emit("onCheck", ...arg); + this.$emit("onCheck", ...arg) }, onClick: (...arg) => { - this.$emit("onClick", ...arg); - //this.removeHoverIcon(...arg); + this.$emit("onClick", ...arg) + this.removeHoverIcon(...arg) }, onCollapse: (...arg) => { - this.$emit("onCollapse", ...arg); + this.$emit("onCollapse", ...arg) }, onDblClick: (...arg) => { - this.$emit("onDblClick", ...arg); + this.$emit("onDblClick", ...arg) }, onDrag: (...arg) => { - this.$emit("onDrag", ...arg); + this.$emit("onDrag", ...arg) }, onDragMove: (...arg) => { - this.$emit("onDragMove", ...arg); + this.$emit("onDragMove", ...arg) }, onDrop: (...arg) => { - this.$emit("onDrop", ...arg); + this.$emit("onDrop", ...arg) }, onExpand: (...arg) => { - this.$emit("onExpand", ...arg); + this.$emit("onExpand", ...arg) }, onMouseDown: (...arg) => { - this.$emit("onMouseDown", ...arg); + this.$emit("onMouseDown", ...arg) }, onMouseUp: (...arg) => { - this.$emit("onMouseUp", ...arg); + this.$emit("onMouseUp", ...arg) }, onRemove: (...arg) => { - this.$emit("onRemove", ...arg); + this.$emit("onRemove", ...arg) }, onRename: (...arg) => { - this.$emit("onRename", ...arg); + this.$emit("onRename", ...arg) }, onRightClick: (...arg) => { - this.$emit("onRightClick", ...arg); - }, - }, + this.$emit("onRightClick", ...arg) + } + } }, - }; + keyWord: "", + options: { + target: "" + } + } }, watch: { nodes: { - handler: function (nodes) { - this.list = nodes; + handler: function(nodes) { + this.list = nodes // update tree if (this.ztreeObj) { - this.ztreeObj.destroy(); + this.ztreeObj.destroy() } this.$nextTick(() => { this.ztreeObj = $.fn.zTree.init( $("#" + this.ztreeId), Object.assign({}, this.ztreeSetting, this.setting), this.list - ); - this.$emit("onCreated", this.ztreeObj); - }); + ) + this.fuzzySearch(this.ztreeObj, this.searchBtnId, false, true) //鍒濆鍖栨ā绯婃悳绱㈡柟娉� + this.$emit("onCreated", this.ztreeObj) + }) }, deep: true, - immediate: true, + immediate: true }, showCheckbox: { - handler: function () { - this.ztreeSetting.check.enable = this.showCheckbox; + handler: function() { + let top = $("#" + this.ztreeId) + .parent() + .scrollTop() + + this.ztreeSetting.check.enable = this.showCheckbox if (this.ztreeObj) { - this.list = this.ztreeObj.getNodes(); - this.ztreeObj.destroy(); + this.list = this.ztreeObj.getNodes() + this.ztreeObj.destroy() } this.$nextTick(() => { this.ztreeObj = $.fn.zTree.init( $("#" + this.ztreeId), Object.assign({}, this.ztreeSetting, this.setting), this.list - ); - this.$emit("onCreated", this.ztreeObj); - }); + ) + $("#" + this.ztreeId) + .parent() + .scrollTop(top) + this.$emit("onCreated", this.ztreeObj) + }) }, - immediate: true, - }, + immediate: true + } }, methods: { addHoverDom(treeid, treeNode) { - let _vue = this; - const item = document.getElementById(`${treeNode.tId}_a`); + let _vue = this + const item = document.getElementById(`${treeNode.tId}_a`) // 鏂囦欢澶规柊澧炴寜閽� if ( item && - !item.querySelector(".addIcon") && + !item.querySelector(".el-icon-circle-plus-outline") && treeNode.isParent && !this.readonly && !this.gb28181 ) { - const btn = document.createElement("a"); - btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add("addIcon"); - btn.classList.add("iconfont"); - btn.title = "鏂板"; + const btn = document.createElement("i") + btn.id = `${treeid}_${treeNode.id}_btn` + btn.classList.add("el-icon-circle-plus-outline") + btn.classList.add("primary") // btn.innerText = '鍒犻櫎'; btn.addEventListener("click", (e) => { - e.stopPropagation(); + e.stopPropagation() // this.clickRemove(treeNode) - _vue.$emit("onAddNode", treeNode); - }); + _vue.$emit("onAddNode", treeNode) + }) - item.appendChild(btn); + item.appendChild(btn) } // 鏂囦欢澶瑰垹闄ゆ寜閽� if ( item && - !item.querySelector(".delIcon") && + !item.querySelector(".el-icon-remove-outline") && treeNode.isParent && !this.readonly && !treeNode.children && !this.gb28181 ) { - const btn = document.createElement("a"); - btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add("delIcon"); - btn.classList.add("iconfont"); - btn.title = "鍒犻櫎"; + const btn = document.createElement("i") + btn.id = `${treeid}_${treeNode.id}_btn` + btn.classList.add("el-icon-remove-outline") + btn.classList.add("danger") // btn.innerText = '鍒犻櫎'; btn.addEventListener("click", (e) => { - e.stopPropagation(); + e.stopPropagation() // this.clickRemove(treeNode) - _vue.$emit("onRemoveNode", treeNode); - }); + _vue.$emit("onRemoveNode", treeNode) + }) - item.appendChild(btn); + item.appendChild(btn) } // 鏂囦欢澶圭紪杈戞寜閽� - if ( - item && - !item.querySelector(".editIcon") && - treeNode.isParent && - !this.readonly - ) { - const btn = document.createElement("a"); - btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add("editIcon"); - btn.classList.add("iconfont"); - btn.title = "缂栬緫"; + 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.innerText = '鍒犻櫎'; btn.addEventListener("click", (e) => { - e.stopPropagation(); + e.stopPropagation() // this.clickRemove(treeNode) - _vue.$emit("onRenameNode", treeNode); - }); + _vue.$emit("onRenameNode", treeNode) + }) - item.appendChild(btn); + item.appendChild(btn) } + // 娣诲姞鎽勫儚鏈烘寜閽� - if ( - item && - !item.querySelector(".addCameraIcon") && - treeNode.isParent && - !this.readonly && - !this.gb28181 - ) { - const btn = document.createElement("a"); - btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add("iconfont"); - btn.classList.add("addCameraIcon"); - btn.title = "娣诲姞鎽勫儚鏈�"; + 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.innerText = '鍒犻櫎'; btn.addEventListener("click", (e) => { - e.stopPropagation(); + e.stopPropagation() // this.clickRemove(treeNode) - _vue.$emit("onAddDevice", treeNode.id); - }); + _vue.$emit("onAddDevice", treeNode.id) + }) + btn.innerHTML = "" - item.appendChild(btn); + item.appendChild(btn) } // 瀵煎叆鎽勫儚鏈烘寜閽� - if ( - item && - !item.querySelector(".importIcon") && - treeNode.isParent && - !this.readonly && - !this.gb28181 - ) { - const btn = document.createElement("a"); - btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add("iconfont"); - btn.classList.add("importIcon"); - btn.title = "瀵煎叆鎽勫儚鏈�"; + 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.innerText = '鍒犻櫎'; btn.addEventListener("click", (e) => { - e.stopPropagation(); + e.stopPropagation() // this.clickRemove(treeNode) - _vue.$emit("onImport", treeNode.id); - }); + _vue.$emit("onImport", treeNode.id) + }) + btn.innerHTML = "" - item.appendChild(btn); + item.appendChild(btn) } // 鏌ョ湅搴曞浘鎸夐挳 - if ( - item && - !item.querySelector(".icontupian1") && - treeNode.type == "camera" - ) { - const btn = document.createElement("a"); - btn.id = `${treeid}_${treeNode.id}_btn`; - btn.classList.add("iconfont"); - btn.classList.add("icontupian1"); - btn.classList.add("primary"); - btn.classList.add("icon-fix"); - btn.title = "鏌ョ湅搴曞浘"; + if (item && !item.querySelector(".el-icon-picture") && treeNode.type == "camera") { + const btn = document.createElement("i") + btn.id = `${treeid}_${treeNode.id}_btn` + btn.classList.add("iconfont") + btn.classList.add("el-icon-picture") + btn.classList.add("primary") + btn.classList.add("icon-fix") // btn.innerText = '鍒犻櫎'; btn.addEventListener("click", (e) => { - e.stopPropagation(); + e.stopPropagation() // this.clickRemove(treeNode) - _vue.$emit("onShowPic", treeNode); - }); + _vue.$emit("onShowPic", treeNode) + }) - item.appendChild(btn); + item.appendChild(btn) } }, removeHoverIcon(evt, treeId, item) { - this.removeHoverDom(treeId, item); + this.removeHoverDom(treeId, item) }, removeHoverDom(treeid, treeNode) { - const item = document.getElementById(`${treeNode.tId}_a`); + const item = document.getElementById(`${treeNode.tId}_a`) if (item) { - let btn = item.querySelector(".addIcon"); + let btn = item.querySelector(".el-icon-circle-plus-outline") if (btn) { - item.removeChild(item.querySelector(".addIcon")); + item.removeChild(item.querySelector(".el-icon-circle-plus-outline")) } - btn = item.querySelector(".delIcon"); + btn = item.querySelector(".el-icon-remove-outline") if (btn) { - item.removeChild(item.querySelector(".delIcon")); + item.removeChild(item.querySelector(".el-icon-remove-outline")) } - btn = item.querySelector(".editIcon"); + btn = item.querySelector(".el-icon-edit") if (btn) { - item.removeChild(item.querySelector(".editIcon")); + item.removeChild(item.querySelector(".el-icon-edit")) } - btn = item.querySelector(".addCameraIcon"); + btn = item.querySelector(".iconshishishipin") if (btn) { - item.removeChild(item.querySelector(".addCameraIcon")); + item.removeChild(item.querySelector(".iconshishishipin")) } - btn = item.querySelector(".importIcon"); + btn = item.querySelector(".icondaoru") if (btn) { - item.removeChild(item.querySelector(".importIcon")); + item.removeChild(item.querySelector(".icondaoru")) } - btn = item.querySelector(".icontupian1"); + btn = item.querySelector(".el-icon-picture") if (btn) { - item.removeChild(item.querySelector(".icontupian1")); + item.removeChild(item.querySelector(".el-icon-picture")) } } }, - }, -}; + 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 + _this.$emit("onAfterSearch", null) + } + + /** + * 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(); + $("#" + searchField).removeClass("el-icon-search") + $("#" + searchField).addClass("el-icon-loading") + searchNodeLazy(_this.keyWord) //call lazy load + // loadingInstance.close() + setTimeout(() => { + $("#" + searchField).removeClass("el-icon-loading") + $("#" + searchField).addClass("el-icon-search") + }, 300) + }) + + var lastKeyword = "" + // excute lazy load once after input change, the last pending task will be cancled + function searchNodeLazy(_keywords) { + if (lastKeyword === _keywords) { + return + } + ztreeFilter(zTreeObj, _keywords) //lazy load ztreeFilter function + // $(searchField).focus();//focus input field again after filtering + lastKeyword = _keywords + } + }, + handleSearch() { + this.loading = true + searchNodeLazy(this.keyWord) //call lazy load + this.loading = false + } + } +} </script> <style lang="scss"> @@ -423,8 +555,7 @@ } .ztree li ul.line { /* background: url(/images/line_conn.gif) 0 0 repeat-y; */ - background: url(data:image/gif;base64,R0lGODlhCQACAIAAAMzMzP///yH5BAEAAAEALAAAAAAJAAIAAAIEjI9pUAA7) - 0 0 repeat-y; + background: url(data:image/gif;base64,R0lGODlhCQACAIAAAMzMzP///yH5BAEAAAEALAAAAAAJAAIAAAIEjI9pUAA7) 0 0 repeat-y; } .ztree li a { @@ -491,6 +622,15 @@ margin-right: 5px; position: relative; top: 2px; +} + +.ztree i.iconshishishipin, +.ztree i.icondaoru { + margin-right: 8px; + font-size: 18px; + vertical-align: middle; + width: 24px; + text-align: left; } .ztree li a.primary { @@ -745,4 +885,37 @@ filter: alpha(opacity=0); position: absolute; } + +.iconfont.el-icon-picture.primary.icon-fix { + margin-left: 10px; + margin-right: 10px; + font-size: 16px; + color: #0065ff; +} +</style> + +<style scoped lang="scss"> +.searchTree { + margin: 5px 5px; + display: flex; + justify-content: center; + + .el-input { + margin: 0 auto; + width: 350px; + } + + ::v-deep .el-input__suffix { + right: 0; + width: 50px; + background: skyblue; + color: #fff; + cursor: pointer; + background-color: rgb(61, 104, 255); + } + + .el-icon-search:before { + content: "鎼滅储"; + } +} </style> -- Gitblit v1.8.0