修改角色管理

This commit is contained in:
龙运模
2024-07-16 18:34:49 +08:00
parent 6dd9d35ce3
commit 196d8cbb91
14 changed files with 495 additions and 151 deletions
+10 -4
View File
@@ -154,10 +154,16 @@ export default {
})
},
async importTemplate() {
const res = await this.$API.system.company.template.get();
if(res.code == 200){
console.log(res.data)
}
const res = await this.$API.system.company.template.post();
const blob = new Blob([res.data]);
const eLink = document.createElement('a');
eLink.download = "company_import_template_20240716093538_6695ce6a3ca1f.xlsx";
eLink.style.display = 'none';
eLink.href = URL.createObjectURL(blob);
document.body.appendChild(eLink);
eLink.click();
URL.revokeObjectURL(eLink.href); // 释放URL 对象
document.body.removeChild(eLink);
},
//编辑
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<el-dialog :title="titleMap[mode]" v-model="visible" :width="1200" destroy-on-close draggable @closed="$emit('closed')">
<el-scrollbar height="480px" style="padding: 0 20px;">
<el-scrollbar height="500px" style="padding: 0 20px;">
<el-form :model="form" :rules="rules" ref="dialogForm" label-width="140px">
<el-row justify="space-between">
<el-col :span="11">
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<!-- 自定义表格 -->
<el-scrollbar max-height="400px">
<el-scrollbar height="100%">
<div class="customTable">
<div class="tableBody" v-if="list.length>0">
<template v-for="(item,inde) in list" :key="inde">
+326 -55
View File
@@ -1,60 +1,116 @@
<template>
<el-container class="mainBox mainBoxHeaderNoBorder">
<el-container>
<el-header>
<div class="left-panel">
<el-button type="primary" :size="size" icon="el-icon-plus" @click="add">新建</el-button>
<el-button type="danger" :size="size" plain icon="el-icon-delete" :disabled="selection.length==0" @click="batch_del"></el-button>
<el-button type="primary" :size="size" plain :disabled="selection.length!=1" @click="permission">权限设置</el-button>
<el-button type="primary" :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-main class="nopadding">
<scTable ref="table" :apiObj="list.apiObj" :column="list.column" row-key="id" @selection-change="selectionChange" stripe :size="size">
<el-table-column type="selection" align="center" width="50"></el-table-column>
<sc-table-column label="序号" align="center" type="index"></sc-table-column>
<el-table-column label="角色名称" prop="label" width="150"></el-table-column>
<el-table-column label="创建时间" prop="date" width="180"></el-table-column>
<el-table-column label="备注" prop="remark" min-width="150"></el-table-column>
<el-table-column label="状态" prop="status" align="center" width="100">
<template #default="scope">
<el-switch :size="size" v-model="scope.row.active_status" @change="changeSwitch($event, scope.row)" :loading="scope.row.$switch_status" :active-value="true" :inactive-value="false"></el-switch>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="170">
<template #default="scope">
<el-dropdown>
<el-button class="noBorderBtn" icon="el-icon-more" :size="size"></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="table_edit(scope.row, 'edit')" icon="sc-icon-Edit">修改</el-dropdown-item>
<el-dropdown-item @click="table_del(scope.row, 'delete')" icon="sc-icon-Delete" divided>删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
<el-container class="mainBox" style="border-radius: 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-tree ref="group" class="menu" node-key="id" show-checkbox :data="group" :default-checked-keys="roleCheckList" :current-node-key="role_id" :highlight-current="true" :expand-on-click-node="false" :filter-node-method="groupFilterNode" @check-change="groupChange" @node-click="groupClick"></el-tree>
</el-main>
</el-container>
</el-aside>
<el-container>
<el-main class="nopadding">
<div class="btnPot" v-if="activeNum==0">
<el-button type="primary" plain :size="size" :loading="isSave" @click="submit">保存权限</el-button>
</div>
<div class="btnPot" v-if="activeNum==2">
<el-button type="danger" plain :size="size" @click="deleteMember">移除成员</el-button>
<el-button type="primary" 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" :data="menu.list"/>
</el-tab-pane>
<el-tab-pane label="数据权限">
</scTable>
</el-main>
</el-tab-pane>
<el-tab-pane label="角色成员">
<members ref="members" :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">
<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 saveDialog from './save';
import permissionDialog from './permission';
import dataTree from "./dataTree";
import members from "./members";
import treeUser from "./tree"
export default {
name: 'role',
components: {
saveDialog,
permissionDialog
permissionDialog,
dataTree,
members,
treeUser
},
watch:{
groupFilterText(val) {
this.$refs.group.filter(val);
}
},
data() {
return {
@@ -64,14 +120,50 @@
save: false,
permission: false
},
showGroupLoading:false,
groupFilterText:"",
group:[],
list:{
apiObj: this.$API.system.role.list,
column:[]
},
selection: [],
isSave:false,
activeNum:0,
roleCheckList:[],
role_id:"",
menu: {
list: [],
},
roleUser:{
list:[]
},
memberShow:false,
deptTree:[],
isMember:false,
userCheckList:[],
userIds:[],
}
},
mounted() {
this.getGroup(true);
},
methods: {
async getGroup(flag = false){
this.showGroupLoading = true;
const res = await this.$API.system.role.list.get();
if(res.code == 200){
this.group = res.data.rows;
this.role_id = res.data.rows && res.data.rows.length>0?res.data.rows[0].id:"";
if(flag){
await this.getMenu();
await this.getRoleList();
}
}
this.showGroupLoading = false;
},
//添加
add(){
this.dialog.save = true
@@ -90,8 +182,7 @@
permission(){
this.dialog.permission = true;
this.$nextTick(() => {
const role_id = this.selection[0]["id"];
this.$refs.permissionDialog.open(role_id)
this.$refs.permissionDialog.open(this.role_id)
})
},
//删除
@@ -102,32 +193,28 @@
const params = {ids: [row.id]};
const res = await this.$API.system.role.delete.post(params);
if(res.code == 200){
this.$refs.table.refresh()
await this.getGroup(true);
this.$message.success("删除成功")
}
}).catch(()=>{})
},
//批量删除
async batch_del(){
this.$confirm(`确定删除选中的 ${this.selection.length} 项吗?`, '提示', {
this.$confirm(`确定删除选中的 ${this.roleCheckList.length} 项吗?`, '提示', {
type: 'warning'
}).then(async () => {
const loading = this.$loading();
const params = {ids: this.selection.map(em=>em.id)};
const params = {ids: this.roleCheckList.map(em=>em)};
const res = await this.$API.system.role.delete.post(params);
if (res.code == 200) {
this.$refs.table.refresh()
this.$message.success("删除成功")
await this.getGroup(true);
this.$message.success("删除成功");
}
loading.close();
}).catch(() => {
})
},
//表格选择后回调事件
selectionChange(selection){
this.selection = selection;
},
//表格内开关
changeSwitch(val, row){
row.$switch_status = true;
@@ -161,16 +248,200 @@
return target
},
//本地更新数据
handleSaveSuccess(data, mode){
if(mode=='add'){
this.$refs.table.refresh()
}else if(mode=='edit'){
this.$refs.table.refresh()
handleSaveSuccess(){
this.getGroup(true);
},
//树过滤
groupFilterNode(value, data){
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
//树选中事件
groupChange(data,isCheck){
let list = JSON.parse(JSON.stringify(this.roleCheckList));
if(isCheck){
this.roleCheckList.push(data.id);
}else{
this.roleCheckList = list.filter(em=>em != data.id);
}
}
},
//树点击事件
groupClick(data){
this.role_id = data.id;
this.getMenu();
this.getRoleList();
},
// 保存权限
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){
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})
}
}
})
}
})
return obj
},
// 权限和角色成员
userAvatar(row) {
return row.name.substring(0, 1)
},
activeClick(e){
this.activeNum = e;
},
async getMenu() {
let params = {
role_id: this.role_id,
};
const res = await this.$API.system.role.roleMenu.post(params);
this.menu.list = res.data;
},
async getRoleList() {
let params = {
role_id: this.role_id,
};
const res = await this.$API.system.role.roleUser.post(params);
this.roleUser.list = res.data;
this.userCheckList = res.data;
this.userIds = res.data.map(item=>item.id);
},
async getDeptTree() {
this.memberShow = true;
const res = await this.$API.system.role.tree.post();
this.deptTree = this.treeShow(res.data);
},
// 数据增加收起
treeShow(list){
list.forEach(item=>{
item.isOpen = false;
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);
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);
}
})
},
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);
}
})
},
// 移除角色成员
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
}
const res = await this.$API.system.role.roleUserDel.post(params);
if(res.code == 200){
await this.getRoleList();
}
},100)
}).catch(()=>{})
},
// 关闭添加成员
closedClose(){
this.memberShow = false;
},
// 保存成员
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>
<style lang="scss" scoped>
.nopadding{
position: relative;
}
.btnPot{
position: absolute;
top: 16px;
right: 0;
z-index: 10;
}
</style>
+24 -4
View File
@@ -1,13 +1,14 @@
<template>
<el-scrollbar max-height="400px">
<el-scrollbar class="scrollbar" height="100%">
<div class="customTable">
<div :class="list.length===0?'thenTitle thenTitleBottom':'thenTitle'">
<div class="tr">
<div class="th btnCheckout"><el-checkbox @change="allCheckChange" :indeterminate="isCheckFun" v-model="checkedFun" :size="size"></el-checkbox></div>
<div class="th seq">序号</div>
<div class="th name">姓名</div>
<div class="th department">部门</div>
<div class="th mobile">手机号</div>
<div class="th email">邮箱</div>
<div class="th department">部门</div>
</div>
</div>
<div :class="list.length==0?'tableBody tableBodyNull':'tableBody'">
@@ -16,8 +17,9 @@
<div class="td btnCheckout"><el-checkbox v-model="item.checked" :size="size"></el-checkbox></div>
<div class="td seq">{{index+1}}</div>
<div class="td name">{{item.name}}</div>
<div class="td department">{{item.department}}</div>
<div class="td mobile">{{item.mobile}}</div>
<div class="td email">{{item.email}}</div>
<div class="td department">{{item.department}}</div>
</div>
</template>
<el-empty v-else :description="emptyText" :image-size="100"></el-empty>
@@ -83,6 +85,11 @@ export default {
</script>
<style lang="scss" scoped>
.scrollbar{
:deep(.el-scrollbar__view){
height: 100%;
}
}
.btnCheckout{
flex-basis: 60px;
display: flex;
@@ -108,7 +115,13 @@ export default {
justify-content: center;
}
.mobile{
flex-basis: 150px;
flex:1;
display: flex;
align-items: center;
justify-content: center;
}
.email{
flex:1;
display: flex;
align-items: center;
justify-content: center;
@@ -116,6 +129,8 @@ export default {
.customTable{
border: 1px solid var(--el-border-color-light);
font-size: 12px;
display: flex;
flex-direction: column;
}
.thenTitle .tr {
display: flex;
@@ -129,6 +144,7 @@ export default {
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.th:first-child{
border-left: 0;
@@ -140,6 +156,9 @@ export default {
.tableBodyNull{
border-top:1px solid var(--el-border-color-light);
}
.tableBody{
flex: 1;
}
.tableBody .tr{
display: flex;
align-items: stretch;
@@ -148,6 +167,7 @@ export default {
.td{
padding: 0 10px;
border-left: 1px solid var(--el-border-color-light);
overflow: hidden;
.nextTd{
display: flex;
align-items: center;
+4 -78
View File
@@ -9,7 +9,7 @@
<div class="dialogBody">
<div class="btnPot" v-if="activeNum==1">
<el-button type="danger" plain :size="size" @click="deleteMember">移除成员</el-button>
<el-button type="primary" plain :size="size" @click="memberShow=true && this.getDeptTree()">添加成员</el-button>
<el-button type="primary" plain :size="size" @click="getDeptTree">添加成员</el-button>
</div>
<el-tabs tab-position="top" @tab-change="activeClick">
<el-tab-pane label="角色权限">
@@ -180,6 +180,7 @@ export default {
this.userIds = res.data.map(item=>item.id);
},
async getDeptTree() {
this.memberShow = true;
const res = await this.$API.system.role.tree.post();
this.deptTree = this.treeShow(res.data);
},
@@ -258,6 +259,7 @@ export default {
this.memberShow = false;
this.$message.success('保存成功');
this.isMember = false;
await this.getRoleList();
}
},
@@ -276,81 +278,5 @@ export default {
right: 0;
z-index: 10;
}
.bodyView{
display: flex;
font-size: 12px;
.viewLeft{
flex: 1;
display: flex;
flex-direction: column;
.treeUser{
padding: 10px 15px 10px 0;
}
}
.iconRight{
flex-basis: 30px;
display: flex;
align-items: center;
justify-content: center;
.icon{
width: 14px;
}
}
.viewRight{
flex: 1;
display: flex;
flex-direction: column;
.checkList{
display: flex;
justify-content: space-between;
margin:8px 15px 8px 15px;
.leftTitle{
flex: 1;
display: flex;
align-items: center;
cursor: pointer;
color: var(--el-color-primary);
.avatar{
background: var(--el-color-primary);
color: var(--el-color-white);
border-radius: 50%;
display: inline-block;
height: 21px;
width: 21px;
text-align: center;
line-height: 21px;
}
.name{
margin-left: 10px;
}
}
.userBtn{
flex-basis: 12px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.userBtn:hover{
color: var(--el-color-primary);
}
}
.checkList:first-child{
margin-top: 10px;
}
.checkList:last-child{
margin-bottom: 10px;
}
}
.viewTitle{
flex-basis: 35px;
}
.viewCom{
flex: 1;
border: 1px solid var(--el-border-color-light);
min-height: 200px;
max-height: 400px;
border-radius: 8px;
}
}
</style>
+2 -2
View File
@@ -1,11 +1,11 @@
<template>
<el-container class="mainBox ">
<el-container class="mainBox">
<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="nopadding">
<el-main class="treeMain nopadding">
<el-tree ref="group" class="menu" node-key="id" :data="group" :current-node-key="''" :highlight-current="true" :expand-on-click-node="false" :filter-node-method="groupFilterNode" @node-click="groupClick"></el-tree>
</el-main>
</el-container>