feat:角色添加权限

This commit is contained in:
有来技术
2021-12-22 23:57:23 +08:00
parent 9f8d5d757b
commit 7a6fbd1373
4 changed files with 157 additions and 177 deletions

View File

@@ -110,10 +110,11 @@ export function updateRoleMenu(roleId: number, menuIds: Array<Number>) {
* *
* @param roleId * @param roleId
*/ */
export function listRolePerms(roleId: number) { export function listRolePerms(roleId: number, menuId: number) {
return request({ return request({
url: '/youlai-admin/api/v1/roles/' + roleId + '/permissions', url: '/youlai-admin/api/v1/roles/' + roleId + '/permissions',
method: 'get', method: 'get',
data: {menuId: menuId}
}) })
} }
@@ -124,7 +125,7 @@ export function listRolePerms(roleId: number) {
* @param roleId * @param roleId
* @param permIds * @param permIds
*/ */
export function saveRolePerms(menuId: number, roleId: number, permIds: Array<number>) { export function saveRolePerms(roleId: number, menuId: number, permIds: Array<number>) {
return request({ return request({
url: '/youlai-admin/api/v1/roles/' + roleId + '/permissions', url: '/youlai-admin/api/v1/roles/' + roleId + '/permissions',
method: 'put', method: 'put',

View File

@@ -1,5 +1,5 @@
<template> <template>
<div style="width: 100%;"> <div class="menu-container">
<el-form size="mini"> <el-form size="mini">
<el-form-item> <el-form-item>
<el-row> <el-row>
@@ -13,17 +13,16 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-tree <el-tree
ref="menuRef" ref="menuRef"
v-if="state.refreshTree" v-if="refreshTree"
:default-expanded-keys="state.expandedKeys" :default-expanded-keys="expandedKeys"
:default-expand-all="state.isExpandAll" :default-expand-all="isExpandAll"
:data="state.menuOptions" :data="menuOptions"
show-checkbox show-checkbox
node-key="id" node-key="id"
empty-text="加载菜单中..." empty-text="加载菜单中..."
:check-strictly="state.checkStrictly" :check-strictly="checkStrictly"
highlight-current highlight-current
@node-click="handleNodeClick" @node-click="handleNodeClick"
/> />
@@ -33,9 +32,8 @@
<script setup lang="ts"> <script setup lang="ts">
import {listTreeSelectMenus} from "@/api/system/menu"; import {listTreeSelectMenus} from "@/api/system/menu";
import {listRoleMenuIds, updateRoleMenu} from "@/api/system/role" import {listRoleMenuIds, updateRoleMenu} from "@/api/system/role"
import {defineEmits, defineProps, nextTick, onMounted, reactive, ref, watch} from "vue" import {defineEmits, defineProps, nextTick, onMounted, reactive, ref, toRefs, watch} from "vue"
import {ElTree, ElMessage, ElMessageBox} from "element-plus" import {ElTree, ElMessage, ElMessageBox} from "element-plus"
import {Switch, Check} from '@element-plus/icons' import {Switch, Check} from '@element-plus/icons'
const emit = defineEmits(['menuClick']) const emit = defineEmits(['menuClick'])
@@ -68,6 +66,8 @@ const state = reactive({
refreshTree: true refreshTree: true
}) })
const {expandedKeys, menuOptions, checkStrictly, isExpandAll, refreshTree} = toRefs(state)
/** /**
* 加载菜单树 * 加载菜单树
*/ */
@@ -109,5 +109,7 @@ onMounted(() => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.menu-container {
width: 100%;
}
</style> </style>

View File

@@ -1,187 +1,154 @@
<template> <template>
<div class="perm-container"> <div class="perm-container">
<el-card class="box-card" shadow="always"> <el-form size="mini">
<div class="clearfix" slot="header"> <el-form-item>
<b> <el-row>
<svg-icon icon-class="menu"/> <el-col :span="12">
{{ menu && menu.label ? "【" + menu.label + "】" : "" }}权限分配 <el-button type="success" plain :icon="Switch" @click="toggleExpandAll">展开/折叠</el-button>
</b> </el-col>
</div> <el-col :span="12" style="text-align: right">
<el-row style="margin-bottom: 10px"> <el-button type="primary" :icon="Check" @click="handleSubmit">提交</el-button>
<el-col :span="18"> </el-col>
<el-tag v-if="role" type="primary">{{ role.name }}</el-tag> </el-row>
<el-tag v-if="menu" type="success" style="margin-left: 5px">{{ </el-form-item>
menu.label </el-form>
}}
</el-tag>
<el-tag v-if="!role" type="info" style="margin-left: 5px"
><i class="el-icon-info"> </i> 请选择角色
</el-tag>
<el-tag v-if="!menu" type="info" style="margin-left: 5px"
><i class="el-icon-info"> </i> 请选择菜单
</el-tag>
</el-col>
<el-col :span="6" style="text-align: right">
<el-button
type="primary"
:disabled="isRoot"
icon="el-icon-check"
size="mini"
@click="handleSubmit"
>提交
</el-button>
</el-col>
</el-row>
<div v-if="permissionList.length > 0">
<el-checkbox <div v-if="permissionOptions.length > 0">
<el-checkbox
:indeterminate="isIndeterminate" :indeterminate="isIndeterminate"
v-model="checkAll" v-model="checkAll"
@change="handleCheckAllChange" @change="handleCheckAllChange"
style="margin-top: 20px" style="margin-top: 20px"
>全选 >全选
</el-checkbox> </el-checkbox>
<el-row> <el-row>
<el-col <el-col
:span="8" :span="8"
v-for="permission in permissionList" v-for="item in permissionOptions"
style="margin-top: 20px" style="margin-top: 20px"
> >
<el-checkbox <el-checkbox
border border
v-model="permission.checked" v-model="item.checked"
:label="permission.id" :label="item.id"
:key="permission.id" :key="item.id"
@change="handleCheckChange" @change="handleCheckedPermChange"
size="mini" size="mini"
> >
{{ permission.name }} {{ permission.name }}
</el-checkbox> </el-checkbox>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
<div style="text-align: center" v-else> <div style="text-align: center" v-else>
<el-empty :description=" !role? '请选择角色': !menu? '请选择菜单': '暂无数据,您可在【菜单管理】配置权限数据'"></el-empty> <el-empty :description=" !role? '请选择角色': !menu? '请选择菜单': '暂无数据,您可在【菜单管理】配置权限数据'"></el-empty>
</div> </div>
</el-card>
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import {getPermissionList} from "@/api/system/permission"; import {listPerms} from "@/api/system/perm";
import {listRolePermission, updateRolePermission} from "@/api/system/role"; import { listRolePerms, saveRolePerms} from "@/api/system/role";
import {defineProps, onMounted, reactive, toRefs, watch} from "vue";
import {ElMessage} from "element-plus";
export default {
name: "Permission", const props = defineProps({
props: ["type"], role: {
data() { type: Object,
return { default: {}
loading: false,
ids: [],
initialCheckedPermissionIds: [],
menu: undefined,
role: undefined,
isIndeterminate: true,
checkAll: false,
permissionList: [],
isRoot: false,
};
}, },
methods: { menu: {
handleQuery() { type: Object,
this.loading = true; default: {}
const menuId = this.menu.value; }
getPermissionList({ })
menuId: menuId
}).then((response) => { watch(() => props.role.id as any, (newVal, oldVal) => {
const {data} = response; const roleId = props.role.id
if (this.role.code == this.ROOT_ROLE_CODE) { if (roleId) {
// 如果是超级管理员默认勾选全部且不可编辑 }
this.isRoot = true })
this.checkAll = true
this.isIndeterminate = false watch(() => props.menu.id as any, (newVal, oldVal) => {
data.map((item) => this.$set(item, "checked", true)) const menuId = props.menu.id
this.permissionList = data if (menuId) {
this.loading = false }
})
const state = reactive({
loading: false,
permissionOptions: [] as Array<any>,
isIndeterminate: true,
checkAll: false,
checkedPerms: []
})
const {permissionOptions, isIndeterminate, checkAll, checkedPerms} = toRefs(state)
function handleCheckAllChange(checked: Boolean) {
state.isIndeterminate = false;
if (checked) {
state.permissionOptions.map((item) => (item.checked = true));
} else {
// 全不选
state.permissionOptions.map((item) => (item.checked = false));
}
}
function handleCheckedPermChange(value: any) {
const checkedCount = value.length;
state.checkAll = checkedCount === state.permissionOptions.length;
state.isIndeterminate = checkedCount > 0 && checkedCount < state.permissionOptions.length;
}
function loadData() {
if(! props.menu.id){
return false
}
state.loading = true;
listPerms({menuId: props.menu.id}).then(response => {
state.permissionOptions = response.data
listRolePerms(props.role.id, props.menu.id).then(res => {
const checkedPermIds = res.data
state.permissionOptions.map((item:any)=> {
if (checkedPermIds.includes(item.id)) {
item.checked = true;
} else { } else {
this.isRoot = false; state.checkAll = false
listRolePermission(this.role.id, {menuId: menuId}).then((res) => {
this.initialCheckedPermissionIds = res.data;
let checkAll = true
data.map((item) => {
if (this.initialCheckedPermissionIds.includes(item.id)) {
item.checked = true;
} else {
checkAll = false
}
});
this.checkAll = checkAll
if (checkAll) {
this.isIndeterminate = false
}
this.permissionList = data;
this.loading = false;
});
} }
}); });
},
menuClick(menu, role) {
this.role = role;
this.menu = menu;
if (role && menu) { state.loading=false
this.handleQuery();
} else { })
this.permissionList = []; })
this.initialCheckedPermissionIds = []; }
}
}, function handleSubmit(){
handleSubmit: function () { const checkedPermIds = state.permissionOptions
const checkedPermissionIds = this.permissionList .filter((item) => item.checked)
.filter((item) => item.checked) .map((item) => item.id);
.map((item) => item.id);
// 判断选中权限是否变动
if ( saveRolePerms( props.menu.id,
this.initialCheckedPermissionIds.length == props.role.id,
checkedPermissionIds.length && checkedPermIds
this.initialCheckedPermissionIds.sort().every(function (v, i) { ).then(() => {
return v == checkedPermissionIds[i]; ElMessage.success("提交成功");
}) });
) {
this.$message.warning("数据未变动"); }
return;
} onMounted(() => {
updateRolePermission( loadData()
this.menu.value, })
this.role.id,
checkedPermissionIds
).then((response) => {
this.$message.success("提交成功");
});
},
handleCheckAllChange(checked) {
if (checked) {
this.permissionList.map((item) => (item.checked = true));
} else {
// 全不选
this.permissionList.map((item) => (item.checked = false));
}
this.isIndeterminate = false;
},
handleCheckChange(item, val) {
const checkedCount = this.permissionList.filter(
(item) => item.checked
).length;
this.checkAll = checkedCount === this.permissionList.length;
this.isIndeterminate =
checkedCount > 0 && checkedCount < this.permissionList.length;
},
},
};
</script> </script>
<style scoped> <style scoped>
.perm-container { .perm-container {
margin-bottom: 20px; width: 100%;
} }
</style> </style>

View File

@@ -17,7 +17,10 @@
<template #header> <template #header>
<svg-icon color="#333" icon-class="menu"/> <svg-icon color="#333" icon-class="menu"/>
<span style="margin:0 5px;">菜单分配</span> <span style="margin:0 5px;">菜单分配</span>
<el-tag type="success" v-if="state.role.id" size="small"> <svg-icon color="green " icon-class="role"/> {{ state.role.name }}</el-tag> <el-tag type="success" v-if="state.role.id" size="small">
<svg-icon color="green " icon-class="role"/>
{{ state.role.name }}
</el-tag>
<el-tag type="warning" v-else size="small">请选择角色</el-tag> <el-tag type="warning" v-else size="small">请选择角色</el-tag>
</template> </template>
<menus ref="menu" @menuClick="handleMenuClick" :role="state.role"/> <menus ref="menu" @menuClick="handleMenuClick" :role="state.role"/>
@@ -30,13 +33,19 @@
<svg-icon color="#333" icon-class="perm"/> <svg-icon color="#333" icon-class="perm"/>
<span style="margin:0 5px;">权限分配</span> <span style="margin:0 5px;">权限分配</span>
<el-tag type="success" style="margin:0 5px 0 0;" v-if="state.role.id" size="small"> <svg-icon color="green" icon-class="role"/> {{ state.role.name }}</el-tag> <el-tag type="success" style="margin:0 5px 0 0;" v-if="state.role.id" size="small">
<svg-icon color="green" icon-class="role"/>
{{ state.role.name }}
</el-tag>
<el-tag type="warning" style="margin:0 5px 0 0;" v-else size="small"> 请选择角色</el-tag> <el-tag type="warning" style="margin:0 5px 0 0;" v-else size="small"> 请选择角色</el-tag>
<el-tag type="primary" v-if="state.role.id" size="small"><svg-icon color="red" icon-class="menu"/> {{ state.role.name }}</el-tag> <el-tag type="primary" v-if="state.role.id" size="small">
<svg-icon color="red" icon-class="menu"/>
{{ state.role.name }}
</el-tag>
<el-tag type="warning" v-else size="small"> 请选择菜单</el-tag> <el-tag type="warning" v-else size="small"> 请选择菜单</el-tag>
</template> </template>
<!--<perm ref="perm" :menu="state.menu" :role="state.role"/>--> <perm ref="perm" :menu="state.menu" :role="state.role"/>
</el-card> </el-card>
</el-col> </el-col>
@@ -47,6 +56,7 @@
<script setup lang="ts"> <script setup lang="ts">
import Role from './components/Role.vue' import Role from './components/Role.vue'
import Menus from './components/Menu.vue' import Menus from './components/Menu.vue'
import Perm from './components/Perm.vue'
import {reactive} from "vue"; import {reactive} from "vue";
import {ElMessage} from "element-plus"; import {ElMessage} from "element-plus";
import SvgIcon from '@/components/SvgIcon/index.vue'; import SvgIcon from '@/components/SvgIcon/index.vue';