描述
问题是这样:我的项目中,有一个角色管理的页面。以前的老代码,直接用el-tree渲染的树形结构,勾选设置对应的权限。其他的部门倒是还好,但是涉及到老板的部门设置的时候,由于我们这边的权限太多,部门也特别多,而老板又是有很多的权限,导致我们一次需要渲染出一大堆的tree结构之外,还需要回显一大堆的勾选。这就导致别的人设置可以,但是老板设置权限的时候就会卡住几十秒,甚至卡死浏览器。所以没办法,只能动手优化一下老代码,让他快一点。
效果图
这样的属性结构,有很多的层级
解决办法
el-tree懒加载的功能,一层一层的加载,让页面不会把所有的结构和回显的数据全部在第一次进来的时候加载,就不会卡顿了。
我这里先说一下实现思路,最后会把整页的代码放在最下面,不过因为老代码多,懒得删改了,就自行在代码里找一下吧。
功能实现思路
1,数据量过大,由于是多层级嵌套的,数据又多,接口请求拿到数据的时间倒是不多,但是数据那么大一次性渲染出节点会非常卡。所以第一步是把数据拆分。我首先把数据拿到了然后循环把第一层单独抽出来放到一个数组,全部的数据也保存一份用于后续抽取子级。抽取第一层,然后把子级设置为空。这样数据就很少了。先用来渲染出一层的节点。
2,有了一层的节点,我们设置懒加载。el-tree的懒加载设置方法很简单,就是直接在tree标签上加:load="loadNode"和lazy和node-key=“id”,方法loadNode就是懒加载的方法,通过resolve来给节点添加子级数组。我首先通过这个方法自带的属性node拿到当前点击展开的节点信息,用这个节点的ID递归查找原本的我备份的所有数据的数组,找到对应ID的位置拿到他的子级数组。然后把子级数组resolve返回就完成了懒加载。
3,这时候数据有了。结构也展示出来了,可以一层层的懒加载了,我们需要解决的就是回显的问题。这个我也是想了很久想到的一个办法。首先你需要断掉tree的父子关联,在el-tree标签上写:check-strictly=“checkStrictly”。这个checkStrictly变量内容是false。这句话的意思就是不建立父子关联。为什么呢。因为如果你有了父子关联,那么你回显的时候如果有父级的id在,父级会选中,同时导致把所有子级全部选中。这是不对的,因为有时候我们可能子级并没有全部选中。那解决办法就是把父子关联断掉。这样回显的时候就各自勾选。不会影响其他没被勾选的节点。
如何回显勾选?就是在tree上写:default-checked-keys=“expandedKeysd”。这代表选中的节点ID数组。至于数组从哪里来,当然是后端返回给你的已勾选的id数组了,自行处理成你要的ID数组。数组中包含父级和子级的id。父级懒加载展开后子级出现了,会自动被勾选上的。
4,这时候我们已经可以正常回显数据了,也可以懒加载展开了。但是还有问题。那就是我们如果断了父子关联,那我们需要点击很多次很麻烦,我们还是想要点一次就把子级全选或者全部不选怎么处理这个问题呢?解决办法是通过这个来处理。在tree上写@check-change=“handleCheckAllChange”,这个方法代表了点击勾选框触发的方法。
这里的主要方法是setChecked。逻辑很简单,就是当我点击了某一个节点的多选框。触发这个方法。在这个方法内,我直接把原本备份的完整数组哪来循环一遍,根据我现在点击的节点的ID去找到对应的节点下面所有的子级,并把子级的ID汇合成一个数组。然后我再把这个数组去重,保证不重复。然后我就可以利用这个数组来循环,把每一个ID都通过setChecked方法勾选或者取消勾选。这样就完成了点一个节点,所有子级一起取消勾选,或者被选中。然后在这同时,如果我点击的是勾选。那么就把所有子级也保存在回显数组expandedKeysd中一份。如果是取消,就在expandedKeysd中找一下有没有这些子级中的id。有就都给删了。这样我就实现了维护一个回显数组的循环。使得这个数组中一直都是最新的勾选数据ID。
5,最后就是保存了。因为前面我说了,后端给我的回显数据id数组我保存在这个expandedKeysd方法内。同时,后续操作,我点击节点全选或者取消全选也是一直在维护这个数组。增加或者删除ID。所以这个ID数组就是最新的勾选数据。我们直接把这个数组给到后端就搞定了。
到这里逻辑就讲完了。逻辑其实不复杂。下面放出这个页面的完整代码,因为很多老代码,我只是改了一下功能。懒得删除了,大家根据上面的逻辑对付着看看吧。
完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="/statics/js/jquery.min.js"></script>
<script src="/statics/vue_element/common.js"></script>
<link rel="stylesheet" href="/statics/vue_element/index.css">
<link rel="stylesheet" href="/statics/vue_element/element.css">
<script src="/statics/vue_element/vue.js"></script>
<script src="/statics/vue_element/element.js"></script>
<script src="/statics/vue_element/axios.js"></script>
</head>
<style>
.showing {
overflow-y: scroll;
padding-right: 10px;
}
.showing::-webkit-scrollbar {
width: 5px;
height: 10px;
background-color: #b5b1b1;
}
.showing::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
border-radius: 10px;
background-color: white;
}
.showing::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
background-color: #b5b1b1;
}
.borde {
width: 100%;
overflow-y: auto;
border: 1px solid #ebeef5;
border-radius: 3px;
margin-top: 10px;
margin-left: 0;
margin-bottom: 10px;
}
.el-input-group__prepend {
width: 55px;
}
.spantop {
margin-top: 20px;
}
.el-form-item {
margin-bottom: 5px !important;
}
.is-error {
margin-bottom: 18px !important;
}
.el-tree-node.is-checked.is-expanded>.el-tree-node__content {
background-color: #EDEDED !important;
color: #409EFF !important;
}
.el-tree-node.is-current>.el-tree-node__content {
background-color: #EDEDED !important;
color: #409EFF !important;
}
.listTrees>.el-tree-node.is-checked.is-expanded>.el-tree-node__content {
color: #409EFF !important;
}
.listTrees>.el-tree-node.is-current>.el-tree-node__content {
color: #409EFF !important;
}
</style>
<body>
<div id="app" v-cloak>
<div class="ibox-content">
<el-tabs @tab-click="jsqh">
<el-tab-pane label="角色管理">
<el-row :gutter="20">
<el-col :span="4">
<div style="margin-bottom:10px;">
<el-input v-model="title" style="max-width: 250px;" size="small" @change="changed"
placeholder="请输入角色名称"></el-input>
</div>
<div :style="constyle" class="showing" v-loading="loadings">
<el-tree :data="data" ref="tree" node-key="id" class="listTree" :props="props"
:default-expanded-keys="openkeys" @node-click="handleNodeClick">
</el-tree>
</div>
</el-col>
<el-col :span="20">
<div v-if="lb_js=='1'">
<span>添加子菜单</span>
<el-form ref="form" :model="form" :rules="rule" label-width="120px">
<el-form-item label="角色类别">
<el-input v-model="form.role_lbname" disabled style="max-width: 400px;"
size="small">
</el-input>
</el-form-item>
<el-form-item label="角色名称" prop="rolename">
<el-input v-model="form.rolename" style="max-width: 400px;" size="small">
</el-input>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input v-model.number="form.sort" type="number" style="max-width: 400px;"
size="small">
</el-input>
</el-form-item>
<el-form-item label="管理菜单">
<el-tabs v-model="activeName" type="border-card">
<el-tab-pane label="PC端" name="1">
<div class="borde showinsty" :style="heighted">
<el-tree :data="label_data" class="listTrees" ref="tree_add"
show-checkbox node-key="id" v-loading="loadingeds"
:default-checked-keys="checkeys" :props="defaultProps">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span v-if="data.modules!==''">
<el-checkbox-group v-model="data.power_new"
style="display: inline-block;">
<el-checkbox
v-for="item in data.modules.split(',')"
:label="item" :key="item">{{item}}
</el-checkbox>
</el-checkbox-group>
</span>
</span>
</el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="钉钉端" name="4">
<div class="borde showinsty" :style="heighted">
<el-tree :data="ding_data" class="listTrees" ref="ding_tree_add"
show-checkbox node-key="id" v-loading="loadingeds"
:default-checked-keys="ding_checkeys"
:props="ding_defaultProps">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span v-if="data.modules!==''">
<el-checkbox-group v-model="data.power_new"
style="display: inline-block;">
<el-checkbox
v-for="item in data.modules.split(',')"
:label="item" :key="item">{{item}}
</el-checkbox>
</el-checkbox-group>
</span>
</span>
</el-tree>
</div>
</el-tab-pane>
</el-tabs>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="role_addsub('form')" size="small">提 交
</el-button>
<el-button @click="role_back('form')" size="small">重 置</el-button>
</el-form-item>
</el-form>
</div>
<div v-if="lb_js=='2'">
<span>编辑菜单</span>
<el-form ref="forms" :model="forms" :rules="rules" label-width="120px">
<el-form-item label="角色类别" prop="role_lbname">
<div style="max-width: 400px;">
<el-select v-model="forms.role_lbname" placeholder="请选择" size="small"
style="width: 100%;">
<el-option v-for="(item,index) in data" :key="index"
:label="item.name" :value="item.id"></el-option>
</el-select>
</div>
</el-form-item>
<el-form-item label="角色名称" prop="rolename">
<el-input v-model="forms.rolename" style="max-width: 400px;" size="small">
</el-input>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input v-model.number="forms.sort" type="number"
style="max-width: 400px;" size="small">
</el-input>
</el-form-item>
<el-form-item label="管理菜单">
<el-tabs v-model="activeNamed" type="border-card" @tab-click="changeCd">
<el-tab-pane label="PC端" name="1">
<div class="borde showinsty" :style="heighted">
<el-tree :data="label_dataed" class="listTrees" ref="tree_edit"
show-checkbox node-key="id" v-loading="loadinged"
:props="defaultPropsd" :load="loadNode" lazy
:default-checked-keys="expandedKeysd"
:default-expanded-keys="[]" :check-strictly="checkStrictly"
@check-change="handleCheckAllChange">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span v-if="data.modules!==''"
@click="getInfo(node,data)">
<el-checkbox-group v-model="data.power_new"
style="display: inline-block;">
<el-checkbox
v-for="item in data.modules.split(',')"
:label="item" :key="item">{{item}}
</el-checkbox>
</el-checkbox-group>
</span>
</span>
</el-tree>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="小程序端" name="2">
<div class="borde showinsty" :style="heighted">
<el-tree :data="xcx_dataed" class="listTrees"
ref="xcx_tree_edit" show-checkbox node-key="id"
v-loading="loadinged" :default-checked-keys="xcx_checkeysd"
:default-expanded-keys="xcx_expandedKeysd"
:props="xcx_defaultPropsd">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span v-if="data.modules!==''">
<el-checkbox-group v-model="data.power_new"
style="display: inline-block;">
<el-checkbox
v-for="item in data.modules.split(',')"
:label="item" :key="item">{{item}}
</el-checkbox>
</el-checkbox-group>
</span>
</span>
</el-tree>
</div>
</el-tab-pane>
<el-tab-pane label="营销渠道报表标题" name="3">
<div class="borde showinsty" :style="heighted">
<el-tree :data="qdyx_dataed" class="listTrees"
ref="qdyx_tree_edit" show-checkbox node-key="id"
v-loading="loadinged" :default-checked-keys="checkeysd"
:default-expanded-keys="qdyx_expandedKeysd"
:props="qdyx_defaultPropsd">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span v-if="data.modules!==''">
<el-checkbox-group v-model="data.power_new"
style="display: inline-block;">
<el-checkbox
v-for="item in data.modules.split(',')"
:label="item" :key="item">{{item}}
</el-checkbox>
</el-checkbox-group>
</span>
</span>
</el-tree>
</div>
</el-tab-pane> -->
<el-tab-pane label="钉钉端" name="4">
<div class="borde showinsty" :style="heighted">
<el-tree :data="ding_dataed" class="listTrees"
ref="ding_tree_edit" show-checkbox node-key="id"
v-loading="loadinged" :default-checked-keys="ding_checkeysd"
:default-expanded-keys="ding_expandedKeysd"
:props="ding_defaultPropsd">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span v-if="data.modules!==''">
<el-checkbox-group v-model="data.power_new"
style="display: inline-block;">
<el-checkbox
v-for="item in data.modules.split(',')"
:label="item" :key="item">{{item}}
</el-checkbox>
</el-checkbox-group>
</span>
</span>
</el-tree>
</div>
</el-tab-pane>
</el-tabs>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="role_editsub('forms')" size="small">提 交
</el-button>
</el-form-item>
</el-form>
</div>
</el-col>
</el-row>
</el-tab-pane>
<el-tab-pane label="角色类别">
<div :style="constyle" class="showing">
<div class="add_tit">
<div class="title_btn m-t-n-xs">
<el-button size="small" @click="js_add" type="primary">添加</el-button>
</div>
</div>
<el-table :data="tableData" style="width: 100%" v-loading="loading" border>
<el-table-column label="类别名称">
<template slot-scope="{ row, $index }">
<el-input v-if="editIndex === $index" size="mini" v-model.trim="row.name"
placeholder="请输入内容"></el-input>
<span v-else>{{row.name}}</span>
</template>
</el-table-column>
<el-table-column label="排序">
<template slot-scope="{ row, $index }">
<el-input v-if="editIndex === $index" size="mini" v-model.trim="row.px"
placeholder="请输入排序"></el-input>
<span v-else>{{row.px}}</span>
</template>
</el-table-column>
<el-table-column label="添加人" prop="author"></el-table-column>
<el-table-column label="添加时间" prop="created_at"></el-table-column>
<el-table-column label="操作">
<template slot-scope="{ row, $index }">
<div v-if="editIndex === $index">
<el-button size="mini" type="success" @click="handleSave(row, $index)">保存
</el-button>
<el-button size="mini" @click="cancel">取消</el-button>
</div>
<div v-else>
<el-button size="mini" type="primary" @click="handleEdit(row, $index)">操作
</el-button>
<el-button size="mini" type="danger" @click="handleDeleted(row, $index)">删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</body>
<script>
new Vue({
el: '#app',
data() {
return {
loadingeds: false,
loadinged: false,
loadings: false,
openkeys: [],
title: '',
loading: false,
tableData: [],
editIndex: -1,
lbjs_id: '0',
// 左侧树形数据
data: [],
props: {
label: 'name',
children: 'children_role'
},
constyle: {
height: window.innerHeight - 120 + "px",
},
heighted: {
height: window.innerHeight - 370 + "px",
},
lb_js: '',
lbid_jsid: '',
//添加 树形数据
label_data: [],
xcx_data: [],
ding_data: [],
qdyx_data: [],
checkeys: [],
xcx_checkeys: [],
ding_checkeys: [],
activeName: '1',
defaultProps: {
children: 'children',
label: 'title'
},
xcx_defaultProps: {
children: 'children',
label: 'title'
},
ding_defaultProps: {
children: 'children',
label: 'title'
},
qdyx_defaultProps: {
children: 'children',
label: 'name'
},
form: {
rolename: '',
role_lbname: '',
sort: null,
},
rule: {
rolename: [{
required: true,
message: '请输入角色名称',
trigger: 'blur'
}]
},
lb_options: [],
//编辑 树形数据
label_dataed: [],
xcx_dataed: [],
ding_dataed: [],
qdyx_dataed: [],
checkeysd: [],
xcx_checkeysd: [],
ding_checkeysd: [],
expandedKeysd: [],
xcx_expandedKeysd: [],
ding_expandedKeysd: [],
qdyx_expandedKeysd: [],
activeNamed: '1',
defaultPropsd: {
children: 'children',
label: 'title',
isLeaf: 'leaf'
},
xcx_defaultPropsd: {
children: 'children',
label: 'title'
},
ding_defaultPropsd: {
children: 'children',
label: 'title'
},
qdyx_defaultPropsd: {
children: 'children',
label: 'name'
},
forms: {
rolename: '',
role_lbname: '',
sort: null,
},
rules: {
role_lbname: [{
required: true,
message: '请选择角色类别',
trigger: 'change'
}],
rolename: [{
required: true,
message: '请输入角色名称',
trigger: 'blur'
}]
},
lbid: '',
dataed: {},
lable_list: [],
checkStrictly: true, //父子不关联
lister: [], //权限列表
btnList: [], //权限按钮列表
}
},
mounted() {
let that = this;
that.hospital_id = userinfo.hospital_id
that.admin_id = userinfo.admin_id
that.name = userinfo.name
that.begin()
},
methods: {
// 获取菜单后按钮数据
getInfo(node, data) {
let that = this
let n = 0
this.btnList.forEach(item => {
if (item.id == data.id) {
setTimeout(function () {
item.power_new = data.power_new
if (item.power_new.length == 0) {
item.power_new = ['search']
}
}, 100)
n--
} else {
n++
}
})
if (n == this.btnList.length) {
let lt = ['search']
setTimeout(function () {
that.btnList.push({
id: data.id,
power_new: lt.concat(data.power_new)
})
}, 100)
}
setTimeout(function () {
let map = new Map();
for (let item of that.btnList) {
if (!map.has(item.id)) {
map.set(item.id, item);
}
}
that.btnList = [...map.values()]
}, 150)
},
// tree懒加载
loadNode(node, resolve) {
let that = this
let arr = this.findChildrenById(that.lable_list, node.key)//递归拿到对应节点ID的子级数组
this.lister.forEach(item => {
arr.forEach(i => {
if (item.id == i.id) {
i.power_new = item.power_new
}
})
})
// 这里必须要用这个定时器或者nextTick。不然不执行
setTimeout(() => {
if (arr == undefined) {
resolve([]); //如果没有子级了给空数组,点击后展开小箭头会消失
} else {
resolve(arr);//如果有子级就把数组返回,就可以展开子级了。
}
}, 500);
},
// 递归
findChildrenById(arr, id) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id === id) {
return arr[i].children || [];
}
if (Array.isArray(arr[i].children)) {
const result = this.findChildrenById(arr[i].children, id);
if (result.length > 0) {
return result;
}
}
}
return [];
},
jsqh(name) {
if (name.label == '角色类别') {
this.lbbegin()
} else {
this.begin()
}
},
// 切换tab
changeCd(val) {
if (val.label == 'PC端') {
return
axios
.post("/api/menu_list", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
type: 1
})
.then(response => {
this.label_dataed = response.data.data.data
axios
.post("/api/getRoleMenu", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
role_id: this.lbid,
type: 1
})
.then(res => {
let that = this
let lister = res.data.data.menu.power
// 小程序端回显
if (res.data.data.menu) {
let llr = []
for (var i = 0; i < lister.length; i++) {
var returnedItem = {};
var find = function (arr, id) {
arr.forEach(item => {
if (item.id == id) {
item.power_new = lister[i]
.power_new
returnedItem = item;
return item;
} else if (item.children !==
undefined) {
find(item.children, id);
}
})
}
var item = find(that.label_dataed, lister[i].id);
llr.push(returnedItem.id)
if (llr.length > 0) {
setTimeout(function () {
llr.forEach((value) => {
that.$refs.tree_edit
.setChecked(value,
true,
false)
})
}, 50);
that.expandedKeysd.push(returnedItem.id)
}
}
}
})
.catch(error => {})
})
.catch(error => {})
return
}
if (val.label == '钉钉端') {
let that = this
axios
.post("/api/menu_list", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
type: 2
})
.then(response => {
this.ding_dataed = response.data.data.data
that.loadinged = true
axios
.post("/api/getRoleMenu", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
role_id: this.lbid,
type: 2
})
.then(res => {
let that = this
let ding_lister = res.data.data.menu.power
// 钉钉端回显
if (res.data.data.menu) {
var ding_llr = []
for (var i = 0; i < ding_lister.length; i++) {
var dd_returnedItem = {};
var dd_find = function (arr, id) {
arr.forEach(xcx_item => {
if (xcx_item.id == id) {
xcx_item.power_new =
ding_lister[i]
.power_new
dd_returnedItem = xcx_item;
return xcx_item;
} else if (xcx_item.children !==
undefined) {
dd_find(xcx_item.children, id);
}
})
}
var xcx_item = dd_find(that.ding_dataed, ding_lister[i]
.id);
ding_llr.push(dd_returnedItem.id)
if (ding_llr.length > 0) {
setTimeout(function () {
ding_llr.forEach((value) => {
that.$refs.ding_tree_edit
.setChecked(
value, true,
false)
})
}, 50);
that.ding_expandedKeysd.push(xcx_returnedItem.id)
}
}
}
that.loadinged = false
})
.catch(error => {})
})
.catch(error => {})
return
}
},
//类别查询
lbbegin() {
let that = this
that.loading = true
axios
.post(apiadmin_url + "5e23ed7284053", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
that.tableData = response.data.data
that.loading = false
})
.catch(error => {})
},
//类别添加
js_add() {
let that = this
var len = that.tableData.length
if (len > 0) {
if (that.tableData[len - 1].name == '') {
that.$alert('请先保存数据')
} else {
that.editIndex = len
var obj = {
id: '0',
name: ''
}
that.tableData.push(obj)
}
} else {
that.editIndex = len
var obj = {
id: '0',
name: ''
}
that.tableData.push(obj)
}
},
//类别编辑
handleEdit(row, index) {
let that = this
that.editIndex = index
that.lbjs_id = row.id
},
//类别的返回
cancel() {
let that = this
that.editIndex = -1
that.lbbegin()
},
//类别的添加的保存
handleSave(row, index) {
let that = this
if (row.name == '') {
that.$alert('类别名称不能为空')
} else {
axios
.post(apiadmin_url + "5e23ee6be14a9", {
id: that.lbjs_id,
name: row.name,
px: row.px,
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
if (response.data.code == '200') {
that.editIndex = -1
that.lbbegin()
that.$message({
showClose: true,
message: '添加成功'
});
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
},
//类别的删除
handleDeleted(row, index) {
let that = this
if (row.id == '0') {
that.tableData.splice(index, 1)
} else {
that.$confirm('此操作将永久删除该信息, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
axios
.post(apiadmin_url + "5e23ef1f306a4", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
id: row.id,
author: userinfo.name,
})
.then(response => {
if (response.data.code == '200') {
that.lbbegin()
that.$message({
type: 'success',
message: '删除成功!'
});
} else {
alert(response.data.message)
}
})
.catch(error => {})
}).catch(() => {
that.$message({
type: 'info',
message: '已取消删除'
});
});
}
},
// ****************************************
//搜索角色
changed() {
let that = this
that.loadings = true
that.openkeys = []
that.$refs.tree.setCheckedKeys(that.openkeys);
for (var i = 0; i < that.$refs.tree.store._getAllNodes().length; i++) {
that.$refs.tree.store._getAllNodes()[i].expanded = false;
}
that.data.forEach(i => {
i.children_role.forEach(element => {
if (element.name.includes(that.title)) {
that.openkeys.push(element.id)
that.$refs.tree.setCheckedKeys(that.openkeys);
}
})
})
that.loadings = false
},
//查询机构数据
begin() {
let that = this
that.loadings = true
axios
.post(apiadmin_url + "getRoleIndex", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
that.data = response.data.data
that.loadings = false
})
.catch(error => {})
},
//添加点击菜单展示
menu_list() {
let that = this
that.loadingeds = true
axios
.post("/api/menu_list", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
type: 1
})
.then(response => {
that.loadingeds = false
that.label_data = response.data.data.data
that.xcx_data = response.data.data.data_xcx
that.qdyx_data = response.data.data.data_qdyx
that.ding_data = response.data.data.data_ding
})
.catch(error => {})
},
//添加 的角色提交
role_addsub(formName) {
let that = this
that.$refs[formName].validate((valid) => {
if (valid) {
// 1 代表是pc端
if (that.activeName == '1') {
var res = []
var res_id = []
// 获取pc端点击的菜单
var arr = this.$refs.tree_add.getCheckedNodes().concat(this.$refs
.tree_add.getHalfCheckedNodes())
arr.forEach(element => {
res_id.push(element.id)
let obj = {
id: '',
power: []
}
obj.id = element.id
if (element.power_new) {
obj.power = element.power_new
} else {
obj.power = ['search']
}
res.push(obj)
});
if (arr.length < 1) {
that.$alert('请勾选菜单')
return false;
}
axios
.post(apiadmin_url + "5e23f13dd9c9d", {
id: '0',
role_type_id: that.lbid_jsid,
name: that.form.rolename,
sort: that.form.sort,
menu_list: res_id,
power_list: res,
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
if (response.data.code == '200') {
that.$message({
type: 'success',
message: '添加成功!'
});
that.begin()
that.role_back()
that.menu_list()
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
// 2代表的是小程序端
if (that.activeName == '2') {
var xcx_res = []
var xcx_res_id = []
// 获取小程序点击的菜单
var xcx_arr = this.$refs.xcx_tree_add.getCheckedNodes().concat(this
.$refs.xcx_tree_add.getHalfCheckedNodes())
xcx_arr.forEach(element => {
xcx_res_id.push(element.id)
let xcx_obj = {
id: '',
power: []
}
xcx_obj.id = element.id
if (element.power_new) {
xcx_obj.power = element.power_new
} else {
xcx_obj.power = ['search']
}
xcx_res.push(xcx_obj)
});
if (xcx_arr.length < 1) {
that.$alert('请勾选菜单')
return false;
}
axios
.post(apiadmin_url + "5e23f13dd9c9d", {
id: '0',
role_type_id: that.lbid_jsid,
name: that.form.rolename,
sort: that.form.sort,
menu_xcx_list: xcx_res_id,
power_xcx_list: xcx_res,
menu_list: '',
power_list: '',
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
if (response.data.code == '200') {
that.$message({
type: 'success',
message: '添加成功!'
});
that.begin()
that.role_back()
that.menu_list()
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
// 4代表的是钉钉端
if (that.activeName == '4') {
var ding_res = []
var ding_res_id = []
// 获取小程序点击的菜单
var ding_arr = this.$refs.ding_tree_add.getCheckedNodes().concat(this
.$refs.ding_tree_add.getHalfCheckedNodes())
ding_arr.forEach(element => {
ding_res_id.push(element.id)
let ding_obj = {
id: '',
power: []
}
ding_obj.id = element.id
if (element.power_new) {
ding_obj.power = element.power_new
} else {
ding_obj.power = ['search']
}
ding_res.push(ding_obj)
});
if (ding_arr.length < 1) {
that.$alert('请勾选菜单')
return false;
}
axios
.post(apiadmin_url + "5e23f13dd9c9d", {
id: '0',
role_type_id: that.lbid_jsid,
name: that.form.rolename,
sort: that.form.sort,
menu_xcx_list: xcx_res_id,
power_xcx_list: xcx_res,
ding_xcx_list: ding_res_id,
ding_power_xcx_list: ding_res,
menu_list: '',
power_list: '',
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
if (response.data.code == '200') {
that.$message({
type: 'success',
message: '添加成功!'
});
that.begin()
that.role_back()
that.menu_list()
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
//3渠道营销报表
if (that.activeName == '3') {
var qdyx_res = []
// 获取小程序点击的菜单
var qdyx_arr = this.$refs.qdyx_tree_add.getCheckedNodes()
if (qdyx_arr.length < 1) {
that.$alert('请勾选菜单')
return false;
}
qdyx_arr.forEach(element => {
qdyx_res.push(element.id)
});
var obj = qdyx_res.toString()
axios
.post(apiadmin_url + "5e23f13dd9c9d", {
id: '0',
role_type_id: that.lbid_jsid,
name: that.form.rolename,
sort: that.form.sort,
channel_report_auth: obj,
menu_list: '',
power_list: '',
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
if (response.data.code == '200') {
that.$message({
type: 'success',
message: '添加成功!'
});
that.begin()
that.role_back()
that.menu_list()
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
} else {
that.$alert('请输入角色名称')
}
});
},
//添加的重置
role_back(formName) {
let that = this
that.form.rolename = ''
that.form.sort = null
that.$refs[formName].resetFields();
// 1代表的是PC端
if (that.activeName == '1') {
that.openkeys = []
that.$refs.tree_add.setCheckedKeys(that.openkeys)
}
// 2代表的是小程序端
if (that.activeName == '2') {
that.openkeys = []
that.$refs.xcx_tree_add.setCheckedKeys(that.openkeys)
}
},
//点击角色管理设置菜单
handleNodeClick(data) {
let that = this
that.openkeys = []
that.$refs.tree.setCheckedKeys(that.openkeys);
that.loadinged = true
that.dataed = data
that.lb_js = data.lb_js
that.lbid_jsid = data.id
that.lbid = data.id
if (that.lb_js == '1') {
that.activeName = '1'
that.menu_list()
that.form.role_lbname = data.name
} else {
that.activeNamed = '1'
// that.select_lb()
that.forms.role_lbname = data.role_type_id
that.forms.rolename = data.name
that.forms.sort = data.sort
// pc端回显参数
that.label_dataed = []
that.expandedKeysd = []
let userPowerList = JSON.parse(sessionStorage.getItem('userPowerList')) //本地获取菜单
//本地没有菜单就加载菜单
if (userPowerList == null) {
axios
.post("/api/menu_list", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
type: 1
})
.then(response => {
that.loadinged = false
this.lable_list = JSON.parse(JSON.stringify(response.data.data.data)) //深拷贝,不然两个数组互相影响
sessionStorage.setItem('userPowerList', JSON.stringify(this.lable_list)) //本地缓存结构,下次直接本地拿,不发请求了
let lable_map = response.data.data.data
// 只取第一层
lable_map.forEach(item => {
if (item.children) {
item.children = []
that.label_dataed.push(item)
} else {
that.label_dataed.push(item)
}
})
that.loadinged = true
//回显请求
axios
.post("/api/getRoleMenu", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
role_id: this.lbid,
type: 1,
})
.then(res => {
let that = this
this.lister = res.data.data.menu.power
this.btnList = JSON.parse(JSON.stringify(res.data.data.menu
.power)) //按钮权限
// pc端回显
if (res.data.data.menu) {
that.expandedKeysd = res.data.data.menu.stru.map(
Number) //回显勾选菜单
}
that.loadinged = false
})
.catch(error => {})
})
.catch(error => {})
} else {
this.lable_list = JSON.parse(JSON.stringify(userPowerList))
let lable_map = userPowerList
// 只取第一层
lable_map.forEach(item => {
if (item.children) {
item.children = []
that.label_dataed.push(item)
} else {
that.label_dataed.push(item)
}
})
axios
.post("/api/getRoleMenu", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
role_id: this.lbid,
type: 1,
})
.then(res => {
let that = this
this.lister = res.data.data.menu.power
this.btnList = JSON.parse(JSON.stringify(res.data.data.menu
.power)) //按钮权限
// pc端回显
if (res.data.data.menu) {
that.expandedKeysd = res.data.data.menu.stru.map(
Number) //回显勾选菜单
}
that.loadinged = false
})
.catch(error => {})
}
}
},
// 勾选tree和取消tree
handleCheckAllChange(val, type, name) {
let that = this
let searchData = this.findChildrenById(that.lable_list, val.id) //获取勾选的节点完整数据
let arr = []
let arr2 = [val.id].concat(this.getAllId(arr, searchData)) //获取勾选的节点包含下面所有子级的id形成数组
if (type == true) {
// 勾选:如果勾选数组中没有这个id就添加进去
if (this.expandedKeysd.includes(val.id) == false) {
let list = this.expandedKeysd.concat(arr2) //勾选的节点的所有子级合并
this.expandedKeysd = Array.from(new Set(list)) //去重
arr2.forEach(item => {
setTimeout(function () {
// 勾选
that.$refs.tree_edit.setChecked(item,
true,
false)
}, 50);
})
}
} else {
// 取消勾选:id是已勾选状态就删除对应的id
if (this.expandedKeysd.includes(val.id) == true) {
// 删除选中的节点包含所有子节点勾选(两个数组比较,相同的删除)
this.expandedKeysd = this.expandedKeysd.filter(item1 => !arr2.some(item2 =>
item2 === item1))
arr2.forEach(item => {
setTimeout(function () {
that.$refs.tree_edit.setChecked(item) //取消勾选
}, 50);
})
}
}
},
// 递归获取所有id成数组返回
getAllId(keys, dataList) {
if (dataList && dataList.length) {
for (let i = 0; i < dataList.length; i++) {
keys.push(dataList[i].id)
if (dataList[i].children) {
keys = this.getAllId(keys, dataList[i].children)
}
}
}
return keys
},
//编辑类别的下拉选择
select_lb() {
let that = this
axios
.post(apiadmin_url + "5e23ed7284053", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
that.lb_options = response.data.data
})
.catch(error => {})
},
//编辑的提交
role_editsub(formName) {
let that = this
that.$refs[formName].validate((valid) => {
if (valid) {
// 1代表的是PC端
if (that.activeNamed == '1') {
console.log('pc端');
var res = []
var res_id = []
this.btnList.forEach(element => {
var obj = {
id: '',
power: []
}
obj.id = element.id
if (element.power_new) {
obj.power = element.power_new
} else {
obj.power = ['search']
}
res.push(obj)
});
axios
.post(apiadmin_url + "5e23f13dd9c9d", {
id: that.lbid,
role_type_id: that.forms.role_lbname,
name: that.forms.rolename,
sort: that.forms.sort,
// menu_list: res_id,
menu_list: this.expandedKeysd,
power_list: res,
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
if (response.data.code == 200) {
that.$message({
type: 'success',
message: '编辑成功!'
});
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
// 2代表的是小程序端
if (that.activeNamed == '2') {
console.log('小程序');
var xcx_res = []
var xcx_res_id = []
var xcx_arr = this.$refs.xcx_tree_edit.getCheckedNodes().concat(this
.$refs.xcx_tree_edit
.getHalfCheckedNodes())
xcx_arr.forEach(element => {
xcx_res_id.push(element.id)
var xcx_obj = {
id: '',
power: []
}
xcx_obj.id = element.id
if (element.power_new) {
xcx_obj.power = element.power_new
} else {
xcx_obj.power = ['search']
}
xcx_res.push(xcx_obj)
});
if (xcx_arr.length < 1) {
that.$alert('请勾选菜单')
return false;
}
axios
.post(apiadmin_url + "5e23f13dd9c9d", {
id: that.lbid,
role_type_id: that.forms.role_lbname,
name: that.forms.rolename,
sort: that.forms.sort,
menu_list: '',
power_list: '',
menu_xcx_list: xcx_res_id,
power_xcx_list: xcx_res,
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
if (response.data.code == 200) {
that.$message({
type: 'success',
message: '编辑成功!'
});
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
// 4代表的是钉钉端
if (that.activeNamed == '4') {
console.log('钉钉');
var ding_res = []
var ding_res_id = []
var ding_arr = this.$refs.ding_tree_edit.getCheckedNodes().concat(this
.$refs.ding_tree_edit
.getHalfCheckedNodes())
ding_arr.forEach(element => {
ding_res_id.push(element.id)
var ding_obj = {
id: '',
power: []
}
ding_obj.id = element.id
if (element.power_new) {
ding_obj.power = element.power_new
} else {
ding_obj.power = ['search']
}
ding_res.push(ding_obj)
});
if (ding_arr.length < 1) {
that.$alert('请勾选菜单')
return false;
}
axios
.post(apiadmin_url + "5e23f13dd9c9d", {
id: that.lbid,
role_type_id: that.forms.role_lbname,
name: that.forms.rolename,
sort: that.forms.sort,
menu_list: '',
power_list: '',
ding_xcx_list: ding_res_id,
ding_power_xcx_list: ding_res,
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
if (response.data.code == 200) {
that.$message({
type: 'success',
message: '编辑成功!'
});
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
//3渠道营销报表
if (that.activeNamed == '3') {
console.log('渠道');
var qdyx_res = []
// 获取小程序点击的菜单
var qdyx_arr = this.$refs.qdyx_tree_edit.getCheckedNodes()
if (qdyx_arr.length < 1) {
that.$alert('请勾选菜单')
return false;
}
qdyx_arr.forEach(element => {
qdyx_res.push(element.id)
});
var obj = qdyx_res.toString()
axios
.post(apiadmin_url + "5e23f13dd9c9d", {
id: that.lbid,
role_type_id: that.forms.role_lbname,
name: that.forms.rolename,
sort: that.forms.sort,
menu_list: '',
power_list: '',
menu_xcx_list: xcx_res_id,
power_xcx_list: xcx_res,
author: userinfo.name,
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
channel_report_auth: obj,
})
.then(response => {
if (response.data.code == '200') {
that.$message({
type: 'success',
message: '编辑成功!'
});
} else {
that.$alert(response.data.message)
}
})
.catch(error => {})
}
}
})
},
Edit() {
let that = this
that.menu_listed()
},
//添加点击菜单展示
menu_listed() {
let that = this
that.loadinged = true
that.openkeys.push(that.lbid_jsid)
that.$refs.tree.setCheckedKeys(that.openkeys);
axios
.post(apiadmin_url + "5e0c06880fa1f", {
sessionToken: session_token,
kw_hospital_id: userinfo.hospital_id,
})
.then(response => {
that.data = response.data.data
that.loadinged = false
})
.catch(error => {})
},
}
})
</script>
</html>