<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>