<template>
|
<div class="wrap">
|
<div class="bread">
|
<el-breadcrumb separator="el-icon-arrow-right">
|
<el-breadcrumb-item>{{ breadLabel }}</el-breadcrumb-item>
|
</el-breadcrumb>
|
</div>
|
<div class="treeBox">
|
<el-tree
|
ref="tree"
|
:props="defaultProps"
|
node-key="id"
|
:data="dirData"
|
:expand-on-click-node="false"
|
:default-expanded-keys="[1, 2, 3, 4, 5, 6, 7, 8, 9]"
|
:draggable="draggable"
|
@node-drag-start="handleDragStart"
|
@node-click="handleNodeClick"
|
@node-drop="handleDrop"
|
>
|
<span class="custom-tree-node" slot-scope="{ node, data }">
|
<span>{{ node.label }}</span>
|
<span class="btnBox" v-show="showEdit">
|
<el-button type="text" size="mini" @click="() => append(data)">
|
<i class="el-icon-circle-plus"></i>
|
</el-button>
|
<el-button
|
type="text"
|
size="mini"
|
@click="() => remove(node, data)"
|
>
|
<i class="el-icon-delete-solid"></i>
|
</el-button>
|
</span>
|
</span>
|
</el-tree>
|
<!-- <div style="margin-left:130px;">
|
<el-button @click="sendChange">保存</el-button>
|
</div> -->
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import { selectdirTab } from '../../api/api';
|
export default {
|
name: 'catalogueTree',
|
props: ['showBtn'],
|
data() {
|
return {
|
draggable: false,
|
id: null,
|
showEdit: false,
|
showBread: false,
|
oriData: [], //原始树数据
|
dirData: [], //el树数据
|
old_dirDat: [], //el树数据(拖动前)
|
newData: [], //拖动后原始数据
|
breadList: [], //面包屑数组
|
breadLabel: '', //面包屑文字
|
filterText: '',
|
defaultProps: {
|
children: 'children',
|
label: 'name',
|
},
|
};
|
},
|
|
methods: {
|
// 请求目录树
|
async getDirTree() {
|
this.selectData = [];
|
const data = await selectdirTab();
|
if (data.code != 200) {
|
this.$message.error('下拉调用失败');
|
} else {
|
this.oriData = data.result;
|
this.newData = data.result;
|
this.dirData = this.treeData(data.result);
|
}
|
},
|
treeData(source) {
|
let cloneData = JSON.parse(JSON.stringify(source)); // 对源数据深度克隆
|
return cloneData.filter((father) => {
|
// 循环所有项
|
let branchArr = cloneData.filter((child) => father.id == child.pid); // 对比ID,分别上下级菜单,并返回数据
|
branchArr.length > 0 ? (father.children = branchArr) : ''; // 给父级添加一个children属性,并赋值
|
// 属于同一对象问题,例如:令 a=b、c=1 ,然后再令 b.c=c , 那么 a.c=b.c=c=1 ;同理,后续令 c.d=2 ,那么 a.c.d 也是=2;
|
// 由此循环多次后,就能形成相应的树形数据结构
|
return father.pid == 0; // 返回一级菜单
|
});
|
},
|
append(data) {
|
this.$prompt('请输入名称', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
})
|
.then(({ value }) => {
|
const newChild = {
|
id: this.id + 1,
|
name: value,
|
pid: data.id,
|
// children: [],
|
oid: data.children ? data.children.length + 1 : 1,
|
};
|
this.id = newChild.id; //修改新的最大I
|
console.log(newChild);
|
|
if (!data.children) {
|
this.$set(data, 'children', []);
|
}
|
data.children.push(newChild);
|
this.newData.push(newChild);
|
this.sendChange();
|
})
|
.catch(() => {
|
this.$message({
|
type: 'info',
|
message: '取消输入',
|
});
|
});
|
},
|
remove(node, data) {
|
this.$confirm('此操作将删除该节点, 是否继续?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning',
|
})
|
.then(() => {
|
const parent = node.parent;
|
const children = parent.data.children || parent.data;
|
const index = children.findIndex((d) => d.id === data.id);
|
let res = children.splice(index, 1);
|
var std = [];
|
for (var i in res) {
|
std.push(res[i].id);
|
}
|
deleteDirTree(std);
|
this.getDirTree();
|
this.$message({
|
type: 'success',
|
message: '删除成功!',
|
});
|
})
|
.catch(() => {
|
this.$message({
|
type: 'info',
|
message: '已取消删除',
|
});
|
});
|
// this.dialogMessage="是否删除"
|
// this.dialogFlag = 1;
|
// this.dialogFrom ={
|
// node:node,
|
// val:data
|
// }
|
// this.dialogVisible=true;//目录树更改弹窗
|
// const parent = node.parent;
|
// const children = parent.data.children || parent.data;
|
// const index = children.findIndex((d) => d.id === data.id);
|
// let res = children.splice(index, 1);
|
// // console.log(res);
|
// // console.log(data);
|
// console.log(this.flaten(res));
|
},
|
flaten(arr) {
|
return arr.reduce((p, v, i) => {
|
for (let i = 0; i < p.length; i++) {
|
if (p[i].children) {
|
delete p[i].children;
|
}
|
}
|
return p.concat(v.children ? this.flaten(v.children).concat(v) : v);
|
}, []);
|
},
|
handleNodeClick(data) {
|
// console.log(data);
|
this.$store.commit('verChangeNode', data);
|
this.breadList = [];
|
this.getTreeNode(this.$refs.tree.getNode(data.id));
|
},
|
getTreeNode(node) {
|
if (node && node.label) {
|
this.breadList.unshift(node.label);
|
this.getTreeNode(node.parent); //递归
|
this.breadLabel = this.breadList.join('>');
|
this.$store.commit('changeCata', this.breadLabel);
|
}
|
},
|
handleDragStart(node, ev) {
|
this.old_dirDat = JSON.parse(JSON.stringify(this.dirData)); //将备份的dir重新赋值
|
},
|
|
handleDrop(draggingNode, dropNode, dropType, ev) {
|
// console.log("被拖拽节点", draggingNode);
|
// console.log("进入的节点", dropNode);
|
// console.log("放置位置", dropType);
|
// console.log("事件", ev);
|
// if (dropType !== "inner") {
|
// // 1.修改父节点pid
|
// draggingNode.data.pid = dropNode.data.pid;
|
// dropNode.parent.childNodes.forEach((item, index) => {
|
// // 2.修改自身顺序oid
|
// item.data.oid = index + 1;
|
// });
|
// }
|
// // console.log(draggingNode.data.id);
|
// let res = this.oriData.filter((item) => item.id == draggingNode.data.id);
|
// console.log(res);
|
this.$confirm('此操作将保存目录更改, 是否继续?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning',
|
})
|
.then(() => {
|
let paramData = [];
|
let data = dropType != 'inner' ? dropNode.parent.data : dropNode.data;
|
let nodeData =
|
dropNode.level == 1 && dropType != 'inner' ? data : data.children;
|
let pid = '';
|
nodeData.forEach((item, i) => {
|
if (dropType != 'inner') {
|
if (draggingNode.data.pid === dropNode.data.pid) {
|
pid = item.pid;
|
} else {
|
pid = dropNode.data.pid;
|
}
|
} else {
|
pid = data.id;
|
}
|
let collection = {
|
id: item.id,
|
name: item.name,
|
pid,
|
oid: i + 1,
|
};
|
paramData.push(collection);
|
});
|
// console.log(paramData);
|
let arr = [];
|
this.oriData.forEach((e) => {
|
paramData.forEach((item) => {
|
if (item.id === e.id) {
|
e = item;
|
}
|
});
|
arr.push(e);
|
});
|
this.newData = arr;
|
this.sendChange();
|
this.$message({
|
type: 'success',
|
message: '更改成功!',
|
});
|
})
|
.catch(() => {
|
this.$message({
|
type: 'info',
|
message: '已取消更改',
|
});
|
this.dirData = this.old_dirDat; //将备份的dir重新赋值
|
});
|
},
|
|
sendChange() {
|
updateDirTree(this.newData).then((res) => {
|
console.log(res);
|
if (res.status == 200) {
|
this.$message({
|
type: 'success',
|
message: '更新成功!',
|
});
|
}
|
});
|
},
|
},
|
mounted() {
|
this.getDirTree();
|
this.$bus.$on('clearTressLabel', (e) => {
|
this.breadLabel = '';
|
});
|
},
|
watch: {
|
showBtn: {
|
immediate: true,
|
handler(val) {
|
if (val) {
|
this.showEdit = val;
|
this.draggable = val;
|
}
|
},
|
},
|
showBread: {
|
immediate: true,
|
handler(val) {
|
if (val) this.showBread = val;
|
},
|
},
|
},
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.wrap {
|
width: 98.5%;
|
height: 100%;
|
|
.bread {
|
width: 100%;
|
height: 5%;
|
margin: 0 auto;
|
overflow: auto;
|
}
|
|
.treeBox {
|
margin-top: 1%;
|
width: 100%;
|
height: 94%;
|
overflow: auto;
|
|
.el-tree {
|
background: transparent;
|
font-size: 15px;
|
font-family: Microsoft YaHei;
|
font-weight: 400;
|
color: #000000;
|
|
// /deep/ .el-tree-node__label {
|
// font-size: 18px;
|
// }
|
/deep/ .el-tree-node {
|
padding-top: 10px;
|
// padding-bottom: 10px;
|
}
|
|
/deep/ .el-tree-node:focus > .el-tree-node__content {
|
background-color: #b9b9b9;
|
}
|
|
/deep/ .el-tree-node__content:hover {
|
background-color: rgb(153, 153, 153);
|
}
|
|
.btnBox {
|
margin-left: 5px;
|
|
.el-button + .el-button {
|
margin-left: 5px;
|
}
|
}
|
}
|
}
|
}
|
</style>
|