src/Pool/TreeData.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/giantTree/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/giantTree/zTree/ztree.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/giantTree/zTree/ztree_v3/jquery.ztree.all.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/pages/gb28181/index/App.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/Pool/TreeData.ts
@@ -338,7 +338,6 @@ } else { if (n.type == "menu" && this.zTree) { n.isParent = true console.log(n) } } }) @@ -492,7 +491,6 @@ this.gb28181CheckedCount = 0 this.gb28181ChildNodeCount = this.countChildrenNodes(this.treeData) this.activeTreeData = this.treeData console.log(this.activeTreeData) } } src/components/giantTree/index.vue
@@ -6,9 +6,11 @@ :readonly="TreeDataPool.readonly" :gb28181="gb28181" :setting="setting" :search="search" @onCreated="handleCreated" @onClick="itemClick" @onCheck="itemCheck" @onAfterSearch="itemCheck" @onDblClick="onDblClick" @onAddNode="addNode" @onRemoveNode="delNode" @@ -20,26 +22,14 @@ @onShowPic="showCameraPic" /> <div class="dialog-box-bg" v-show="showDialog" @click="hideDialogBox"></div> <div class="dialog-box" v-show="showDialog" :style="{ left: clientX + 'px', top: clientY + 'px' }" > <div class="dialog-box" v-show="showDialog" :style="{ left: clientX + 'px', top: clientY + 'px' }"> <el-card :body-style="{ padding: '10px' }"> <el-form :model="dialogForm" size="mini" :rules="rules" ref="dialogForm" label-width="70px" > <el-form :model="dialogForm" size="mini" :rules="rules" ref="dialogForm" label-width="70px"> <el-form-item label="名称:" prop="name"> <el-input v-model="dialogForm.text"></el-input> </el-form-item> <div class="text-center pb-2"> <el-button size="mini" type="primary" @click="submitForm" >保存</el-button > <el-button size="mini" type="primary" @click="submitForm">保存</el-button> <el-button size="mini" @click="hideDialogBox">取消</el-button> </div> </el-form> @@ -50,44 +40,48 @@ <script> // import VJstree from "./jsTree"; import ZTree from "./zTree/ztree"; import ZTree from "./zTree/ztree" export default { name: "GiantTreeMenu", components: { ZTree, ZTree }, props: { app: { type: String, default: "Video", default: "Video" }, node: { type: Array, type: Array }, treeName: { type: String, default: "", default: "" }, gb28181: { type: Boolean, default: false, default: false }, search: { type: Boolean, default: false }, height: { type: Number, default: 0, default: 0 }, setting: { type: Object, require: false, default: function () { return {}; }, default: function() { return {} } }, clickType: { type: String, default: "", }, default: "" } }, data() { return { @@ -96,36 +90,36 @@ clientX: 0, clientY: 0, dialogForm: { text: "", text: "" }, rules: { text: [ { required: true, message: "请输入节点名称", trigger: "change" }, { min: 2, max: 10, message: "长度在2到10个字", trigger: "change" }, ], { min: 2, max: 10, message: "长度在2到10个字", trigger: "change" } ] }, curNodeTid: "", }; curNodeTid: "" } }, created() { // console.log(this.height, '树高度') this.TreeDataPool.zTree = true; this.TreeDataPool.zTree = true this.TreeDataPool.activeVideoIndex = sessionStorage.activeIndexVideo ? Number(sessionStorage.activeIndexVideo) : this.TreeDataPool.activeVideoIndex; : this.TreeDataPool.activeVideoIndex }, watch: { "TreeDataPool.treeType": function (newValue) { "TreeDataPool.treeType": function(newValue) { if (newValue !== this.treeName) { this.TreeDataPool.cleanTree(this.treeName); this.TreeDataPool.cleanTree(this.treeName) } }, } }, methods: { handleCreated: function (ztreeObj) { let _this = this; this.ztreeObj = ztreeObj; handleCreated: function(ztreeObj) { let _this = this this.ztreeObj = ztreeObj // console.log("handleCreated") // onCreated 中操作ztreeObj对象展开第一个节点 // ztreeObj.expandNode(ztreeObj.getNodes()[0], true); @@ -133,120 +127,94 @@ // 摄像机配置切换时, 设置选中状态 if (this.TreeDataPool.selectedNode.id) { // 取消所有多选的节点,仅保留当前单选的节点 this.TreeDataPool.selectedNodes = [this.TreeDataPool.selectedNode.id]; this.curNodeTid = this.TreeDataPool.selectedNode.tId; this.TreeDataPool.selectedNodes = [this.TreeDataPool.selectedNode.id] this.curNodeTid = this.TreeDataPool.selectedNode.tId //摄像机信息更新信息后,如果节点位置有变tId就不准了,this.TreeDataPool.selectedNode此时还是旧的信息 let ztreeNodes = ztreeObj.getNodes(); let ztreeNodes = ztreeObj.getNodes() //var curNodeTid = ''; _this.findTidByIdFromArr(ztreeNodes); this.TreeDataPool.selectedNode.tId = _this.curNodeTid; let node = this.ztreeObj.getNodeByTId( this.TreeDataPool.selectedNode.tId ); _this.findTidByIdFromArr(ztreeNodes) this.TreeDataPool.selectedNode.tId = _this.curNodeTid let node = this.ztreeObj.getNodeByTId(this.TreeDataPool.selectedNode.tId) // 多选时, 选中单选单击的节点 if (this.TreeDataPool.multiple) { this.ztreeObj.checkAllNodes(false); this.ztreeObj.checkNode(node, true, false, false); this.ztreeObj.checkAllNodes(false) this.ztreeObj.checkNode(node, true, false, false) } this.ztreeObj.selectNode(node, false, true); this.ztreeObj.selectNode(node, false, true) } }, findTidByIdFromArr(arr) { let len = arr.length; let _this = this; let len = arr.length let _this = this for (var i = 0; i < len; i++) { if (arr[i].id == this.TreeDataPool.selectedNode.id) { _this.curNodeTid = arr[i].tId; break; _this.curNodeTid = arr[i].tId break } if (arr[i].children) { this.findTidByIdFromArr(arr[i].children); this.findTidByIdFromArr(arr[i].children) } } }, onDblClick(evt, treeId, item) { if (item.type !== "4" || this.app !== "Camera") { return; if (!item || item.type !== "4" || this.app !== "Camera") { return } // console.log('activeForceChoose', this.TreeDataPool.activeForceChoose) this.TreeDataPool.activeVideoId = item.id; let videoArr = this.TreeDataPool.videoArr; let nullVideoIndex = ""; this.TreeDataPool.activeVideoId = item.id let videoArr = this.TreeDataPool.videoArr let nullVideoIndex = "" if ( this.TreeDataPool.activeForceChoose && this.TreeDataPool.activeVideoIndex !== "" && this.TreeDataPool.activeVideoIndex <= videoArr.length - 1 ) { this.TreeDataPool.setVideoArr( this.TreeDataPool.activeVideoIndex, undefined, this ); this.TreeDataPool.setVideoArr(this.TreeDataPool.activeVideoIndex, undefined, this) this.$nextTick(() => { this.TreeDataPool.setVideoArr( this.TreeDataPool.activeVideoIndex, item, this ); }); return; this.TreeDataPool.setVideoArr(this.TreeDataPool.activeVideoIndex, item, this) }) return } for (let i = 0; i < videoArr.length; i++) { // eslint-disable-next-line if ( videoArr[i] === "" || videoArr[i] === undefined || videoArr[i] === null ) { nullVideoIndex = i; break; if (videoArr[i] === "" || videoArr[i] === undefined || videoArr[i] === null) { nullVideoIndex = i break } else { nullVideoIndex = ""; nullVideoIndex = "" } } if (nullVideoIndex === "") { this.TreeDataPool.setVideoArr( this.TreeDataPool.activeVideoIndex, undefined, this ); this.TreeDataPool.setVideoArr(this.TreeDataPool.activeVideoIndex, undefined, this) this.$nextTick(() => { this.TreeDataPool.setVideoArr( this.TreeDataPool.activeVideoIndex, item, this ); }); this.TreeDataPool.setVideoArr(this.TreeDataPool.activeVideoIndex, item, this) }) } else { // this.TreeDataPool.setVideoArr(this.TreeDataPool.activeVideoIndex, undefined, this); this.$nextTick(() => { this.TreeDataPool.setVideoArr( this.TreeDataPool.activeVideoIndex, item, this ); }); this.TreeDataPool.activeVideoIndex = nullVideoIndex; this.TreeDataPool.setVideoArr(this.TreeDataPool.activeVideoIndex, item, this) }) this.TreeDataPool.activeVideoIndex = nullVideoIndex } }, addCamera(node) { this.$emit("addDevice", node); this.$emit("addDevice", node) }, importCameras(node) { this.$emit("import", node); this.$emit("import", node) }, addNode(node) { this.dialogForm = { text: "", method: "add", node: node.id, }; this.showDialogBox(event); node: node.id } this.showDialogBox(event) }, editNode(node) { this.dialogForm = { @@ -254,61 +222,61 @@ method: "edit", node: node.id, alias: node.alias, gb28181: this.gb28181, }; this.showDialogBox(event); gb28181: this.gb28181 } this.showDialogBox(event) }, delNode(node) { this.TreeDataPool.del(node.id); this.TreeDataPool.del(node.id) }, submitForm() { // 提交新增或者编辑区域节点表单 this.$refs.dialogForm.validate((valid) => { if (valid) { if (this.dialogForm.method == "add") { this.TreeDataPool.add(this.dialogForm.text, this.dialogForm.node); this.TreeDataPool.add(this.dialogForm.text, this.dialogForm.node) } else if (this.dialogForm.method == "edit") { this.TreeDataPool.update( this.dialogForm.text, this.dialogForm.node, this.gb28181 ? this.dialogForm.text : "", this.dialogForm.gb28181 ); ) } } else { return false; return false } }); this.hideDialogBox(); }) this.hideDialogBox() }, hideDialogBox() { this.showDialog = false; this.dialogForm = { text: "" }; this.showDialog = false this.dialogForm = { text: "" } }, showDialogBox(event) { let { clientX = 0, offsetY = 0 } = event; let { clientX = 0, offsetY = 0 } = event // this.clientX = clientX - 120; this.clientX = 50; this.clientY = offsetY; this.showDialog = true; this.clientX = 50 this.clientY = offsetY this.showDialog = true }, itemClick(evt, treeId, treeNode) { if (this.clickType == "multiple") { evt.target.parentNode.parentNode.querySelector(".chk").click(); return; evt.target.parentNode.parentNode.querySelector(".chk").click() return } this.TreeDataPool.selectedNode = treeNode; this.TreeDataPool.treeType = this.treeName; this.TreeDataPool.selectedNode = treeNode this.TreeDataPool.treeType = this.treeName // 多选 if (this.TreeDataPool.multiple) { // 单击某一个节点文字时 取消所有勾选状态 然后选中自身 this.ztreeObj.checkAllNodes(false); this.ztreeObj.checkNode(treeNode, true, false, false); this.ztreeObj.checkAllNodes(false) this.ztreeObj.checkNode(treeNode, true, false, false) } this.TreeDataPool.updateZTreeCheckNodes([treeNode]); this.TreeDataPool.updateZTreeCheckNodes([treeNode]) }, // itemClick(treeNode) { // this.TreeDataPool.selectedNode = treeNode; @@ -324,37 +292,40 @@ // this.TreeDataPool.updateZTreeCheckNodes([treeNode]); // }, itemCheck(evt, treeId, treeNode) { this.TreeDataPool.selectedNode = treeNode; this.TreeDataPool.treeType = this.treeName; if (treeNode) { this.TreeDataPool.selectedNode = treeNode } this.TreeDataPool.treeType = this.treeName // 多选 // this.ztreeObj.checkNode(treeNode, true, false, false); let checkedNodes = this.ztreeObj.getCheckedNodes(true); this.TreeDataPool.updateZTreeCheckNodes(checkedNodes); let checkedNodes = this.ztreeObj.getCheckedNodes(true) this.TreeDataPool.updateZTreeCheckNodes(checkedNodes) // 实时统计选中个数 this.TreeDataPool.countCheckedNodes(checkedNodes); this.TreeDataPool.countCheckedNodes(checkedNodes) // 保存一份数据 this.TreeDataPool.activeTreeData = this.ztreeObj.getNodes(); this.TreeDataPool.activeTreeData = this.ztreeObj.getNodes() this.$emit("itemChecked", treeNode) }, //展开 itemExpand(e, id, node) { delete this.TreeDataPool.foldNodeList[node.id]; delete this.TreeDataPool.foldNodeList[node.id] }, // 折叠 itemCollapse(e, id, node) { this.TreeDataPool.foldNodeList[node.id] = true; this.TreeDataPool.foldNodeList[node.id] = true }, dropNode(node, item, draggedItem, e) { // console.log('dropNode', node, item, draggedItem); this.TreeDataPool.dropNode(draggedItem.id, item.id); this.TreeDataPool.dropNode(draggedItem.id, item.id) }, showCameraPic(nodeId) { this.TreeDataPool.showBaseImage(nodeId); }, }, }; this.TreeDataPool.showBaseImage(nodeId) } } } </script> <style lang="scss" scoped> .dialog-box { src/components/giantTree/zTree/ztree.vue
@@ -1,8 +1,8 @@ <template> <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 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> @@ -10,162 +10,164 @@ </template> <script> import * as $ from "jquery"; import { Loading } from "element-ui"; 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.exhide"); 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, 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: "", }, }; 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 ); console.log("---------"); this.fuzzySearch(this.ztreeObj, "#key", null, true); //初始化模糊搜索方法 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 () { handler: function() { let top = $("#" + this.ztreeId) .parent() .scrollTop(); .scrollTop() this.ztreeSetting.check.enable = this.showCheckbox; 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.ztreeId) .parent() .scrollTop(top); this.$emit("onCreated", this.ztreeObj); }); .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 ( @@ -175,18 +177,18 @@ !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"); 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) } // 文件夹删除按钮 @@ -198,220 +200,192 @@ !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"); 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(".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"); 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(".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"); 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) }) item.appendChild(btn); item.appendChild(btn) } // 导入摄像机按钮 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"); 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) }) item.appendChild(btn); 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"); 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(); 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(".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; const _this = this if (!zTreeObj) { alert("fail to get ztree object"); 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 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 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 _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 node[nameKey] = node.oldname //recover oldname of the node if exist } zTreeObj.updateNode(node); //update node to for modifications take effect 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; 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 (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) { 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 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 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.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 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 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) } /** @@ -421,62 +395,64 @@ 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 $.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 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 }); 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); $("#" + 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(); }); $("#" + 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 timeoutId = null; var lastKeyword = ""; 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); if (lastKeyword === _keywords) { return } 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); 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 > <style> /* beauty ztree! */ .ztree * { @@ -508,8 +484,7 @@ } .ztree li ul.line { /* background: url(./img/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 { @@ -810,7 +785,8 @@ <style scoped lang="scss"> .search { width: 300px; width: 280px; margin: 5px 5px; ::v-deep .el-input__suffix { right: 0; @@ -821,4 +797,4 @@ background-color: rgb(61, 104, 255); } } </style> </style> src/components/giantTree/zTree/ztree_v3/jquery.ztree.all.js
Diff too large src/pages/gb28181/index/App.vue
@@ -9,21 +9,15 @@ type="border-card" @tab-click="hanleTabClick" > <el-tab-pane label="国标ID" name="gb28181"> <el-tab-pane label="国标服务" name="gb28181"> <div style="width: 775px"> <!-- GB28181设置 --> <el-form :model="gb28181" :rules="rules" label-width="130px" class="alarmSetting" ref="gb28181" > <el-form :model="gb28181" :rules="rules" label-width="130px" class="alarmSetting" ref="gb28181"> <!-- <el-form-item label="国际服务器IP" prop="ServerIp"> <ip-input :ip="gb28181.ServerIp" @on-blur="gb28181.ServerIp = arguments[0]"></ip-input> </el-form-item>--> <div style="text-align: left; margin-bottom: 16px"> <div style="text-align: left;margin-bottom: 16px;"> <el-radio-group v-model="gb28181.idType"> <el-radio :label="0">输入已有ID</el-radio> <el-radio :label="1">生成新的ID</el-radio> @@ -74,11 +68,7 @@ :value="item.id" ></el-option> </el-select> <el-button type="text" style="position: absolute" v-show="gb28181.idType === 1" @click="newGBID" <el-button type="text" style="position: absolute" v-show="gb28181.idType === 1" @click="newGBID" >生成ID</el-button > </el-form-item> @@ -97,11 +87,7 @@ </el-form-item> <el-form-item label="国标端口" prop="GbServerPort"> <el-input v-model.number="gb28181.GbServerPort" placeholder="请输入" size="small" ></el-input> <el-input v-model.number="gb28181.GbServerPort" placeholder="请输入" size="small"></el-input> </el-form-item> <el-form-item label="开启鉴权" style="text-align: left"> @@ -118,9 +104,7 @@ </el-form-item> <el-form-item style="float: right"> <el-button type="primary" @click="submitGB28281" size="small" >保存</el-button > <el-button type="primary" @click="submitGB28281" size="small">保存</el-button> </el-form-item> </el-form> </div> @@ -132,87 +116,73 @@ border fit highlight-current-row style="width: 100%; color: #000" :header-cell-style="{ background: '#f8f8f8', color: '#222222', height: '30px', }" style="width: 100%; color:#000" :header-cell-style="{ background: '#f8f8f8', color: '#222222', height: '30px' }" > <el-table-column type="index" label="序号" align="center" width="50" ></el-table-column> <el-table-column prop="name" label="名称" align="center" ></el-table-column> <el-table-column prop="publicid" label="ID" align="center" ></el-table-column> <el-table-column prop="ip" label="IP" align="center" ></el-table-column> <el-table-column type="index" label="序号" align="center" width="50"></el-table-column> <el-table-column prop="name" label="名称" align="center"></el-table-column> <el-table-column prop="publicid" label="ID" align="center"></el-table-column> <el-table-column prop="ip" label="IP" align="center"></el-table-column> <el-table-column prop="status" label="状态" align="center"> <template slot-scope="scope"> <span :style="scope.row.alive ? `color:#047d19` : 'color:#f11a1a;'" >{{ scope.row.alive ? "在线" : "离线" }}</span > <span :style="scope.row.alive ? `color:#047d19` : 'color:#f11a1a;'">{{ scope.row.alive ? "在线" : "离线" }}</span> </template> </el-table-column> <el-table-column prop="corp" label="备注" align="center" ></el-table-column> <el-table-column prop="corp" label="备注" align="center"></el-table-column> </el-table> </el-tab-pane> <el-tab-pane label="国标摄像机" name="cameras"> <div style="text-align: left"> <el-button type="primary" size="small" @click="updateCamerasFromVideosvr" >刷新</el-button > <div style="text-align:left"> <el-button type="primary" size="small" @click="updateCamerasFromVideosvr">刷新</el-button> </div> <div class="camera-title"> <b>国标摄像机配置</b> <span>(最多勾选500路摄像机)</span> </div> <tree-menu ref="tree" app="gb28181" treeName="localTree" :node="TreeDataPool.treeData" :height="treeHeight" :setting="treeSettings" clickType="multiple" style="width: 600px; min-height: 500px" /> <div class="base-image" v-loading="TreeDataPool.baseImageLoading"> <span>{{ TreeDataPool.cameraNameForBaseImage }}</span> <div class="camera-image" v-show="TreeDataPool.cameraNameForBaseImage.length" > <img :src=" 'data:image/png;base64,' + TreeDataPool.gb28181CameraBaseImage " width="450px" alt <div class="tree-container"> <div class="tree-box"> <div class="camera-title"> <b>国标摄像机</b> </div> <tree-menu ref="ztree" app="gb28181" treeName="localTree" clickType="multiple" :node="TreeDataPool.treeData" :height="treeHeight" :setting="treeSettings" @itemChecked="onItemCheck" search style="width:500px;min-height:500px" /> </div> <div class="tree-box"> <div class="camera-title"> <b>已选摄像机</b> <span>(最多勾选500路摄像机)</span> </div> <!-- <tree-menu ref="dstTree" treeName="localTree" :node="dstTreeData" :height="treeHeight" :setting="treeSettingsSelect" style="width:500px;min-height:500px" /> --> <div class="select-tree-menu" :style="`max-height:${750 - 200}px;`"> <z-tree :nodes="dstTreeData" :show-checkbox="false" :gb28181="true" search /> </div> </div> <div class="base-image" v-loading="TreeDataPool.baseImageLoading"> <span>{{ TreeDataPool.cameraNameForBaseImage }}</span> <div class="camera-image" v-show="TreeDataPool.cameraNameForBaseImage.length"> <img :src="'data:image/png;base64,' + TreeDataPool.gb28181CameraBaseImage" width="450px" alt /> </div> </div> </div> <el-divider></el-divider> <span class="camera-seleted-text"> @@ -221,9 +191,7 @@ / {{ TreeDataPool.gb28181ChildNodeCount }} ) 路 </span> <el-button type="primary" size="small" @click="saveChecked" >保存</el-button > <el-button type="primary" size="small" @click="saveChecked">保存</el-button> </el-tab-pane> </el-tabs> </div> @@ -237,23 +205,25 @@ getGb28181AreaList, newGb28181ID, getAllSubServer, saveGb28181CamTree, } from "./api"; saveGb28181CamTree } from "./api" import TreeMenu from "@/components/giantTree/index"; import { isPort, isIPv4 } from "@/scripts/validate"; import bus from "@/plugin/bus"; import TreeMenu from "@/components/giantTree/index" import { isPort, isIPv4 } from "@/scripts/validate" import ZTree from "@/components/giantTree/zTree/ztree" export default { name: "Gb28181Setting", components: { TreeMenu, ZTree }, directives: { focus: { inserted: function (el) { el.querySelector("input").focus(); }, }, inserted: function(el) { el.querySelector("input").focus() } } }, data() { @@ -268,46 +238,47 @@ idType: 1, treeSettings: { check: { enable: true, }, view: { showLine: true, showIcon: true, // default to hide icon }, enable: true } }, treeSettingsSelect: { check: { enable: false } }, rules: { ip: [ { required: true, message: "请输入IP地址", trigger: "change", trigger: "change" }, { validator: isIPv4, trigger: "change" }, { validator: isIPv4, trigger: "change" } ], ServerIp: [ { required: true, message: "请输入IP地址", trigger: "change", trigger: "change" }, { validator: isIPv4, trigger: "change" }, { validator: isIPv4, trigger: "change" } ], ServerPort: [ { required: true, message: "请输入端口", trigger: "change", trigger: "change" }, { validator: isPort, trigger: "change" }, { validator: isPort, trigger: "change" } ], GbServerPort: [ { required: true, message: "请输入端口", trigger: "change", trigger: "change" }, { validator: isPort, trigger: "change" }, ], { validator: isPort, trigger: "change" } ] }, locationCity: { province: "", @@ -315,97 +286,100 @@ county: "", provinceOptions: [], cityOptions: [], countyOptions: [], countyOptions: [] }, }; dstTreeData: [] } }, mounted() { this.TreeDataPool.multiple = true; this.TreeDataPool.multiple = true // 记录目录是否折叠 let foldList = localStorage.getItem("ztree_fold_list"); let foldList = localStorage.getItem("ztree_fold_list") if (foldList) { this.TreeDataPool.foldNodeList = JSON.parse(foldList); this.TreeDataPool.foldNodeList = JSON.parse(foldList) } this.initGB28181Conf(); this.initGB28181Conf() }, methods: { hanleTabClick(tab, event) { if (this.activeName == "subordinates") { getAllSubServer().then((rsp) => { if (rsp && rsp.success) { this.subDevTable = rsp.data; this.subDevTable = rsp.data } }); }) } else if (this.activeName == "cameras") { this.getCamerasFromVideosvr(); this.getCamerasFromVideosvr() } // this.TreeDataPool.fetchGbTree() // this.dstTreeData = this.TreeDataPool.gb28181Data }, async getCamerasFromVideosvr() { this.loading = true; await this.TreeDataPool.fetchVideosvrCameras(false); this.loading = false; this.loading = true await this.TreeDataPool.fetchVideosvrCameras(false) this.dstTreeData = this.TreeDataPool.newTreeByChecked(this.TreeDataPool.treeData) this.loading = false }, async updateCamerasFromVideosvr() { this.loading = true; await this.TreeDataPool.fetchVideosvrCameras(true); this.loading = false; this.loading = true await this.TreeDataPool.fetchVideosvrCameras(true) this.loading = false }, onItemCheck() { this.dstTreeData = this.TreeDataPool.newTreeByChecked(this.TreeDataPool.activeTreeData) }, saveChecked() { localStorage.setItem( "ztree_fold_list", JSON.stringify(this.TreeDataPool.foldNodeList) ); localStorage.setItem("ztree_fold_list", JSON.stringify(this.TreeDataPool.foldNodeList)) if (this.TreeDataPool.gb28181CheckedCount > 500) { this.$message({ type: "warning", message: "最多仅支持选择500路摄像机. 请重新选择", }); message: "最多仅支持选择500路摄像机. 请重新选择" }) return; return } this.loading = true; this.loading = true let treeData = this.TreeDataPool.newTreeByChecked( this.TreeDataPool.activeTreeData ); let treeData = this.TreeDataPool.newTreeByChecked(this.TreeDataPool.activeTreeData) saveGb28181CamTree({ checkedMenus: treeData }) .then((rsp) => { if (rsp && rsp.success) { this.$message({ type: "success", message: "保存成功", }); message: "保存成功" }) } this.loading = false; this.loading = false }) .catch((err) => { this.$message({ type: "error", message: "保存失败", }); this.loading = false; }); message: "保存失败" }) this.loading = false }) }, initGB28181Conf() { getGB28181Config().then((rsp) => { if (rsp && rsp.success) { this.gb28181 = rsp.data; this.gb28181 = rsp.data //this.gb28181.idType = 0; this.$set(this.gb28181, "idType", 0); this.$refs["gb28181"].resetFields(); this.$set(this.gb28181, "idType", 0) this.$refs["gb28181"].resetFields() } }); }) getGb28181AreaList().then((rsp) => { if (rsp && rsp.success) { this.locationCity.provinceOptions = rsp.data; this.locationCity.provinceOptions = rsp.data } }); }) }, submitGB28281() { this.$refs["gb28181"].validate((valid) => { @@ -414,62 +388,62 @@ if (rsp && rsp.success) { this.$notify({ type: "success", message: "GB28181设置保存成功", }); message: "GB28181设置保存成功" }) } }); }) } else { console.log("error submit!!"); return false; console.log("error submit!!") return false } }); }) }, changeProvince() { let pid = this.locationCity.province; let pid = this.locationCity.province getGb28181AreaList({ parentId: pid }).then((rsp) => { if (rsp && rsp.success) { this.locationCity.cityOptions = rsp.data; this.locationCity.city = this.locationCity.cityOptions[0].id; this.changeCity(); this.locationCity.cityOptions = rsp.data this.locationCity.city = this.locationCity.cityOptions[0].id this.changeCity() } }); }) }, changeCity() { let pid = this.locationCity.city; let pid = this.locationCity.city getGb28181AreaList({ parentId: pid }).then((rsp) => { if (rsp && rsp.success) { this.locationCity.countyOptions = rsp.data; this.locationCity.county = this.locationCity.countyOptions[0].id; this.locationCity.countyOptions = rsp.data this.locationCity.county = this.locationCity.countyOptions[0].id } }); }) }, newGBID() { let cCode = this.locationCity.county + ""; let cCode = this.locationCity.county + "" newGb28181ID({ code: cCode }).then((rsp) => { if (rsp && rsp.success) { this.gb28181.PublicId = rsp.data; this.gb28181.PublicId = rsp.data } }); }) }, menuOpen() {}, menuClose() {}, toOpenMenuList(e) { let t = e.clientY - this.$el.offsetTop + 30; let l = e.clientX - this.$el.offsetLeft; let t = e.clientY - this.$el.offsetTop + 30 let l = e.clientX - this.$el.offsetLeft window.parent.postMessage( { source: location.href.split("/")[location.href.split("/").length - 1], trigger: "contextmenu", menuT: t, menuL: l, menuL: l }, "*" ); return false; }, }, }; ) return false } } } </script> <style lang="scss"> .s-system-manage { @@ -570,16 +544,6 @@ text-decoration: underline; } .camera-title { text-align: left; padding: 0px 10px; margin: 5px 0px; height: 33px; background-color: #e4e2e2; line-height: 33px; font-size: 14px; } .camera-seleted-text { margin-right: 20px; @@ -588,15 +552,64 @@ } } .base-image { position: absolute; top: 18%; left: 57%; width: 450px; .tree-container { display: flex; .tree-box { width: 500px; margin: 5px 10px 0px 0px; border: 1px solid #e4e2e2; .camera-image { background-color: black; height: 254px; .camera-title { text-align: left; padding: 0px 10px; margin: 0px 0px; height: 33px; background-color: #e4e2e2; line-height: 33px; font-size: 14px; } } .base-image { margin: 140px 10px; width: 450px; height: 300px; .camera-image { background-color: black; height: 254px; } } .select-tree-menu { // max-width: 350px; overflow-x: hidden; overflow-y: hidden; margin-bottom: 4px; } .select-tree-menu::-webkit-scrollbar { /*滚动条整体样式*/ width: 4px; /*高宽分别对应横竖滚动条的尺寸*/ height: 4px; } .select-tree-menu::-webkit-scrollbar-thumb { /*滚动条里面小方块*/ border-radius: 5px; -webkit-box-shadow: inset 0 0 5px rgba(157, 165, 183, 0); background: rgb(202, 201, 201); } .select-tree-menu::-webkit-scrollbar-track { /*滚动条里面轨道*/ -webkit-box-shadow: inset 0 0 5px rgba(157, 165, 183, 0); border-radius: 0; background: rgb(235, 234, 234); } .select-tree-menu::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.4); } .select-tree-menu:hover { overflow-x: visible; overflow-y: auto; margin-bottom: 0px; } } }