説明する
問題は次のとおりです。私のプロジェクトにはロール管理ページがあります。以前の古いコードは、el-tree によってレンダリングされたツリー構造を直接使用し、対応するアクセス許可の設定を確認します。他の部門は問題ありませんが、上司の部門を設定する場合、権限と部門が多すぎ、上司も多くの権限を持っているため、一度に多くの権限をレンダリングする必要があります。ツリー構造では、多くのチェックをエコーする必要があります。これにより、他の人が設定することになりますが、ボスは権限を設定するときに数十秒間固まったり、ブラウザがフリーズしたりすることがあります。したがって、古いコードを最適化して高速化するしかありません。
レンダリング
このような属性構造には多くのレベルがあります
解決
el-tree の遅延読み込み機能はレイヤーごとに読み込みを行うため、ページが初めて受信したときにすべての構造とエコーされたデータを読み込むことができないため、フリーズすることはありません。
ここで最初に実装アイデアについて話して、最後にページ全体のコードを一番下に置きますが、古いコードがたくさんあるので、削除したり修正したりするのが面倒なので、自分でコードを作成します。
機能実現のアイデア
1. データ量が多すぎる 多層ネストされており、データ量が多いため、インターフェースがデータを要求するのにそれほど時間はかかりませんが、データが大きすぎるため、非常に長い時間がかかります。ノードを一度にレンダリングすることに固執しました。したがって、最初のステップはデータを分割することです。まずデータを取得し、ループして最初のレイヤーを個別に抽出して配列に入れ、後続の子の抽出のためにすべてのデータのコピーを保存しました。最初のレベルを抽出し、子を null に設定します。このように、データは非常に少ないです。最初にノードのレイヤーをレンダリングするために使用されます。
2. ノードのレイヤーを使用して、遅延読み込みを設定します。el-treeの遅延ロードの設定方法は非常に簡単で、treeタグにload="loadNode"とlazyとnode-key="id"を直接追加します。loadNodeメソッドは遅延ロードのメソッドであり、解決レベル配列を通じてノードに子を追加します。まず、このメソッドに付属する属性ノードを使用して、現在クリックされて展開されているノード情報を取得します。次に、このノードの ID を使用して、バックアップしたすべてのデータの元の配列を再帰的に検索し、ID に対応する位置を見つけます。 、その子配列を取得します。次に、子配列の解決を返して遅延読み込みを完了します。
3. この時点で、データは利用可能です。構造も表示され、レイヤーごとに遅延ロードできますが、解決する必要があるのはエコーの問題です。これは私が長い間考えてきた方法です。まず、ツリーの親子関係を解除し、el-tree タグに check-strictly="checkStrictly" と記述する必要があります。checkStrictly 変数の内容は false です。この文は、親子関係が確立されていないことを意味します。なぜ。なぜなら、親子関連付けがある場合、echoしたときに親のIDがあれば親が選択され、同時に子もすべて選択されてしまうからです。すべての子を選択できない場合があるため、これは誤りです。解決策は親子関係を断つことです。このように、エコーがかかったら、それぞれ確認していきます。他の未チェックのノードには影響しません。
チェックマークをエコーする方法は? ツリーに「default-checked-keys="expandedKeysd"」と記述するだけです。これは、選択されたノード ID の配列を表します。配列がどこから来るかというと、もちろんバックエンドから返されるチェックされた ID 配列であり、それは自分で必要な ID 配列に処理されます。配列には親と子の ID が含まれます。親の遅延読み込みが展開されると、子が表示され、自動的にチェックされます。
4. この時点で、データを通常どおりエコーすることができ、遅延ロードと拡張も可能です。しかし、まだ問題があります。つまり、親子関係を切ると何度もクリックする必要があり非常に面倒なのですが、それでも一度クリックして全選択したい、全選択しないなどしたいのですが、どうすればよいでしょうか?解決策はこれで対処することです。ツリー上に @check-change="handleCheckAllChange" と記述します。このメソッドは、チェック ボックスをクリックすることによってトリガーされるメソッドを表します。
ここでの主なメソッドは setChecked です。ロジックは非常に単純で、特定のノードの複数選択ボックスをクリックしたときです。このメソッドをトリガーします。このメソッドでは、最初にバックアップされた完全な配列を直接ループし、現在クリックしたノードの ID に従って対応するノードの下のすべての子を検索し、子の ID を配列にマージします。次に、この配列を重複排除して、同じことが繰り返されないようにします。次に、この配列を使用してループし、setChecked メソッドを通じて各 ID をチェックまたはチェック解除します。このようにして、ノードをクリックすると、すべての子のチェックが外されるか選択されます。そして同時に、チェックマークをクリックすると。次に、すべての子をエコー配列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>