<template lang="pug"> el-container(style="height:77.6vh") el-aside( width="18vw" v-loading="leftLoading" style="z-index:1000;box-shadow: 2px 0 8px 0 rgba(0, 0, 0, 0.2);") div.tree_warp div.title_warp span.title-bold(style='padding-right:150px;margin-left:20px;z-index:1001;') 角色列表 el-button(type='primary' v-if="isAuth('sys:role:save')" size='mini' icon='el-icon-plus' @click="addOrUpdateHandle('')") 新增 div.tree_content(v-for='item in tableData' :key='item.roleId' @click='chooseRole(item)' :class="{'isActive': ids == item.roleId}" ) el-tooltip(v-if="item.roleName.replace(/[\u0391-\uFFE5]/g,'aa').length>14" :content="item.roleName" effect="light" placement="top") div.role_name {{item.roleName | ellipsis}} div.role_name(v-else) {{item.roleName | ellipsis}} div(style="width:50%;text-align:right;padding-right:20px") el-button(v-if="isAuth('sys:role:update')" plain type='primary' size='mini' @click="addOrUpdateHandle(item)") 编辑 el-button(v-if="isAuth('sys:role:delete')" plain type='primary' size='mini' style="margin-left:10px;" @click="delRole(item.roleId)") 删除 el-container(style="height:77vh") el-header(style='height:42px;line-height:42px;background: #f4f4f4;z-index:1001;border:1px solid rgba(196, 196, 196, 1);') template() span.title-bold.title-left-color {{roleName ? roleName : '权限详情'}}  el-checkbox(v-model="checked" @change="checkAll(videoData)") 全选 el-main().box_main el-card.tableCard( style='overflow:auto;box-sizing:border-box;' v-loading.fullscreen.lock="rightLoading") div(v-loading="rightLoading1" class='div_tree') //- el-tree(ref="tree" @check-change="handleNodeClick" :render-content="renderContent" @node-expand="handleNodeExpand" :default-expanded-keys="expandedKeys" :props="defaultProps" :data="videoData" show-checkbox node-key="menu_id") //- 树结构 div.my_role_tree() div.firstDiv(v-for='(item, index) in videoData' :key='index') div.ffDiv(@click='changeOpen(item)' :class='{active1 : !item.isopen, active2 : item.isopen}') el-checkbox(:indeterminate="item.indeterminate" v-model='item.checked' @change='checkboxClick(item)') font {{item.name}} div.div_content(:id="item.menu_id") div.twoDiv(v-for='(ii, ini) in item.children' :key='ini' ) div.ttDiv label el-checkbox(:indeterminate="ii.indeterminate" v-model='ii.checked' @change='checkboxClick(ii)') font {{ii.name}} div.threeDiv(v-for='(itei, indee) in ii.children' :key='indee') label el-checkbox(v-model='itei.checked' @change='checkboxClick(itei)') font {{itei.name}} div(style="margin-top:20px;") el-button(type='primary' size='medium' v-if="isAuth('sys:role:update')" @click="saveRoleMenu" v-prevent-re-click) 保存 //- el-button(type='primary' size='medium' @click='ccc') cccc add-or-update( v-if="addOrUpdateVisible" ref="addOrUpdate" @reFreshDataList="reFreshDataList") </template> <script> import AddOrUpdate from './role-add-or-update' export default { data() { return { isopen: true, rightLoading: false, clickFlag: false, ids: '', leftLoading: false, rightLoading1: false, selection: '', expandedKeys: [], addOrUpdateVisible: false, tableData: [], checked: false, isIndeterminate: true, roleName: '', activeNames: ['1'], //手风琴 videoData: [], totalCount: 0, checkTotalCount: 0, defaultProps: { children: 'children', label: 'name' } } }, filters: { ellipsis(value) { // console.log(value) if (!value) return '' let len = value.length let realLength = 0 for (var i = 0; i < len; i++) { let charCode = value.charCodeAt(i) if (charCode >= 0 && charCode <= 128) { realLength += 1 } else { realLength += 2 } if (realLength > 14) { return value.slice(0, i) + '...' } } return value } }, components: { AddOrUpdate }, created() { //查询角色信息 this.getAllRole() this.getMenu() }, methods: { reFreshDataList() { this.getAllRole() this.getMenu() }, // 打开关闭切换 changeOpen(item) { this.$set(item, 'isopen', !item.isopen) let sel = document.getElementById(item.menu_id) let height = item.isopen ? (item.children.length || 0) * 48 : 0 sel.style.height = height + 'px' // let f = document.body.offsetHeight; }, // 新增或修改 addOrUpdateHandle(item) { this.addOrUpdateVisible = true this.$nextTick(() => { this.$refs.addOrUpdate.init(item) }) }, saveRoleMenu() { // let checkedKeys = this.$refs.tree // .getCheckedKeys() // .concat(this.$refs.tree.getHalfCheckedKeys()) // // console.log(checkedKeys) let checkedKeys = this.checkKeys(this.videoData) let checkedRow = this.selection if (!checkedRow) { this.$message({ type: 'warning', message: '请先选择角色!', duration: 1000 }) return } this.clickFlag = true this.rightLoading = true // console.log("checkedKeys", checkedKeys); // console.log("checkedRow", checkedRow); this.$http({ url: this.$http.adornUrl(`/sys/menu/updateRoleMenu`), method: 'post', data: { roleId: checkedRow, menuIds: checkedKeys, stationId: localStorage.getItem('stationId') } }).then((data) => { if (data && data.code === 0) { this.$message({ message: '操作成功', type: 'success', duration: 1500 }) this.reFreshDataList() } this.clickFlag = false this.rightLoading = false }) }, // 全选 checkAll(item) { this.videoData.forEach((item) => { this.checkedAll(item, this.checked) }) }, // 递归勾选 checkedAll(data, bool) { this.$set(data, 'checked', bool) this.$set(data, 'indeterminate', false) if (data.children && data.children.length > 0) { data.children.forEach((ii) => { this.checkedAll(ii, bool) }) } }, // 点击左侧角色列表 chooseRole(res) { this.clickFlag = false this.ids = res.roleId this.selection = res.roleId this.roleName = res.roleName this.$http({ url: this.$http.adornUrl(`/sys/menu/getRoleMenu`), method: 'get', params: this.$http.adornParams({ roleId: res.roleId }) }).then((data) => { if (data && data.code === 0) { let list = data.list.map((item) => { return item.menu_id }) this.$nextTick(() => { this.addChecked(this.videoData, list) this.checked = this.allChecked(this.videoData) }) } }) }, //节点勾选 checkboxClick(item) { this.checkedAll(item, item.checked) let list = this.check(this.videoData) this.addChecked(this.videoData, list) this.checked = this.allChecked(this.videoData) }, // 获取选中状态 check(item) { let list = [] item.forEach((ii) => { if (ii.checked) list.push(ii.menu_id) if (ii.children && ii.children.length > 0) { list = list.concat(this.check(ii.children)) } }) return list }, // 获取所有选中和半选中的 checkKeys(item) { let list = [] item.forEach((ii) => { if (ii.checked || ii.indeterminate) list.push(ii.menu_id) if (ii.children && ii.children.length > 0) { list = list.concat(this.checkKeys(ii.children)) } }) return list }, // 勾选回显 addChecked(data, ids) { data.forEach((item) => { if (ids.indexOf(item.menu_id) >= 0) { this.$set(item, 'checked', true) } else { this.$set(item, 'checked', false) } if (item.children && item.children.length > 0) { this.addChecked(item.children, ids) let num = item.children.length let cnum = 0 let indete = false item.children.forEach((ii, iiindex) => { if (ii.checked) cnum++ if (ii.indeterminate) indete = true }) if (cnum === 0) { // 半选状态(子集全未选默认是false,子集有一个为半选为true) this.$set(item, 'indeterminate', indete) this.$set(item, 'checked', false) } else if (cnum > 0 && cnum < num) { // 半选 this.$set(item, 'indeterminate', true) this.$set(item, 'checked', false) } else if (cnum === num) { // 全选了 this.$set(item, 'checked', true) this.$set(item, 'indeterminate', false) } } }) }, // 校验全选状态 allChecked(data) { for (const ii of data) { if (!ii.checked) { return false } if (ii.children && ii.children.length > 0) { if (!this.allChecked(ii.children)) return false } } return true }, getAllRole() { this.leftLoading = true this.$http({ url: this.$http.adornUrl(`/sys/role/getRoleList`), method: 'get', params: this.$http.adornParams({ stationId: localStorage.getItem('stationId') }) }) .then((data) => { if (data && data.code === 0) { this.tableData = data.list // let row = this.$refs.roleTable.data[0] // this.$refs.roleTable.setCurrentRow(row) // this.chooseRole(row) } this.leftLoading = false }) .then(() => { this.$nextTick(() => { if (this.tableData && this.tableData.length) { this.chooseRole(this.tableData[0]) } }) }) }, getMenu() { this.rightLoading1 = true this.$http({ url: this.$http.adornUrl(`/sys/menu/getMenu`), method: 'get', params: this.$http.adornParams({ stationId: localStorage.getItem('stationId') }) }).then((data) => { if (data && data.code === 0) { this.videoData = data.result // console.log(data.size, 'size') // this.totalCount = data.size // this.totalCount = this.videoData.length // this.videoData.forEach(e => { // if (e.children != null && e.children.length > 0) { // this.totalCount += e.children.length // e.children.forEach(j => { // if (j.children != null && j.children.length > 0) { // this.totalCount += j.children.length // } // }) // } // }) } this.rightLoading1 = false }) }, delRole(roleId) { this.$confirm('确认删除该角色?', '删除角色', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.leftLoading = true let roleIds = [roleId] this.$http({ url: this.$http.adornUrl(`/sys/role/delete`), method: 'POST', data: roleIds }).then((data) => { if (data && data.code === 0) { this.$message({ message: '操作成功', type: 'success', duration: 1500 }) } else { this.$message.error(data.msg) } this.getMenu() this.getAllRole() this.leftLoading = false }) }) } } } </script> <style lang="scss" scoped> .item { margin-bottom: 18px; } .is-leaf > span:nth-child(0) { font-size: 11px; font-weight: 100; } .tree_warp { overflow: auto; height: 100%; box-sizing: border-box; background: #f4f4f4; /*border-right: 1px solid rgba(195, 195, 195, 1);*/ /*box-shadow: 2px 0 8px 0 rgba(0, 0, 0, 0.2);*/ /*box-shadow: 2px 0 8px 0 red;*/ .title_warp { height: 42px; line-height: 42px; background: #eef8ff; color: #333333; } .tree_content { display: flex; height: 40px; line-height: 40px; background: #fff; border-top-left-radius: 20px; border-bottom-left-radius: 20px; margin: 10px 10px 0 20px; // float: right; .role_name { margin-left: 20px; width: 50%; margin-left: 20px; font-size: 14px; font-family: Microsoft YaHei; font-weight: 400; color: rgba(51, 51, 51, 1); display: inline-block; } } } .isActive { background: #eef8ff !important; } .el-tree-node__content { height: 40px; .el-tree-node__expand-icon { position: relative; left: 126px; } } </style> <style lang="scss"> .my_role_tree { background-color: #f6f7fb; font-size: 14px; font-family: Arial, Helvetica, sans-serif; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; .firstDiv { background-color: #f6f7fb; .active1:after { background: url("../../../assets/images/active1.png"); background-repeat: no-repeat; transition: 0.3s; content: ""; display: inline-flex; width: 5px; height: 10px; left: 100px; margin-left: 20px; // border: 1px solid red; } .active2:after { background: url("../../../assets/images/active1.png"); transform: rotate(90deg); transition: 0.3s; background-repeat: no-repeat; content: ""; display: inline-flex; width: 10px; height: 10px; margin-left: 20px; } .ffDiv { // width: 200px; border: 1px solid #edeef1; padding: 0 12px; height: 46px; // background: #f6f7fb; font { line-height: 46px; margin-left: 10px; font-size: 16px; font-family: Microsoft YaHei; font-weight: bold; color: #333333; } } .div_content { transition: height .3s; height: 0; overflow: hidden; .twoDiv { display: flex; background: #e9eaee; border: 1px solid #edeef1; padding-left: 37px; .ttDiv { width: 150px; height: 46px; font { line-height: 46px; font-size: 14px; margin-left: 10px; font-family: Microsoft YaHei; font-weight: bold; color: #333333; } } .threeDiv { width: 120px; height: 46px; font { line-height: 46px; margin-left: 10px; font-size: 13px; font-family: Microsoft YaHei; font-weight: 400; color: #000000; } } } } } } </style>