123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489 |
- <template>
- <div class="permission-container">
- <el-form :model="permissionForm" :rules="permissionRules" ref="permissionForm" label-width="200px"
- class="demo-ruleForm">
- <el-form-item label="角色名称" prop="role_name">
- <el-input v-model="permissionForm.role_name"></el-input>
- </el-form-item>
- <el-form-item label="数据范围" prop="dept_ids">
- <el-cascader
- @visible-change="visibleChange"
- ref="cascader"
- :clearable="true"
- v-model="permissionForm.dept_ids"
- :options="deptList"
- @change="selectHandle"
- :props="props"></el-cascader>
- </el-form-item>
- <el-form-item label="角色描述" prop="role_describe">
- <el-input v-model="permissionForm.role_describe"></el-input>
- </el-form-item>
- <el-form-item label="角色权限" prop="permission">
- <el-checkbox :indeterminate="allIndeterminate" v-model="allCheck" @change="handleCheckAll">全部选择</el-checkbox>
- <div v-for="(item, index) in permissions" :key="item.identifier" class="level_1">
- <el-row :gutter="20">
- <el-col :span="4">
- <el-checkbox v-model="item.checked" :label="item.title" :indeterminate="checkIndeterminate(item.children)"
- @change="handleCheckboxChanged(item)"></el-checkbox>
- </el-col>
- <el-col :span="20">
- <div v-for="(_item, _index) in item.children" :key="_item.identifier" class="checkbox-dropdown">
- <el-popover placement="bottom" trigger="hover" :open-delay="300" :disabled="!hasChildren(_item)"
- :append-to-body="false">
- <div slot="reference">
- <el-checkbox v-model="_item.checked" :indeterminate="checkIndeterminate(_item.children)"
- @click.native.stop @change="handleCheckboxChanged(_item, item)">
- {{ _item.title }}
- <template v-if="hasChildren(_item)">
- <i class="el-icon-arrow-down"></i>
- </template>
- </el-checkbox>
- </div>
- <div class="role-dropdown__list" v-if="hasChildren(_item)">
- <div class="role-dropdown" v-for="(__item, __index) in _item.children" :key="__item.identifier">
- <el-popover placement="right" trigger="hover" :open-delay="200" :disabled="!hasChildren(__item)"
- :append-to-body="false">
- <div slot="reference" class="role-dropdown__label">
- <el-checkbox v-model="__item.checked" :indeterminate="checkIndeterminate(__item.children)"
- @click.native.stop @change="handleCheckboxChanged(__item, _item)">
- {{ __item.title }}
- <template v-if="hasChildren(__item)">
- <i class="el-icon-arrow-right"></i>
- </template>
- </el-checkbox>
- </div>
- <div class="role-dropdown__list" v-if="hasChildren(__item)">
- <div class="role-dropdown" v-for="(___item, __index) in __item.children"
- :key="___item.identifier">
- <el-popover placement="right" trigger="hover" :open-delay="200"
- :disabled="!hasChildren(___item)" :append-to-body="false">
- <div slot="reference" class="role-dropdown__label">
- <el-checkbox v-model="___item.checked"
- :indeterminate="checkIndeterminate(___item.children)" @click.native.stop
- @change="handleCheckboxChanged(___item, __item)">{{ ___item.title }}</el-checkbox>
- </div>
- </el-popover>
- </div>
- </div>
- </el-popover>
- </div>
- </div>
- </el-popover>
- </div>
- </el-col>
- </el-row>
- </div>
- </el-form-item>
- <el-form-item label="">
- <el-button type="primary" size="small" style="margin-top: 15px" @click="saveRolePermission">保存设置</el-button>
- </el-form-item>
- </el-form>
- </div>
- </template>
- <script>
- import * as API_Auth from '@/api/auth'
- import * as API_Menus from '@/api/menus'
- import * as API_Setting from '@/api/setting'
- import { Foundation } from '~/ui-utils'
- export default {
- name: 'rolePermission',
- data() {
- return {
- props: {
- label: 'name',
- value: 'id',
- emitPath: false,
- multiple: true,
- checkStrictly: true
- },
- checked: true,
- deptList: [],
- oneDimensionalList: [], // 源数据平铺成一级节点
- /** 权限 表单 */
- permissionForm: {
- data_scope: 'ALL',
- role_name: '',
- role_describe: ''
- },
- /** 权限 表单规则 */
- permissionRules: {
- role_name: [
- this.MixinRequired('请输入角色名称!'),
- { min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: 'blur' }
- ]
- },
- permissions: [],
- // 全选状态
- allCheck: false,
- // 全选不确定状态
- allIndeterminate: false,
- isAllSelected: false
- }
- },
- mounted() {
- this.role_id = this.$route.params.id
- this.GET_RolePermission()
- },
- beforeRouteUpdate(to, from, next) {
- this.role_id = to.params.id
- next()
- },
- activated() {
- this.role_id = this.$router.params.id
- },
- watch: {
- role_id: 'GET_RolePermission'
- },
- methods: {
- // 查找全部节点所在的索引
- searchSelectAllNodeIndex() {
- let selectAllOptionIndex = -1
- this.permissionForm.dept_ids.forEach((res, index) => {
- if (res.length === 1) {
- selectAllOptionIndex = index
- }
- })
- return selectAllOptionIndex
- },
- visibleChange(visible) {
- console.log(visible)
- if (visible) {
- this.deptList.unshift({
- id: '全选',
- name: '全选',
- value: '全选'
- })
- } else {
- this.deptList.shift()
- }
- },
- // 选择级联选择器
- async selectHandle(e = []) {
- // 当前选中数量
- const selectLength = e.filter(v => v !== '全选').length
- const has_all_option = e.some(v => { return v === '全选' })
- let dept_ids = this.MixinClone(this.permissionForm.dept_ids)
- if (has_all_option && this.isAllSelected) {
- // 移除了选项中除全部外的某个节点
- this.$refs.cascader.$refs.panel.clearCheckedNodes()
- dept_ids = dept_ids.filter(v => v !== '全选')
- dept_ids.splice(this.searchSelectAllNodeIndex(), 1)
- this.$set(this.permissionForm, 'dept_ids', dept_ids)
- this.isAllSelected = false
- } else if (has_all_option && !this.isAllSelected) {
- // 选中全部节点
- this.isAllSelected = true
- const deptList = this.deptList
- const dept_ids = []
- const loopSelectData = (list) => {
- list.forEach(e => {
- dept_ids.push(e.id)
- if (e.children && e.children.length > 0) {
- loopSelectData(e.children)
- }
- })
- }
- loopSelectData(deptList)
- this.permissionForm.dept_ids = dept_ids
- } else if (!has_all_option && this.isAllSelected) {
- // 取消选中全部节点
- this.isAllSelected = false
- this.$refs.cascader.$refs.panel.clearCheckedNodes()
- this.permissionForm.dept_ids = []
- } else if (selectLength === this.oneDimensionalList.length) {
- this.isAllSelected = true
- dept_ids.unshift('全选')
- this.permissionForm.dept_ids = dept_ids
- }
- this.$nextTick(() => {
- this.$forceUpdate()
- })
- },
- /** 获取部门 */
- GET_DeptList() {
- API_Setting.getDeptList().then(response => {
- this.deptList = Foundation.buildTree(response, '0')
- const oneDimensionalList = []
- const loopData = (list) => {
- list.forEach(e => {
- oneDimensionalList.push(e)
- if (e.children && e.children.length > 0) {
- loopData(e.children)
- }
- })
- }
- loopData(response)
- this.oneDimensionalList = oneDimensionalList
- if (this.permissionForm.dept_ids.length === oneDimensionalList.length) {
- // 设置数据范围全选
- this.permissionForm.dept_ids.push('全选')
- this.isAllSelected = true
- }
- })
- },
- /** 判断是否还有子集 */
- hasChildren(item) {
- return Array.isArray(item.children) && item.children.length !== 0
- },
- /** 全选 */
- handleCheckAll(checked) {
- this.allIndeterminate = false
- this.$set(this, 'permissions', this.setPermissionsCheck(this.permissions, checked))
- },
- /** 选择 */
- handleCheckboxChanged(item, parent) {
- if (item.children && item.children.length) {
- this.$set(item, 'children', this.setPermissionsCheck(item.children, item.checked))
- }
- this.countAllPermissions()
- this.countParentChecked()
- },
- /** 设置权限状态 */
- setPermissionsCheck(permissions, checked) {
- const perm = this.MixinClone(permissions)
- perm.map(item => {
- item.checked = checked
- this.$set(item, 'checked', checked)
- if (item.children && item.children.length) {
- this.$set(item, 'children', this.setPermissionsCheck(item.children, checked))
- }
- })
- return perm
- },
- /** 检测是否有不确定性 */
- checkIndeterminate(permissions) {
- if (!Array.isArray(permissions)) return false
- const _len = permissions.length
- const __len = permissions.filter(item => item.checked).length
- return (__len !== 0) && (_len !== __len)
- },
- /** 获取所有权限展开后的长度、被选中的长度 */
- countAllPermissions(permissions) {
- permissions = permissions || this.permissions
- const _list = []
- permissions.forEach(item => {
- _list.push(item)
- if (item.children) _list.push(...this.countAllPermissions(item.children))
- })
- const length = _list.length
- const length_checked = _list.filter(_item => _item.checked).length
- this.allCheck = length === _list.filter(_item => _item.checked).length
- this.allIndeterminate = (length_checked !== 0) && (length !== length_checked)
- return _list
- },
- /** 计算所有父辈的选中状态 */
- countParentChecked(permissions) {
- permissions = permissions || this.permissions
- permissions.forEach(item => {
- if (item.children && item.children.length) {
- this.countParentChecked(item.children)
- const lenght = item.children.length
- const checked_length = item.children.filter(_item => _item.checked).length
- item.checked = !!checked_length
- }
- })
- },
- /** 保存角色权限 */
- saveRolePermission() {
- this.$refs['permissionForm'].validate(valid => {
- if (valid) {
- let params = {
- ...this.permissionForm,
- menus: this.permissions
- }
- if (!params.dept_ids) {
- this.$message.error('请选择数据范围!')
- return
- }
- params.dept_ids = params.dept_ids.filter(v => v !== '全选')
- if (params.dept_ids) {
- if (this.isAllSelected) {
- params.data_scope = 'ALL'
- params.dept_ids = params.dept_ids.join(',')
- } else {
- params.data_scope = 'DEPT_CUSTOM'
- params.dept_ids = params.dept_ids.join(',')
- }
- }
- this.role_id === 0
- ? API_Auth.addRole(params).then(() => saveSuccess())
- : API_Auth.editRole(this.role_id, params).then(() => saveSuccess())
- const saveSuccess = () => {
- this.$message.success('保存成功!')
- this.$route.params.callback()
- this.$store.dispatch('delCurrentViews', {
- view: this.$route,
- $router: this.$router
- })
- }
- } else {
- this.$message.error('表单填写有误,请检查!')
- return false
- }
- })
- },
- /** 获取权限菜单树 */
- GET_RolePermission() {
- API_Menus.getMenusChildren().then(res => {
- // 如果this.role_id 不为0,说明是编辑。
- if (this.role_id !== 0) {
- API_Auth.getRolePermission(this.role_id).then(response => {
- this.role_id = response.role_id
- this.permissionForm.data_scope = response.data_scope
- this.permissionForm.role_name = response.role_name
- this.permissionForm.role_describe = response.role_describe
- this.permissionForm.dept_ids = response.dept_ids.split(',')
- const checkedIds = this.expandRouters(response.menus)
- this.$set(this, 'permissions', this.filterRoleRouter(res, checkedIds))
- this.countAllPermissions()
- this.GET_DeptList()
- })
- } else {
- this.$set(this, 'permissions', res)
- this.countAllPermissions()
- this.GET_DeptList()
- }
- })
- },
- /** 展开路由的identifier */
- expandRouters(menus) {
- const routers = []
- menus.forEach(item => {
- item.checked && routers.push(item.identifier)
- if (item.children && item.children.length) {
- routers.push(...this.expandRouters(item.children))
- }
- })
- return routers
- },
- /** 递归筛选被选中的路由 */
- filterRoleRouter(routers, ids) {
- const _routers = []
- routers.forEach(item => {
- if (ids.includes(item.identifier) || item.hidden) {
- item.checked = true
- } else {
- item.checked = false
- }
- if (item.children) {
- this.$set(item, 'children', this.filterRoleRouter(item.children, ids))
- }
- _routers.push(item)
- })
- return _routers
- }
- }
- }
- </script>
- <style type="text/scss" lang="scss" scoped>
- .permission-container {
- padding: 10px;
- background-color: #fff;
- padding-bottom: 150px;
- }
- .level_1 {
- padding: 15px 0;
- border-bottom: 1px dashed #e7e7e7;
- &:last-child {
- border-bottom: none
- }
- }
- /deep/ {
- .el-form-item__label {
- padding-top: 15px;
- }
- .el-form-item__content {
- border-left: 1px solid #e7e7e7;
- padding-left: 20px;
- padding-top: 15px;
- .el-form-item__error {
- padding-left: 20px;
- }
- }
- .el-form-item:last-child {
- .el-form-item__content {
- padding-top: 0;
- }
- }
- .el-form-item:not(:first-child) {
- border-top: 1px solid #e7e7e7;
- position: relative;
- &::after {
- content: ' ';
- width: 1px;
- height: 22px;
- background-color: #e7e7e7;
- position: absolute;
- top: -22px;
- left: 200px;
- }
- }
- .el-button-group {
- display: inline-block;
- .el-button {
- display: inline-block;
- padding: 0;
- border: none;
- &:focus,
- &:hover {
- color: #606266;
- border-color: #fff;
- background-color: #fff;
- }
- }
- }
- }
- .checkbox-dropdown {
- display: inline-block;
- min-width: 130px;
- cursor: pointer;
- .checked {
- color: #409EFF
- }
- }
- .role-dropdown {
- display: flex;
- align-items: center;
- width: 25%;
- height: 30px;
- margin-bottom: 10px;
- &:last-child {
- margin-bottom: 0;
- }
- &__label {
- display: flex;
- align-items: center;
- width: 100%;
- /deep/ .el-checkbox__label {
- color: inherit;
- }
- }
- &__list {
- max-height: 320px;
- overflow-y: auto;
- }
- }
- </style>
|