[update]添加Ztree

This commit is contained in:
OrangeM21
2020-04-13 19:58:39 +08:00
parent d4a4acc089
commit e83828dd22
7 changed files with 357 additions and 8 deletions

View File

@@ -19,6 +19,7 @@
"axios": "0.18.1",
"element-ui": "2.13.0",
"eslint-plugin-html": "^6.0.0",
"jquery": "^3.5.0",
"js-cookie": "2.2.0",
"less": "^3.10.3",
"less-loader": "^5.0.0",
@@ -42,7 +43,8 @@
"vue-i18n": "^8.15.5",
"vue-router": "3.0.6",
"vue-select": "^3.9.5",
"vuex": "3.1.0"
"vuex": "3.1.0",
"ztree": "^3.5.24"
},
"devDependencies": {
"@babel/core": "7.0.0",

View File

@@ -59,10 +59,9 @@ export default {
// Object.assign(data, { node_id: '', asset_id: node.id })
// }
if (node.type === 'node') {
console.log(this.url)
this.$emit('urlChanged', this.internalUrl + '?node_id=' + node.id)
this.$emit('nodeClicked', this.internalUrl + '?node_id=' + node.id)
} else {
this.$emit('urlChanged', this.internalUrl + '?asset_id=' + node.id)
this.$emit('assetClicked', this.internalUrl + '?asset_id=' + node.id)
}
// this.$axios.get(this.url, { params: data }).then(res => {

View File

@@ -4,7 +4,7 @@
<el-collapse-transition>
<div style="display: flex;justify-items: center; flex-wrap: nowrap;justify-content:space-between;">
<div v-show="ShowTree" :style="ShowTree?('width:250px;'):('width:0;')" class="transition-box">
<TreeNode :tree-url="tableConfig.treeurl" :url="tableConfig.url" @urlChanged="handleUrlChange" />
<ZTree :tree-url="tableConfig.treeurl" :url="tableConfig.url" @nodeClicked="handleUrlChange" @assetClicked="handleUrlChange" />
</div>
<div :style="ShowTree?('display: flex;width: calc(100% - 250px);'):('display: flex;width:100%;')">
<div class="mini">
@@ -23,14 +23,15 @@
<script>
import { Page } from '@/layout/components'
import TreeNode from '../TreeNode'
// import TreeNode from '../TreeNode'
import ZTree from '../ZTree'
import TreeListTable from './components/TreeListTable'
export default {
name: 'TreeTable',
components: {
Page,
TreeListTable,
TreeNode
ZTree
},
props: {
...TreeListTable.props,

View File

@@ -0,0 +1,331 @@
<template>
<div>
<div class="treebox">
<ul id="ztree" class="ztree" />
</div>
<div id="rMenu">
<ul class="dropdown-menu menu-actions">
<li class="divider" />
<li id="m_create" tabindex="-1" @click="addTreeNode"><a><i class="fa fa-plus-square-o" /> 添加资产到节点 </a></li>
<li id="m_edit" tabindex="-1" @click="editTreeNode"><a><i class="fa fa-pencil-square-o" /> 重命名节点 </a></li>
<li id="m_del" tabindex="-1" @click="removeTreeNode"><a><i class="fa fa-minus-square" /> 删除节点 </a></li>
</ul>
</div>
</div>
</template>
<script>
// 导入JQuery
// eslint-disable-next-line no-unused-vars
import $ from '@/utils/jquery-vendor.js'
import 'ztree'
import 'ztree/css/metroStyle/metroStyle.css'
const defaultFunction = {
type: Function,
default: () => {}
}
const defaultString = {
type: String,
default: () => {}
}
const defaultBoolean = {
type: Boolean,
default: () => true
}
const defaultArray = {
type: Array,
default: () => []
}
export default {
name: 'ZTree',
components: {
},
props: {
url: defaultString,
treeUrl: defaultString,
// treeNodeUrl: defaultString,
showAssets: defaultBoolean,
showMenu: defaultBoolean,
// 额外右侧菜单
otherMenu: defaultArray,
onRightClick: defaultFunction,
beforeClick: defaultFunction,
onRename: defaultFunction,
beforeDrag: defaultFunction,
onDrag: defaultFunction,
beforeDrop: defaultFunction,
onDrop: defaultFunction,
beforeAsync: defaultFunction,
onSelected: defaultFunction
},
data() {
return {
setting: {
view: {
dblClickExpand: false,
showLine: true
},
data: {
simpleData: {
enable: true
}
},
async: {
enable: true,
url: this.showAssets ? process.env.VUE_APP_BASE_API + this.treeUrl : process.env.VUE_APP_BASE_API + this.setUrlParam(this.treeUrl, 'assets', '1'),
autoParam: ['id=key', 'name=n', 'level=lv'],
type: 'get'
},
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false,
drag: {
isCopy: true,
isMove: true
}
},
callback: {
onRightClick: this.OnRightClick || this.defaultOnRightClick,
beforeClick: this.beforeClick || this.defaultBeforeClick,
onRename: this.onRename || this.defaultOnRename,
onSelected: this.onSelected || this.defaultCallback('On selected'),
beforeDrag: this.beforeDrag || this.defaultCallback('On selected'),
onDrag: this.onDrag || this.defaultOnDrop('On selected'),
beforeDrop: this.beforeDrop || this.defaultBeforeDrop,
onDrop: this.onDrop || this.defaultOnDrop,
beforeAsync: this.beforeAsync || this.defaultCallback('Before async')
}
},
zTree: '',
rMenu: ''
}
},
computed() {
},
mounted() {
this.initTree()
$('.treebox').css('height', window.innerHeight - 60)
},
methods: {
initTree: function() {
this.$axios.get(this.treeUrl).then(res => {
this.zTree = $.fn.zTree.init($('#ztree'), this.setting, res)
this.rootNodeAddDom(
this.zTree,
() => {
this.$axios.post(
'/api/v1/assets/nodes/00000000-0000-0000-0000-000000000000/tasks/',
{ action: 'refresh_cache' }
).then(res => {
this.initTree()
}
)
}
)
if (this.showMenu) {
this.rMenu = $('#rMenu')
}
if (this.otherMenu) {
$('.menu-actions').append(this.otherMenu)
}
})
},
rootNodeAddDom: function(ztree, callback) {
var refreshIcon = "<a id='tree-refresh'><i class='fa fa-refresh'></i></a>"
var rootNode = ztree.getNodes()[0]
if (rootNode) {
var $rootNodeRef = $('#' + rootNode.tId + '_a')
$rootNodeRef.after(refreshIcon)
} else {
$rootNodeRef = $('#' + ztree.setting.treeId)
$rootNodeRef.html(refreshIcon)
}
var refreshIconRef = $('#tree-refresh')
refreshIconRef.bind('click', function() {
ztree.destroy()
callback()
})
},
showRMenu: function(type, x, y) {
var offset = $('#ztree').offset()
var scrollTop = document.querySelector('.treebox').scrollTop
x -= offset.left
y -= offset.top + scrollTop
x += document.body.scrollLeft
y += document.body.scrollTop + document.documentElement.scrollTop
this.rMenu.css({ 'top': y + 'px', 'left': x + 'px', 'visibility': 'visible' })
$('#rMenu ul').show()
$('body').bind('mousedown', this.onBodyMouseDown)
},
defaultCallback: function(action) {
console.log(action)
},
defaultOnRightClick: function(event, treeId, treeNode) {
if (!this.showMenu) {
return
}
if (!treeNode && event.target.tagName.toLowerCase() !== 'button' && $(event.target).parents('a').length === 0) {
this.zTree.cancelSelectedNode()
this.showRMenu('root', event.clientX, event.clientY)
} else if (treeNode && !treeNode.noR) {
this.zTree.selectNode(treeNode)
this.showRMenu('node', event.clientX, event.clientY)
}
},
defaultBeforeClick: function(treeId, treeNode, clickFlag) {
return true
},
defaultOnDrop: function(event, treeId, treeNodes, targetNode, moveType) {
var treeNodesIds = []
$.each(treeNodes, function(index, value) {
treeNodesIds.push(value.meta.node.id)
})
// var the_url = "{% url 'api-assets:node-add-children' pk=DEFAULT_PK %}".replace('{{ DEFAULT_PK }}', targetNode.meta.node.id)
// var body = { nodes: treeNodesIds }
// TODO
this.$axios.put(
)
},
// TODO
defaultOnRename: function(treeId, treeNode, clickFlag) {
return true
},
editTreeNode: function() {
this.hideRMenu()
var current_node = this.zTree.getSelectedNodes()[0]
if (!current_node) {
return
}
if (current_node) {
current_node.name = current_node.meta.node.value
}
this.zTree.editName(current_node)
},
onBodyMouseDown: function(event) {
if (!(event.target.id === 'rMenu' || $(event.target).parents('#rMenu').length > 0)) {
this.rMenu.css({ 'visibility': 'hidden' })
}
},
hideRMenu: function() {
if (this.rMenu) this.rMenu.css({ 'visibility': 'hidden' })
$('body').unbind('mousedown', this.onBodyMouseDown)
},
defaultBeforeDrop: function(treeId, treeNodes, targetNode, moveType) {
var treeNodesNames = []
$.each(treeNodes, function(index, value) {
treeNodesNames.push(value.name)
})
var msg = '你想移动节点: `' + treeNodesNames.join(',') + '` 到 `' + targetNode.name + '` 下吗?'
return confirm(msg)
},
setUrlParam: function(url, name, value) {
var urlArray = url.split('?')
if (urlArray.length === 1) {
url += '?' + name + '=' + value
} else {
var oriParam = urlArray[1].split('&')
var oriParamMap = {}
$.each(oriParam, function(index, value) {
var v = value.split('=')
oriParamMap[v[0]] = v[1]
})
oriParamMap[name] = value
url = urlArray[0] + '?'
var newParam = []
$.each(oriParamMap, function(index, value) {
newParam.push(index + '=' + value)
})
url += newParam.join('&')
}
return url
},
removeTreeNode: function() {
this.hideRMenu()
var current_node = this.zTree.getSelectedNodes()[0]
if (!current_node) {
return
}
// var url = "{% url 'api-assets:node-detail' pk=DEFAULT_PK %}".replace('{{ DEFAULT_PK }}', current_node_id)
// requestApi({
// url: url,
// method: 'DELETE',
// success: function() {
// zTree.removeNode(current_node)
// }
// })
}
}
}
</script>
<style lang='less' scoped>
div#rMenu {
position: absolute;
visibility: hidden;
text-align: left;
top: 0;
left: 0;
z-index: 999;
float: left;
padding: 0 0;
margin: 2px 0 0;
list-style: none;
background-clip: padding-box;
}
.dataTables_wrapper .dataTables_processing {
opacity: .9;
border: none;
}
div#rMenu li{
margin: 1px 0;
cursor: pointer;
list-style: none outside none;
}
.dropdown-menu {
border: medium none;
min-width: 160px;
background-color: #fff;
border-radius: 3px;
box-shadow: 0 0 3px rgba(86, 96, 117, 0.7);
display: block;
float: left;
font-size: 12px;
left: 0;
list-style: none outside none;
padding: 0;
position: absolute;
text-shadow: none;
top: 100%;
z-index: 1000;
}
.ztree /deep/ .fa-refresh {
font: normal normal normal 14px/1 FontAwesome !important;
}
.dropdown a:hover {
background-color: #f1f1f1
}
.dropdown-menu > li > a {
border-radius: 3px;
color: inherit;
line-height: 25px;
margin: 4px;
text-align: left;
font-weight: normal;
display: block;
padding: 3px 20px;
clear: both;
white-space: nowrap;
}
.dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus {
color: #262626;
text-decoration: none;
background-color: #f5f5f5;
}
</style>

4
src/utils/jquery-vendor.js vendored Normal file
View File

@@ -0,0 +1,4 @@
import $ from 'jquery'
window.$ = $
window.jQuery = $
export default $

View File

@@ -14,7 +14,7 @@ export default {
return {
tableConfig: {
url: '/api/v1/assets/assets/',
treeurl: '/api/v1/assets/nodes/children/tree/',
treeurl: '/api/v1/assets/nodes/children/tree/?assets=0',
columns: [
{
prop: 'hostname',

View File

@@ -5597,6 +5597,11 @@ jest@^23.6.0:
import-local "^1.0.0"
jest-cli "^23.6.0"
jquery@>=1.4.4, jquery@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9"
integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==
js-base64@^2.1.8, js-base64@^2.1.9:
version "2.5.2"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209"
@@ -9986,3 +9991,10 @@ yorkie@^2.0.0:
is-ci "^1.0.10"
normalize-path "^1.0.0"
strip-indent "^2.0.0"
ztree@^3.5.24:
version "3.5.24"
resolved "https://registry.yarnpkg.com/ztree/-/ztree-3.5.24.tgz#b63fe52981fdf2c329675cfd2772f0d147521ff1"
integrity sha1-tj/lKYH98sMpZ1z9J3Lw0UdSH/E=
dependencies:
jquery ">=1.4.4"