<template>
|
<div class="cataSettings_box">
|
<div class="cataSettings_tree">
|
<My-bread :list="['数据管理', '目录管理']"></My-bread>
|
<el-button class="saveBtn" type="primary" size="mini" @click="sendChange"
|
>保存</el-button
|
>
|
<el-divider />
|
<div class="cataTreeBox">
|
<el-tree
|
ref="tree"
|
:props="defaultProps"
|
node-key="id"
|
:data="dirList"
|
:expand-on-click-node="false"
|
:default-expand-all="true"
|
draggable
|
@node-click="handleNodeClick"
|
@node-drag-start="handleDragStart"
|
@node-drag-end="handleDrop"
|
>
|
<span class="custom-tree-node" slot-scope="{ node, data }">
|
<span>{{ node.label }}</span>
|
<span class="btnBox">
|
<el-button
|
type="text"
|
size="mini"
|
@click="() => append(node, 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>
|
</div>
|
<div class="itemSettings">
|
<div class="title_box">
|
<h4>详细信息</h4>
|
</div>
|
<div class="form_box">
|
<el-form :model="itemdetail">
|
<!-- <el-form-item label="目录编码" :label-width="formLabelWidth">
|
<el-input v-model="itemdetail.id" disabled />
|
</el-form-item> -->
|
<el-form-item label="目录名称" :label-width="formLabelWidth">
|
<el-input v-model="itemdetail.name" />
|
</el-form-item>
|
<el-form-item label="目录说明" :label-width="formLabelWidth">
|
<el-input
|
v-model="itemdetail.descr"
|
type="textarea"
|
resize="none"
|
style="height: 100%; overflow: auto"
|
/>
|
</el-form-item>
|
<el-form-item label="目录备注" :label-width="formLabelWidth">
|
<el-input v-model="itemdetail.bak" type="textarea" resize="none" />
|
</el-form-item>
|
<div class="btnBox">
|
<el-button type="primary" @click="updMenu">保存</el-button>
|
<el-button type="primary" @click="reset">取消</el-button>
|
</div>
|
</el-form>
|
</div>
|
</div>
|
'
|
|
<el-dialog title="新增子目录" :visible.sync="dialogFormVisible">
|
<el-form :model="ruleForm" ref="ruleForm" :rules="rules">
|
<el-form-item
|
label="目录名称"
|
prop="name"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="ruleForm.name" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item
|
prop="descr"
|
label="目录说明"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="ruleForm.descr" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item prop="bak" label="目录备注" :label-width="formLabelWidth">
|
<el-input v-model="ruleForm.bak" autocomplete="off"></el-input>
|
</el-form-item>
|
</el-form>
|
<div slot="footer" class="dialog-footer">
|
<el-button @click="resetForm('ruleForm')">取消</el-button>
|
<el-button
|
type="primary"
|
@click="submitForm('ruleForm')"
|
v-loading.fullscreen.lock="fullscreenLoading"
|
>提交</el-button
|
>
|
</div>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import {
|
queryDirTree,
|
queryMaxId,
|
updateDirTrees,
|
insertDir,
|
deleteDir,
|
} from "../../api/api";
|
import MyBread from "../../components/MyBread.vue";
|
export default {
|
name: "catalogueManage",
|
components: {
|
MyBread,
|
},
|
data() {
|
let validName = (rule, value, callback) => {
|
if (value === "") {
|
return callback(new Error("目录名称不能为空"));
|
} else {
|
callback();
|
}
|
};
|
return {
|
defaultProps: {
|
children: "children",
|
label: "name",
|
},
|
fullscreenLoading: false,
|
oriData: [], //原始树数据
|
dirList: [], //el树数据
|
old_dirDat: [], //el树数据(拖动前)
|
newData: [], //拖动后原始数据
|
itemdetail: {},
|
backUpData: {},
|
formLabelWidth: "170px",
|
delChildIDs: "",
|
dialogFormVisible: false,
|
ruleForm: {
|
level: null,
|
orderNum: null,
|
pid: null,
|
name: "",
|
descr: "",
|
bak: "",
|
},
|
rules: {
|
name: [{ validator: validName, trigger: "blur" }],
|
},
|
};
|
},
|
methods: {
|
// 请求目录树
|
getDirTree() {
|
//获取目录树最大ID,新建节点使用
|
// queryMaxId().then((res) => {
|
// this.id = res.data;
|
// });
|
// 获取目录树数据
|
queryDirTree().then((res) => {
|
// console.log(res);
|
if (res.code == 200) {
|
this.oriData = res.result;
|
this.newData = res.result;
|
this.dirList = this.treeData(res.result);
|
} else {
|
console.log("接口报错");
|
}
|
});
|
},
|
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(node, data) {
|
this.dialogFormVisible = true;
|
this.ruleForm.pid = data.id;
|
this.ruleForm.orderNum = node.childNodes.length + 1;
|
this.ruleForm.level = data.level + 1;
|
// console.log(data);
|
// console.log(node);
|
},
|
resetForm(formName) {
|
this.dialogFormVisible = false;
|
this.$nextTick(() => {
|
this.$refs[formName].resetFields();
|
});
|
},
|
submitForm(formName) {
|
this.$nextTick(() => {
|
this.$refs[formName].validate((valid) => {
|
if (valid) {
|
this.fullscreenLoading = true;
|
insertDir(this.ruleForm)
|
.then((res) => {
|
setTimeout(() => {
|
this.fullscreenLoading = false;
|
if (res.code == 200) {
|
this.$message({
|
message: "添加成功",
|
type: "success",
|
});
|
this.dialogFormVisible = false;
|
this.$refs[formName].resetFields();
|
}
|
}, 2000);
|
})
|
.catch((res) => {
|
console.log(res);
|
this.fullscreenLoading = false;
|
});
|
} else {
|
// alert("目录名称不能为空");
|
return false;
|
}
|
});
|
});
|
},
|
remove(node, data) {
|
this.$confirm("此操作将删除该节点, 是否继续?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
// console.log(node);
|
// console.log(data);
|
|
//兄弟重新排序
|
const parent = node.parent;
|
const children = parent.data.children || parent.data;
|
children.splice(data.orderNum - 1, 1);
|
children.forEach((item, index) => {
|
item.orderNum = index + 1;
|
});
|
|
this.traverseArr(data); //获取删除的子ID
|
let delIDs = this.delChildIDs + "id=" + data.id; //要删除的全部ID
|
console.log(delIDs);
|
Promise.all([deleteDir(delIDs), updateDirTrees(children)])
|
.then((res) => {
|
console.log(res);
|
if (res[0].code == 200 && res[1].code == 200) {
|
this.$message({
|
type: "success",
|
message: "删除成功!",
|
});
|
}
|
})
|
.catch(() => {
|
this.$message({
|
type: "error",
|
message: "删除失败",
|
});
|
});
|
|
//重置要删除的子ID
|
this.delChildIDs = "";
|
})
|
.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));
|
},
|
traverseArr(obj) {
|
if (obj.children) {
|
return obj.children.forEach((item) => {
|
// console.log(item.id + "---" + item.name);
|
this.delChildIDs += "id=" + item.id + "&";
|
this.traverseArr(item);
|
});
|
}
|
return;
|
},
|
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);
|
}, []);
|
},
|
handleDragStart(node, ev) {
|
this.old_dirDat = JSON.parse(JSON.stringify(this.dirList)); //将备份的dir重新赋值
|
},
|
handleDrop(draggingNode, dropNode, dropType, ev) {
|
this.$confirm("此操作将保存目录更改, 是否继续?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
//父节点
|
let data = dropType != "inner" ? dropNode.parent.data : dropNode.data;
|
// 父节点中全部子节点
|
let nodeData =
|
dropNode.level == 1 && dropType != "inner" ? data : data.children;
|
//变更节点
|
nodeData.forEach((item, i) => {
|
if (dropType != "inner") {
|
if (draggingNode.data.pid === dropNode.data.pid) {
|
item.pid = item.pid;
|
} else {
|
item.pid = dropNode.data.pid;
|
}
|
} else {
|
item.pid = data.id;
|
}
|
item.orderNum = i + 1;
|
});
|
// console.log(nodeData);
|
//更新原始整体数据
|
let arr = [];
|
this.oriData.forEach((e) => {
|
nodeData.forEach((item) => {
|
if (item.id === e.id) {
|
e = item;
|
}
|
});
|
arr.push(e);
|
});
|
this.newData = arr;
|
})
|
.catch(() => {
|
this.$message({
|
type: "info",
|
message: "已取消更改",
|
});
|
this.dirList = this.old_dirDat; //将备份的dir重新赋值
|
});
|
},
|
sendChange() {
|
updateDirTrees(this.newData).then((res) => {
|
// console.log(res);
|
if (res.code == 200) {
|
this.$message({
|
type: "success",
|
message: "更新成功!",
|
});
|
}
|
});
|
},
|
handleNodeClick(data) {
|
// console.log(data);
|
this.backUpData = JSON.stringify(data);
|
this.itemdetail = JSON.parse(JSON.stringify(data));
|
},
|
updMenu() {
|
this.$message({
|
message: "修改成功",
|
type: "success",
|
});
|
},
|
reset() {
|
this.$message("已取消");
|
},
|
},
|
mounted() {
|
this.getDirTree();
|
},
|
};
|
</script>
|
|
<style lang="less" scoped>
|
.cataSettings_box {
|
border-radius: 10px;
|
height: 100%;
|
padding: 10px;
|
box-sizing: border-box;
|
display: flex;
|
.cataSettings_tree {
|
position: relative;
|
width: 344px;
|
height: 100%;
|
background: rgb(240, 242, 245);
|
padding: 20px;
|
border-radius: 10px;
|
box-sizing: border-box;
|
overflow: auto;
|
.saveBtn {
|
position: absolute;
|
left: 250px;
|
top: 23px;
|
}
|
.cataTreeBox {
|
height: 88%;
|
width: 100%;
|
overflow: auto;
|
.el-tree {
|
background: transparent;
|
font-size: 15px;
|
font-family: Microsoft YaHei;
|
font-weight: 400;
|
color: #000000;
|
/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;
|
}
|
}
|
}
|
}
|
}
|
.itemSettings {
|
width: calc(100% - 344px);
|
border-radius: 10px;
|
background: rgb(240, 242, 245);
|
margin-left: 10px;
|
height: 100%;
|
padding: 10px;
|
box-sizing: border-box;
|
.title_box {
|
background: #fff;
|
padding: 10px;
|
margin-bottom: 24px;
|
display: flex;
|
border-radius: 10px;
|
border: 1px solid rgb(202, 201, 204);
|
box-sizing: border-box;
|
}
|
.form_box {
|
border: 1px solid rgb(202, 201, 204);
|
border-radius: 10px;
|
background: #fff;
|
padding-top: 30px;
|
box-sizing: border-box;
|
width: 100%;
|
.el-input,
|
/deep/ .el-textarea {
|
width: 400px;
|
}
|
.btnBox {
|
margin: 0 270px 20px;
|
width: 200px;
|
display: flex;
|
justify-content: space-between;
|
}
|
}
|
}
|
}
|
</style>
|