<template>
<el-dialog v-loading="dialogLoading" :visible.sync="dialogFormVisible" :title="titleText" width="330px" append-to-body>
<el-scrollbar>
<el-tree
v-loading="loading"
ref="tree"
:props="defaultProps"
:data="resourceTreeList"
:default-expanded-keys="defaultExpanded"
:default-checked-keys="defaultChecked"
check-strictly
show-checkbox
node-key="id"
@check="changeSelect"
/>
</el-scrollbar>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="saveData">保存</el-button>
<el-button @click="dialogFormVisible = false">取消</el-button>
</div>
</el-dialog>
</template>
<script>
import { toTreeList, getShowItem } from '@/utils/structure'
import { getResourceListByRole } from '@/api/resource'
import { funcAuthor } from '@/api/role'
export default {
name: 'FunctionPerm',
data() {
return {
roleName: '', // 角色名称
roleId: '', // 角色id
dialogFormVisible: false, // 对话框是否显示
defaultProps: {
label: 'name',
children: 'children'
},
resourcePlainList: [], // 资源列表平行数据
resourceTreeList: [], // 资源树列表数据
defaultExpanded: [], // 默认展开的项
defaultChecked: [], // 默认选中的树
ids: [],
loading: false, // 加载动态效果
dialogLoading: false
}
},
computed: {
titleText: function() {
return this.roleName + ''
}
},
methods: {
// 初始化对话框
initDialog: function(dialogFormVisible, row) {
this.loading = true
this.roleName = row.name
this.roleId = row.id
this.dialogFormVisible = dialogFormVisible
this.fetchResourceTree()
},
// 获取资源列表
fetchResourceTree: function() {
getResourceListByRole(this.roleId).then(response => {
if (response.data.list) {
this.resourcePlainList = response.data.list
this.resourceTreeList = toTreeList(response.data.list)
const temp = getShowItem(response.data.list) // 获取展开项和选中项
this.defaultExpanded = temp[0]
this.defaultChecked = temp[1]
this.loading = false
}
})
},
// 保存数据
saveData: function() {
this.ids = this.$refs.tree.getCheckedKeys()
this.dialogLoading = true
funcAuthor(this.roleId, this.ids).then(response => {
if (response.code === 200) {
this.dialogLoading = false
this.$message.success('权限配置成功')
this.dialogFormVisible = false
}
})
},
// 选择变更,对应更新上下级
changeSelect(node, treeState) {
const checked = treeState.checkedKeys.findIndex(v => v === node.id) !== -1
// 若有子节点,将子节点都选中或不选中
this.checkChildState(node, checked, treeState)
// 如果有父节点,向上追溯找父节点
if (node.pid !== '0' && checked) {
// treeState.checkedKeys.push(node.pid)
const pcodes_str = node.pcodes
const pcodes_ori_list = pcodes_str.split(',')
const pcodes_list = [] // 存父级pcodes
for (const item of pcodes_ori_list) {
if (item.length !== 0) {
pcodes_list.push(item.substring(1, item.length - 1))
}
}
// 根据code找id,将id放入选中列表
for (const item of this.resourcePlainList) {
if (pcodes_list.includes(item.code)) {
treeState.checkedKeys.push(item.id)
}
}
}
// else if (node.pid !== '0' && !checked) {
// const index = treeState.checkedKeys.findIndex(v => v === node.pid)
// if (index !== -1) {
// treeState.checkedKeys.splice(index, 1)
// }
// }
this.$refs.tree.setCheckedKeys(treeState.checkedKeys)
},
// 检查子节点状态,状态若有变更更新
checkChildState(node, checked, treeState) {
// 如果选中
if (checked) {
const index = treeState.checkedKeys.findIndex(v => v === node.id)
if (index === -1) {
treeState.checkedKeys.push(node.id)
}
} else { // 如果没有选中
const index = treeState.checkedKeys.findIndex(v => v === node.id)
if (index !== -1) {
treeState.checkedKeys.splice(index, 1)
}
}
this.$refs.tree.setCheckedKeys(treeState.checkedKeys)
if (node.children && node.children.length > 0) {
node.children.forEach((item) => {
this.checkChildState(item, checked, treeState)
})
}
},
// 检查父节点状态,状态若有变更则更新
checkParentState(pid, checked, treeState) {
if (pid !== '0' && checked) {
const index = treeState.checkedKeys.findIndex(v => v === pid)
if (index === -1) {
treeState.checkedKeys.push(pid)
}
} else if (pid !== '0' && checked) {
const index = treeState.checkedKeys.findIndex(v => v === pid)
if (index !== -1) {
treeState.checkedKeys.splice(index, 1)
}
}
this.$refs.tree.setCheckedKeys(treeState.checkedKeys)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.el-dialog{
min-width:350px !important;
}
.el-tree{
max-height:300px;
}
.el-select{
width: 100%;
}
</style>