xw_admin/src/views/setting/role/index.vue
2024-10-28 21:24:40 +08:00

580 lines
15 KiB
Vue

<template>
<el-container class="mainBox">
<el-header>
<div class="left-panel">
<el-button type="primary" v-auth="'addRoles'" :size="size" icon="el-icon-plus" @click="add">新增角色</el-button>
<!--<el-button type="danger" :size="size" plain icon="el-icon-delete" :disabled="roleCheckList.length==0" @click="batch_del"></el-button>-->
<!--<el-button type="primary" :size="size" plain :disabled="roleCheckList.length!=1" @click="permission">权限设置</el-button>-->
</div>
<div class="right-panel">
</div>
</el-header>
<el-container class="mainBox" style="border-radius: 0;padding-left: 0;padding-right: 0;">
<el-aside width="200px" v-loading="showGroupLoading">
<el-container>
<!-- <el-header>-->
<!-- <el-input placeholder="输入关键字进行过滤" :size="size" v-model="groupFilterText" clearable></el-input>-->
<!-- </el-header>-->
<el-main class="treeMain nopadding">
<el-scrollbar>
<role-sort ref="roleSort" :role_id="role_id" :column="group" @roleChange="groupChange" @roleClick="roleClick" @roleEdit="table_edit" @roleDelete="table_del"></role-sort>
</el-scrollbar>
</el-main>
</el-container>
</el-aside>
<el-container>
<el-main class="nopadding">
<div class="btnPot" v-if="activeNum==0">
<el-button type="primary" v-auth="'addRoleAuth'" plain :size="size" :loading="isSave" @click="submit">保存权限</el-button>
</div>
<div class="btnPot" v-if="activeNum==1">
<el-button type="primary" v-auth="'addDataPermission'" plain :size="size" :loading="isDataSave" @click="submitPermissions">保存权限</el-button>
</div>
<div class="btnPot" v-if="activeNum==2">
<el-button type="danger" v-auth="'roleRemovedUsers'" plain :size="size" @click="deleteMember">移除成员</el-button>
<el-button type="primary" v-auth="'roleAddedUsers'" plain :size="size" @click="getDeptTree">添加成员</el-button>
</div>
<el-tabs class="role_tabs" tab-position="top" @tab-change="activeClick">
<el-tab-pane label="功能权限">
<dataTree ref="dataTree" v-loading="dataTreeLoading" element-loading-text="加载中..." :data="menu.list"/>
</el-tab-pane>
<el-tab-pane label="数据权限">
<dataPermissions ref="dataPermissions" v-loading="dataPermissionsLoading" element-loading-text="加载中..." :data="dataPermissions.list"/>
</el-tab-pane>
<el-tab-pane label="角色成员">
<members ref="members" v-loading="roleUserLoading" element-loading-text="加载中..." :data="roleUser.list" />
</el-tab-pane>
</el-tabs>
</el-main>
</el-container>
</el-container>
</el-container>
<el-dialog
title="选择成员"
v-model="memberShow"
:width="720"
destroy-on-close
@closed="closedClose"
>
<div class="bodyView">
<div class="viewLeft">
<div class="viewTitle">成员</div>
<div class="viewCom" element-loading-text="加载中..." v-loading="userLoading">
<el-scrollbar>
<treeUser class="treeUser" ref="treeList" :data="deptTree" :userIds="userIds" @roleChecked="roleChecked" />
</el-scrollbar>
</div>
</div>
<div class="iconRight">
<div class="icon">
<el-icon-ArrowRight></el-icon-ArrowRight>
</div>
</div>
<div class="viewRight">
<div class="viewTitle">已选成员 ({{userCheckList.length}})</div>
<div class="viewCom">
<el-scrollbar>
<div class="checkList" v-for="(item,index) in userCheckList" :key="index" @click="deleteUser(item)">
<div class="leftTitle">
<div class="avatar">{{ userAvatar(item) }}</div>
<div class="name">{{item.name}}</div>
</div>
<div class="userBtn"><el-icon-Close></el-icon-Close></div>
</div>
</el-scrollbar>
</div>
</div>
</div>
<template #footer>
<el-button @click="memberShow = false">关 闭</el-button>
<!-- <el-button type="primary" :loading="isMember" @click="userSubmit">保 存</el-button>-->
</template>
</el-dialog>
<save-dialog v-if="dialog.save" ref="saveDialog" @success="handleSaveSuccess" @closed="dialog.save=false"></save-dialog>
<permission-dialog v-if="dialog.permission" ref="permissionDialog" @closed="dialog.permission=false"></permission-dialog>
</template>
<script>
import saveDialog from './save';
import permissionDialog from './permission';
import dataTree from "./dataTree";
import dataPermissions from "./dataPermissions";
import members from "./members";
import treeUser from "./userTree"
import roleSort from "./roleSort";
export default {
name:"role",
components: {
saveDialog,
permissionDialog,
dataTree,
dataPermissions,
members,
treeUser,
roleSort
},
watch:{
groupFilterText(val) {
this.$refs.group.filter(val);
}
},
data() {
return {
size:'small',
dialog: {
save: false,
permission: false
},
showGroupLoading:false,
groupFilterText:"",
group:[],
list:{
apiObj: this.$API.system.role.list,
column:[]
},
isSave:false,
isDataSave:false,
activeNum:0,
roleCheckList:[],
role_id:0,
dataTreeLoading:false,
menu: {
list: [],
},
dataPermissionsLoading:false,
dataPermissions:{
list:[],
},
roleUserLoading:false,
roleUser:{
list:[]
},
memberShow:false,
deptTree:[],
isMember:false,
userCheckList:[],
userIds:[],
userLoading:false,
}
},
mounted() {
this.getGroup(true);
},
methods: {
async getGroup(flag = true){
this.showGroupLoading = true;
const res = await this.$API.system.role.list.get();
this.showGroupLoading = false;
if(res.code == 200){
this.group = res.data.rows;
if(res.data.rows && res.data.rows.length>0){
this.role_id = res.data.rows[0].id
if(flag){
await this.getMenu(res.data.rows[0].id);
await this.getRoleList(res.data.rows[0].id);
await this.getDataList(res.data.rows[0].id);
}
}
}
},
//添加
add(){
this.dialog.save = true
this.$nextTick(() => {
this.$refs.saveDialog.open()
})
},
//编辑
table_edit(row){
this.dialog.save = true
this.$nextTick(() => {
this.$refs.saveDialog.open('edit').setData(row)
})
},
//权限设置
permission(){
this.dialog.permission = true;
this.$nextTick(() => {
this.$refs.permissionDialog.open(this.role_id)
})
},
//删除
async table_del(row){
this.$confirm(`确定删除 ${row.role_name} 吗?`, '提示', {
type: 'warning'
}).then(async () => {
const params = {ids: [row.id]};
const res = await this.$API.system.role.delete.post(params);
if(res.code == 200){
await this.getGroup(true);
this.$message.success("删除成功")
}
}).catch(()=>{})
},
//批量删除
async batch_del(){
this.$confirm(`确定删除选中的 ${this.roleCheckList.length} 项吗?`, '提示', {
type: 'warning'
}).then(async () => {
const loading = this.$loading();
const params = {ids: this.roleCheckList.map(em=>em)};
const res = await this.$API.system.role.delete.post(params);
if (res.code == 200) {
await this.getGroup(true);
this.$message.success("删除成功");
}
loading.close();
}).catch(() => {
})
},
//表格内开关
changeSwitch(val, row){
row.$switch_status = true;
setTimeout(async () => {
let params = {
id: row.id,
status: row.active_status,
};
const res = await this.$API.system.role.status.post(params);
if (res.code != 200) {
row.active_status = !row.active_status;
}
delete row.$switch_status;
delete row.$switch_yx;
}, 500)
},
//根据ID获取树结构
filterTree(id){
let target = null;
function filter(tree){
tree.forEach(item => {
if(item.id == id){
target = item
}
if(item.children){
filter(item.children)
}
})
}
filter(this.$refs.table.tableData)
return target
},
//本地更新数据
handleSaveSuccess(){
this.getGroup(true);
},
//树过滤
groupFilterNode(value, data){
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
//角色拖动事件
groupChange(data){
let params = {
sort_info:data.map((item,index)=>({
id:item.id,
sort:index+1
}))
}
const res = this.$API.system.role.sort.post(params);
if(res.code === 200){
this.$message.success('保存成功');
}
},
//树点击事件
roleClick(data){
this.role_id = data.id;
this.getMenu();
this.getRoleList();
this.getDataList();
},
// 保存权限
submit() {
this.isSave = true;
const params = this.setList(this.$refs.dataTree.list);
setTimeout(async ()=>{
const res = await this.$API.system.role.roleAuth.post(params);
if(res.code === 200){
this.$message.success("授权成功");
await this.getMenu();
}
this.isSave = false;
})
},
setList(list){
let obj = {
role_id:this.role_id,
menu_permission:[],
data_permission:[]
}
list.forEach(item=>{
if(item.checked || item.isCheck){
obj.menu_permission.push(item.meta.code);
}
if(item.children){
item.children.forEach(em=>{
if(em.checked || em.isCheck){
obj.menu_permission.push(em.meta.code);
}
if(em.meta.data_permission && em.meta.data_permission.length>0){
let list = em.meta.data_permission.filter(e=>e.checked).map(u=>{
let obj = {
actions:u.actions,
title:u.title
}
return obj
});
if(list.length>0){
obj.data_permission.push({[em.meta.code]:list})
}
}
if(em.children && em.children.length>0){
em.children.forEach(daList=>{
if(em.checked || em.isCheck && daList.meta.hidden){
obj.menu_permission.push(daList.meta.code);
}
})
}
})
}
})
return obj
},
// 保存数据权限
submitPermissions(){
this.isDataSave = true;
const params = this.setDataList(this.$refs.dataPermissions.list);
setTimeout(async ()=>{
const res = await this.$API.system.role.dataAuth.post(params);
if(res.code === 200){
this.$message.success("授权成功");
await this.getDataList();
}
this.isDataSave = false;
})
},
setDataList(list){
let obj = {
role_id:this.role_id,
resource_info:[],
}
list.forEach(item=>{
if(item.set_info && item.set_info.length>0){
item.set_info.forEach(em=>{
obj.resource_info.push(em)
})
}
})
return obj
},
// 权限和角色成员
userAvatar(row) {
return row.name.substring(0, 1)
},
activeClick(e){
this.activeNum = e;
},
async getMenu(id) {
if(this.role_id!="" || id){
let params = {
role_id:id?id:this.role_id,
};
this.dataTreeLoading = true;
const res = await this.$API.system.role.roleMenu.post(params);
this.dataTreeLoading = false;
this.menu.list = res.data;
}
},
async getDataList(id) {
if (this.role_id != "" || id) {
let params = {
role_id:id?id:this.role_id,
};
this.dataPermissionsLoading = true;
const res = await this.$API.system.role.dataMenu.post(params);
this.dataPermissionsLoading = false;
this.dataPermissions.list = res.data;
}
},
async getRoleList(id) {
if(this.role_id!="" || id){
let params = {
role_id:id?id:this.role_id,
};
this.roleUserLoading = true;
const res = await this.$API.system.role.roleUser.post(params);
this.roleUserLoading = false;
this.roleUser.list = res.data;
this.userCheckList = res.data;
if(res.data && res.data.length>0){
this.userIds = res.data.map(item=>item.id);
}
}
},
async getDeptTree() {
this.memberShow = true;
this.userLoading = true;
const res = await this.$API.system.role.roleUserTree.post();
this.deptTree = this.treeShow(res.data);
this.userLoading = false;
},
// 数据增加收起
treeShow(list){
list.forEach(item=>{
item.isOpen = true;
if(item.children){
this.treeShow(item.children)
}
})
return list
},
roleChecked(em){
let arr = this.userIds;
if(arr.indexOf(em.id) ==-1){
this.userIds.push(em.id);
this.userCheckList.push(em);
// 添加用户
this.userSingleSubmit(em.id);
return
}
this.userIds.forEach((item,index)=>{
if(item == em.id){
this.userIds.splice(index,1);
}
})
this.userCheckList.forEach((item,index)=>{
if(item.id == em.id){
this.userCheckList.splice(index,1);
}
})
// 单个删除用户
this.deleteSingleMember(em.id);
},
deleteUser(em){
this.userIds.forEach((item,index)=>{
if(item == em.id){
this.userIds.splice(index,1);
}
})
this.userCheckList.forEach((item,index)=>{
if(item.id == em.id){
this.userCheckList.splice(index,1);
}
})
this.deleteSingleMember(em.id);
},
// 移除角色成员
async deleteSingleMember(id){
let params = {
role_id:this.role_id,
user_ids:[id],
}
this.userLoading = true;
const res = await this.$API.system.role.roleUserDel.post(params);
this.userLoading = false;
if(res.code == 200){
await this.getRoleList();
}
},
deleteMember(){
this.$confirm(`确定删除选中成员吗?`, '提示', {
type: 'warning'
}).then(async () => {
let ids = [];
this.$refs.members.list.forEach(item=>{
if(item.checked){
ids.push(item.id);
}
})
setTimeout(async()=>{
let params = {
user_ids:ids,
role_id:this.role_id
}
this.roleUserLoading = true;
const res = await this.$API.system.role.roleUserDel.post(params);
if(res.code == 200){
await this.getRoleList();
}
},100)
}).catch(()=>{})
},
// 关闭添加成员
closedClose(){
this.memberShow = false;
},
// 保存成员
async userSingleSubmit(id) {
let params = {
role_ids: [this.role_id],
user_ids: [id]
};
this.userLoading = true;
const res = await this.$API.system.role.roleUserAdd.post(params);
this.userLoading = false;
if(res.code == 200){
this.$message.success('保存成功');
await this.getRoleList();
}
},
async userSubmit() {
let params = {
role_ids: [this.role_id],
user_ids: this.userCheckList.map(em=>em.id)
};
this.isMember = true;
const res = await this.$API.system.role.roleUserAdd.post(params);
if(res.code == 200){
this.memberShow = false;
this.$message.success('保存成功');
this.isMember = false;
await this.getRoleList();
}
},
}
}
</script>
<style lang="scss" scoped>
.nopadding{
position: relative;
}
.btnPot{
position: absolute;
top: 6px;
right: 0;
z-index: 10;
}
.custom-tree-node{
width: 100%;
display: flex;
justify-content: space-between;
.btnBox{
display: none;
margin-right: 10px;
.btn{
margin: 0 5px;
}
}
}
.is-current .custom-tree-node .btnBox{
display: block;
}
.custom-tree-node:hover .btnBox{
display: block;
}
</style>