<template>
|
<div class="menuSettings_box">
|
<div class="menuSettings_tree">
|
<My-bread
|
:list="[
|
`${$t('operatManage.operatManage')}`,
|
`${$t('operatManage.menuSettings')}`,
|
]"
|
></My-bread>
|
<el-divider />
|
</div>
|
<div class="left_Tree">
|
<el-card class="el-card-define">
|
<div class="card_tree">
|
<el-tree
|
ref="tree"
|
:props="defaultProps"
|
node-key="id"
|
highlight-current
|
:data="menuList"
|
: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
|
v-if="menuStatus.insert"
|
type="text"
|
size="mini"
|
@click="() => append(node, data)"
|
>
|
<i class="el-icon-circle-plus"></i>
|
</el-button>
|
<el-button
|
v-if="menuStatus.delete"
|
type="text"
|
size="mini"
|
@click="() => remove(node, data)"
|
>
|
<i class="el-icon-delete-solid"></i>
|
</el-button>
|
</span>
|
</span>
|
</el-tree>
|
</div>
|
</el-card>
|
</div>
|
<div class="right_menu">
|
<el-card class="el-card-define">
|
<el-breadcrumb separator="/">
|
<el-breadcrumb-item :to="{ path: '/' }">{{
|
$t('dataManage.dictionaryManageObj.particulars')
|
}}</el-breadcrumb-item>
|
</el-breadcrumb>
|
<el-divider />
|
<div class="form_box">
|
<el-form :model="itemdetail" ref="itemdetail" :rules="rules">
|
<el-form-item
|
prop="enName"
|
:label="$t('operatManage.menuSetObj.enName')"
|
:label-width="formLabelWidth"
|
>
|
<el-input
|
clear="el_input"
|
v-model="itemdetail.enName"
|
autocomplete="off"
|
></el-input>
|
</el-form-item>
|
<el-form-item
|
prop="cnName"
|
:label="$t('operatManage.menuSetObj.cnName')"
|
:label-width="formLabelWidth"
|
>
|
<el-input
|
v-model="itemdetail.cnName"
|
autocomplete="off"
|
></el-input>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.icon')"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="itemdetail.icon" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item
|
prop="isShow"
|
:label="$t('operatManage.menuSetObj.isShow')"
|
:label-width="formLabelWidth"
|
>
|
<el-select
|
style="width: 400px"
|
v-model="itemdetail.isShow"
|
placeholder=""
|
>
|
<el-option
|
v-for="item in options1"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.menuUrl')"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="itemdetail.url" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.authorize')"
|
:label-width="formLabelWidth"
|
>
|
<el-input
|
v-model="itemdetail.perms"
|
autocomplete="off"
|
></el-input>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.type')"
|
prop="type"
|
:label-width="formLabelWidth"
|
>
|
<el-select
|
style="width: 400px"
|
v-model="itemdetail.type"
|
:placeholder="$t('common.choose')"
|
>
|
<el-option
|
v-for="item in options2"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.bak')"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="itemdetail.bak" autocomplete="off"></el-input>
|
</el-form-item>
|
<div class="btnBox" v-if="menuStatus.update">
|
<el-button
|
style="
|
background: #409eff;
|
color: white;
|
border: 1px solid #409eff;
|
"
|
@click="updMenu('itemdetail')"
|
>{{ $t('common.confirm') }}</el-button
|
>
|
<el-button @click="reset('itemdetail')">{{
|
$t('common.cancel')
|
}}</el-button>
|
</div>
|
</el-form>
|
</div>
|
</el-card>
|
</div>
|
<el-dialog :title="$t('common.append')" :visible.sync="dialogFormVisible">
|
<el-form :model="ruleForm" ref="ruleForm" :rules="rules">
|
<el-form-item
|
prop="enName"
|
:label="$t('operatManage.menuSetObj.enName')"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="ruleForm.enName" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item
|
prop="cnName"
|
:label="$t('operatManage.menuSetObj.cnName')"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="ruleForm.cnName" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.icon')"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="ruleForm.icon" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item
|
prop="isShow"
|
:label="$t('operatManage.menuSetObj.isShow')"
|
:label-width="formLabelWidth"
|
>
|
<el-select v-model="ruleForm.isShow" placeholder="">
|
<el-option
|
v-for="item in options1"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.menuUrl')"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="ruleForm.url" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.authorize')"
|
:label-width="formLabelWidth"
|
>
|
<el-input v-model="ruleForm.perms" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.type')"
|
prop="type"
|
:label-width="formLabelWidth"
|
>
|
<el-select v-model="ruleForm.type" :placeholder="$t('common.choose')">
|
<el-option
|
v-for="item in options2"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
>
|
</el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item
|
:label="$t('operatManage.menuSetObj.bak')"
|
: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')">{{
|
$t('common.cancel')
|
}}</el-button>
|
<el-button
|
style="background: #409eff; color: white; border: 1px solid #409eff"
|
@click="submitForm('ruleForm')"
|
v-loading.fullscreen.lock="fullscreenLoading"
|
>{{ $t('common.confirm') }}</el-button
|
>
|
</div>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import MyBread from '../../components/MyBread.vue';
|
import {
|
queryMenuAll,
|
updateMenuTree,
|
updateMenuTrees,
|
queryMaxId,
|
insertMenu,
|
deleteMenu,
|
getPerms,
|
} from '../../api/api';
|
export default {
|
//import引入的组件需要注入到对象中才能使用
|
components: {
|
MyBread,
|
},
|
data() {
|
return {
|
menuStatus: {
|
delete: false,
|
insert: false,
|
update: false,
|
},
|
defaultProps: {
|
children: 'children',
|
label: 'cnName',
|
},
|
fullscreenLoading: false,
|
oriData: [], //原始树数据
|
menuList: [], //el树数据
|
old_dirDat: [], //el树数据(拖动前)
|
newData: [], //拖动后原始数据
|
itemdetail: {
|
cnName: '',
|
enName: '',
|
icon: null,
|
isShow: null,
|
perms: null,
|
url: '',
|
type: null,
|
bak: '',
|
},
|
backUpData: '',
|
formLabelWidth: '130px',
|
delChildID: '',
|
delChildIDs: [],
|
dialogFormVisible: false,
|
ruleForm: {
|
level: null,
|
orderNum: null,
|
pid: null,
|
enName: '',
|
cnName: '',
|
icon: '',
|
isShow: null,
|
url: '',
|
perms: null,
|
type: null,
|
bak: '',
|
},
|
rules: {
|
enName: [
|
{ required: true, message: '请输入英文名称', trigger: 'blur' },
|
],
|
cnName: [
|
{ required: true, message: '请输入中文名称', trigger: 'blur' },
|
],
|
|
isShow: [
|
{
|
required: true,
|
message: '请选择是否显示',
|
trigger: 'change',
|
},
|
],
|
type: [
|
{
|
required: true,
|
message: '请选择节点类型',
|
trigger: 'change',
|
},
|
],
|
},
|
// 下拉的option里面的value定义成0,1,不能定义成’0’,'1’字符串,
|
// 如果要定义成字符串,后台需要返回的也是字符串
|
options1: [
|
{
|
value: 0,
|
label: '隐藏',
|
},
|
{
|
value: 1,
|
label: '显示',
|
},
|
],
|
options2: [
|
{
|
value: 0,
|
label: '根目录',
|
},
|
{
|
value: 1,
|
label: '菜单',
|
},
|
{
|
value: 2,
|
label: '按钮',
|
},
|
],
|
};
|
},
|
methods: {
|
getMenuTree() {
|
//获取目录树最大ID,新建节点使用
|
// queryMaxId().then((res) => {
|
// this.id = res.data;
|
// });
|
queryMenuAll().then((res) => {
|
if (res.code == 200) {
|
this.menuList = this.treeData(res.result);
|
this.oriData = res.result;
|
this.newData = 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属性,并赋值
|
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;
|
},
|
resetForm(formName) {
|
this.dialogFormVisible = false;
|
this.$nextTick(() => {
|
this.$refs[formName].resetFields();
|
this.ruleForm = {};
|
});
|
},
|
submitForm(formName) {
|
this.$nextTick(() => {
|
this.$refs[formName].validate((valid) => {
|
if (valid) {
|
this.fullscreenLoading = true;
|
insertMenu(this.ruleForm)
|
.then((res) => {
|
setTimeout(() => {
|
this.fullscreenLoading = false;
|
if (res.code == 200) {
|
this.$message({
|
message: '添加成功',
|
type: 'success',
|
});
|
this.getMenuTree();
|
this.itemdetail = {};
|
this.ruleForm = {};
|
this.dialogFormVisible = false;
|
this.$refs[formName].resetFields();
|
}
|
}, 500);
|
})
|
.catch((res) => {
|
this.itemdetail = {};
|
this.$message.error('添加失败');
|
this.fullscreenLoading = false;
|
console.log(res);
|
});
|
} else {
|
// alert("目录名称不能为空");
|
return false;
|
}
|
});
|
});
|
},
|
remove(node, data) {
|
this.$confirm('此操作将删除该节点, 是否继续?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning',
|
})
|
.then(() => {
|
//兄弟重新排序
|
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
|
this.delChildIDs.push(data.id); //要删除的全部ID
|
let delIDs = this.delChildIDs;
|
Promise.all([
|
deleteMenu({ ids: delIDs.toString() }),
|
updateMenuTrees(children),
|
])
|
.then((res) => {
|
if (res[0].code == 200 && res[1].code == 200) {
|
this.$message({
|
type: 'success',
|
message: '删除成功!',
|
});
|
this.getMenuTree();
|
this.itemdetail = {};
|
} else if (res[0].code == 200) {
|
this.getMenuTree();
|
this.$message.error('删除成功,位置调整失败');
|
} else if (res[1].code == 200) {
|
this.getMenuTree();
|
this.$message.error('删除失败,位置调整成功');
|
} else {
|
this.$message.error('删除失败');
|
}
|
})
|
.catch(() => {
|
this.$message({
|
type: 'error',
|
message: '删除失败',
|
});
|
});
|
|
//重置要删除的子ID
|
this.delChildIDs = [];
|
})
|
.catch(() => {
|
this.$message('已取消删除');
|
});
|
},
|
traverseArr(obj) {
|
if (obj.children) {
|
return obj.children.forEach((item) => {
|
// console.log(item.id + "---" + item.name);
|
// this.delChildID += "id=" + item.id + "&";
|
this.delChildIDs.push(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.menuList)); //将备份的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;
|
//变更节点
|
// console.log(nodeData);
|
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;
|
this.sendChange();
|
})
|
.catch(() => {
|
this.$message({
|
type: 'info',
|
message: '已取消更改',
|
});
|
this.menuList = this.old_dirDat; //将备份的dir重新赋值
|
});
|
},
|
sendChange() {
|
this.newData.forEach((item) => {
|
if (item.pid == 0) {
|
item.type = 0;
|
}
|
});
|
updateMenuTrees(this.newData)
|
.then((res) => {
|
if (res.code == 200) {
|
this.getMenuTree();
|
return;
|
} else {
|
alert('调整失败,请重试!');
|
}
|
})
|
.catch(() => {
|
alert('修改失败,请重试!');
|
});
|
},
|
handleNodeClick(data) {
|
// console.log(data);
|
this.backUpData = JSON.stringify(data);
|
this.itemdetail = JSON.parse(JSON.stringify(data));
|
},
|
updMenu(formName) {
|
this.$nextTick(() => {
|
this.$refs[formName].validate((valid) => {
|
if (valid) {
|
this.fullscreenLoading = true;
|
updateMenuTree(this.itemdetail)
|
.then((res) => {
|
setTimeout(() => {
|
this.fullscreenLoading = false;
|
if (res.code == 200) {
|
this.getMenuTree();
|
this.itemdetail = {};
|
this.dialogFormVisible = false;
|
this.$refs[formName].resetFields();
|
}
|
}, 500);
|
})
|
.catch((res) => {
|
alert('修改失败,请重试!');
|
this.fullscreenLoading = false;
|
});
|
} else {
|
return false;
|
}
|
});
|
});
|
},
|
reset(formName) {
|
this.$refs[formName].resetFields();
|
if (this.backUpData != '') {
|
this.itemdetail = JSON.parse(this.backUpData);
|
}
|
},
|
showPermsMenu(res) {
|
switch (res.tag) {
|
case '/delete':
|
this.menuStatus.delete = true;
|
break;
|
case '/insert':
|
this.menuStatus.insert = true;
|
break;
|
case '/update':
|
this.menuStatus.update = true;
|
break;
|
}
|
},
|
getPerms() {
|
var val = this.$store.state.currentPerms;
|
var permsEntity = this.$store.state.permsEntity;
|
if (permsEntity.length == 0) {
|
getPerms().then((res) => {
|
if (res.code == 200) {
|
permsEntity = res.result;
|
}
|
});
|
}
|
for (var i = 0; i < permsEntity.length; i++) {
|
if (permsEntity[i].perms == val) {
|
this.showPermsMenu(permsEntity[i]);
|
}
|
}
|
},
|
},
|
mounted() {
|
this.getMenuTree();
|
this.getPerms();
|
},
|
created() {},
|
};
|
</script>
|
<style lang="less" scoped>
|
//@import url(); 引入公共css类
|
.menuSettings_box {
|
width: 100%;
|
height: 100%;
|
position: relative;
|
box-sizing: border-box;
|
.left_Tree {
|
width: 15%;
|
height: 100%;
|
position: relative;
|
float: left;
|
box-sizing: border-box;
|
overflow-y: auto;
|
.el-icon-circle-plus {
|
color: gray;
|
}
|
.el-icon-delete-solid {
|
color: gray;
|
}
|
}
|
.right_menu {
|
width: 84%;
|
float: right;
|
.form_box {
|
box-sizing: border-box;
|
width: 100%;
|
.el-input {
|
width: 400px;
|
}
|
|
/deep/.el-form-item__label {
|
color: white;
|
}
|
}
|
}
|
.el-card-define {
|
height: 680px;
|
background: #303030;
|
border: 1px solid gray;
|
padding: 1px;
|
}
|
.card_tree {
|
display: block;
|
height: 650px;
|
overflow-y: auto;
|
// 更改指标树图标颜色
|
/deep/ .el-tree .el-icon-caret-right:before {
|
color: white; /** 这里是要修改图标的颜色 **/
|
}
|
/deep/ .el-tree {
|
color: white; /** 这里是要修改图标的颜色 **/
|
background: transparent;
|
}
|
/deep/.el-tree-node__content {
|
&:hover {
|
background-color: rgba(255, 255, 255, 0.3) !important;
|
}
|
}
|
/deep/.el-tree-node.is-current > .el-tree-node__content {
|
background-color: rgba(255, 255, 255, 0.3) !important;
|
color: #409eff;
|
}
|
}
|
/deep/ .el-input__inner {
|
background-color: transparent !important;
|
border: 1px solid;
|
color: white;
|
}
|
/deep/ .el-dialog {
|
background: #303030;
|
}
|
/deep/.el-range-editor.is-active,
|
.el-range-editor.is-active:hover,
|
.el-select .el-input.is-focus .el-input__inner {
|
border: 1px solid;
|
}
|
/deep/.el-dialog__title {
|
color: white;
|
}
|
/deep/.el-form-item__label {
|
color: white;
|
}
|
|
/*里面的代码可以根据自己需求去进行更改*/
|
/* 设置滚动条的样式 */
|
::-webkit-scrollbar {
|
width: 4px;
|
}
|
/* 滚动槽 */
|
::-webkit-scrollbar-track {
|
-webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.3);
|
border-radius: 10px;
|
}
|
/* 滚动条滑块 */
|
::-webkit-scrollbar-thumb {
|
border-radius: 10px;
|
background: #8b8b8b;
|
-webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.5);
|
}
|
::-webkit-scrollbar-thumb:window-inactive {
|
background: #8b8b8b;
|
height: 289px;
|
}
|
}
|
</style>
|
<style lang="less">
|
.el-select-dropdown {
|
background: #303030;
|
border-color: white;
|
}
|
//右侧和下方的白边
|
.el-scrollbar__wrap {
|
margin-bottom: -20px !important;
|
margin-right: -20px !important;
|
}
|
.el-select-dropdown__item.hover,
|
.el-select-dropdown__item:hover {
|
background: rgba(255, 255, 255, 0.3);
|
}
|
.el-select-dropdown__item {
|
color: white;
|
}
|
</style>
|