角色管理授权

This commit is contained in:
zhaoyz 2024-04-26 18:53:37 +08:00
parent e349bdbecf
commit 7a6a21c52b
5 changed files with 301 additions and 237 deletions

View File

@ -24,6 +24,16 @@ export function getMenuTree(menuName?: string, parent?: string, type?: string) {
}) })
} }
export function getRoleTree(roleId: string) {
return new Promise(resolve => {
request.get(getMenuTreeUrl + "/" + roleId).then(res => {
resolve(res.data);
}).catch(err => {
resolve(err);
});
})
}
export function saveMenu(menu: any) { export function saveMenu(menu: any) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request.post(menuUrl, menu).then((res: any) => { request.post(menuUrl, menu).then((res: any) => {
@ -52,4 +62,18 @@ export function deleteById(id: string) {
resolve(err); resolve(err);
}) })
}) })
}
export function getUserMenu(type?: string, parentId?: string) {
return new Promise(resolve => {
const params: string[] = [];
if (type) params.push("type=" + type);
if (parentId) params.push("parentId=" + parentId);
request.get(menuUrl + (params.length > 0 ? "?" + params.join("&") : ""))
.then((res: any) => {
resolve(res.data);
}).catch(err => {
resolve(err);
});
})
} }

View File

@ -1,7 +1,9 @@
import request, {getData} from "@/utils/request"; import request, {getData} from "@/utils/request";
const getRoleListUrl = '/admin/role/page'; const getRoleListUrl = '/admin/role/tree';
const roleUrl = "/admin/role"; const roleUrl = "/admin/role";
const saveRoleMenuUrl = "/admin/role/menu";
const getDetailsUrl = "/admin/role/details";
export function getRoleList(current: number, size: number, name?: string) { export function getRoleList(current: number, size: number, name?: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -25,3 +27,24 @@ export function addRole(role: any) {
}) })
} }
export function saveRoleMenus(roleId: string, menuIds: string) {
return new Promise(resolve => {
request.put(saveRoleMenuUrl, {roleId, menuIds})
.then(res => {
resolve(res.data);
}).catch(err => {
resolve(err);
})
})
}
export function getDetails(id: string) {
return new Promise(resolve => {
request(getDetailsUrl + "/" + id).then(res => {
resolve(res.data);
}).catch(err => {
resolve(err);
})
})
}

View File

@ -1,122 +1,108 @@
<template> <template>
<el-dialog v-model="dialogVisible" width="30%"> <el-dialog v-model="dialogVisible" width="30%">
<template #header> <template #header>
<span class="el-dialog__title" style="margin-right: 50px;">授权权限</span> <span class="el-dialog__title" style="margin-right: 50px;">授权权限</span>
<el-checkbox v-model="toggleExpand" @change="toggleExpandChange">展开 / 折叠</el-checkbox> <el-checkbox v-model="toggleExpand" @change="toggleExpandChange">展开 / 折叠</el-checkbox>
<el-checkbox v-model="toggleSelectAll" @change="toggleSelectAllChange">全选 / 全不选</el-checkbox> <el-checkbox v-model="toggleSelectAll" @change="toggleSelectAllChange">全选 / 全不选</el-checkbox>
</template> </template>
<div style="min-height: 200px;max-height: 500px;overflow-y: auto;"> <div style="min-height: 200px;max-height: 500px;overflow-y: auto;">
<el-tree ref="treeRef" :key="treeKey" :props="props" :data="treeData" :default-expanded-keys="expandedKey" node-key="id" <el-tree ref="treeRef" :props="props" :data="treeData" :default-expanded-keys="expandedKey"
show-checkbox @check-change="checkChange" /> node-key="id"
</div> show-checkbox/>
<div style="text-align: right;margin-top: 20px;"> </div>
<el-button class="f18" @click="dialogVisible = false">取消</el-button> <div style="text-align: right;margin-top: 20px;">
<el-button class="f18" type="primary" @click="updateData">更新</el-button> <el-button class="f18" @click="dialogVisible = false">取消</el-button>
</div> <el-button class="f18" type="primary" @click="updateData">更新</el-button>
</el-dialog> </div>
</el-dialog>
</template> </template>
<script lang='ts' setup> <script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue' import {ref} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus' import {ElMessage} from 'element-plus'
import { getMenuData } from '@/static-data/menu' import * as menuApi from "@/api/menu";
import * as roleApi from "@/api/role";
const props = { const props = {
label: 'menuName', label: 'name',
children: 'children' children: 'children'
} }
let treeIds: Array<string> = [] const treeIds: Array<string> = []
let checkDatas: Array<any> = []
const treeRef = ref() const treeRef = ref()
const treeKey = ref(0)
const dialogVisible = ref(false) const dialogVisible = ref(false)
const toggleExpand = ref(false) const toggleExpand = ref(false)
const toggleSelectAll = ref(false) const toggleSelectAll = ref(false)
const treeData = ref() const treeData = ref()
const expandedKey = ref<Array<string>>([]) const expandedKey = ref<Array<string>>([])
let roleObj: any;
initTree()
defineExpose({ defineExpose({
open, open,
close, close
initTree,
})
onMounted(() => {
}) })
function open() { function open(role: any) {
dialogVisible.value = true dialogVisible.value = true
setTimeout(() => { roleObj = role;
setTreeChecked(['0']) getMenuTree();
}, 0) getRoleMenu();
} }
function close() { function close() {
dialogVisible.value = false dialogVisible.value = false
} }
function initTree() {
treeData.value = [ const getMenuTree = () => {
{ menuApi.getMenuTree().then((res: any) => {
id: '1', label: '权限管理', children: [ treeData.value = res.data;
{ setTreeIds(res.data, treeIds);
id: '1-1', label: '医生管理', children: [ });
{ id: '1-1-1', label: '医生新增' },
{ id: '1-1-2', label: '医生删除' }
]
}
]
},
{
id: '2', label: '患者管理', children: [
{
id: '2-1', label: '医生管理', children: [
{ id: '2-1-1', label: '医生新增' }
]
}
]
}
]
treeData.value = getMenuData()
treeIds = []
const setTreeIds = (ary: any) => {
for (let i = 0; i < ary.length; i++) {
const obj = ary[i]
treeIds.push(obj.id)
if(obj.children && obj.children.length > 0) setTreeIds(obj.children)
}
}
// id使
setTreeIds(treeData.value)
} }
function setTreeChecked(e?: Array<any>) {
e && treeRef.value.setCheckedKeys(e) const getRoleMenu = () => {
menuApi.getRoleTree(roleObj.roleId).then((res: any) => {
treeRef.value.setCheckedKeys(res.data);
})
}
const setTreeIds = (data: any[], container: string[]) => {
data.forEach((menu: any) => {
container.push(menu.id);
if (menu.children) {
setTreeIds(menu.children, container);
}
});
} }
const toggleExpandChange = (e: boolean) => { const toggleExpandChange = (e: boolean) => {
if (e) expandedKey.value = JSON.parse(JSON.stringify(treeIds)) setTreeExpand(treeRef.value.store.root, e)
else {
expandedKey.value = []
const storeCheck = JSON.parse(JSON.stringify(checkDatas)) //
treeKey.value++ //
setTimeout(() => {
setTreeChecked(storeCheck)
})
}
} }
const setTreeExpand = (node: any, status: boolean) => {
node.expanded = status;
if (node.childNodes) {
node.childNodes.forEach((node: any) => {
setTreeExpand(node, status);
})
}
}
const toggleSelectAllChange = (e: boolean) => { const toggleSelectAllChange = (e: boolean) => {
// console.log(e) if (!e) treeRef.value.setCheckedNodes(treeIds)
if (!e) treeRef.value.setCheckedNodes(treeIds) else treeRef.value.setCheckedKeys(treeIds)
else treeRef.value.setCheckedKeys(treeIds)
}
const checkChange = () => {
checkDatas = treeRef.value.getCheckedKeys()
} }
const updateData = () => { const updateData = () => {
ElMessage.success('更新成功') const menuIds = treeRef.value.getCheckedKeys().join(",");
close() roleApi.saveRoleMenus(roleObj.roleId, menuIds)
.then((res: any) => {
if (res.code == 0) {
ElMessage.success('更新成功');
close();
} else {
ElMessage.error(res.msg ? res.msg : "更新失败");
}
});
} }
</script> </script>

View File

@ -25,7 +25,20 @@
<el-table-column property="roleName" label="角色名称" width="120" align="center"/> <el-table-column property="roleName" label="角色名称" width="120" align="center"/>
<el-table-column property="roleCode" label="角色标识" width="180" align="center"/> <el-table-column property="roleCode" label="角色标识" width="180" align="center"/>
<el-table-column property="roleDesc" label="角色描述" width="120" align="center"/> <el-table-column property="roleDesc" label="角色描述" width="120" align="center"/>
<el-table-column property="dataPermissions" label="数据权限" width="120" align="center"/> <el-table-column label="数据权限" width="120" align="center">
<template #default="scope">
<el-popover
trigger="hover"
:content="scope.row.menu"
>
<template #reference>
<div class="cell-content">
{{ scope.row.menu }}
</div>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column label="创建时间" width="220" align="center"> <el-table-column label="创建时间" width="220" align="center">
<template #default="scope">{{ scope.row.createTime }}</template> <template #default="scope">{{ scope.row.createTime }}</template>
</el-table-column> </el-table-column>
@ -128,7 +141,7 @@ const removeData = (e?: any) => {
} }
const empower = (e: any) => { const empower = (e: any) => {
setTimeout(() => { setTimeout(() => {
empowerDialogRef.value.open() empowerDialogRef.value.open(e)
}) })
} }
const editData = (e: any) => { const editData = (e: any) => {
@ -150,4 +163,20 @@ const paginationChange = (page: number, s: number) => {
} }
</script> </script>
<style lang='scss' scoped></style> <style lang='scss' scoped>
:deep(.el-table__body) {
.cell {
max-height: 49px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.cell-content {
max-height: 49px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
</style>

View File

@ -783,169 +783,171 @@ function startAI() {
border-radius: 10px; border-radius: 10px;
} }
.unusual-box { .unusual-box {
width: 100%; width: 100%;
height: calc(100% - 45px); height: calc(100% - 45px);
// background: #F8F8F8; // background: #F8F8F8;
border-left: 1px dashed #C1C1C1; border-left: 1px dashed #C1C1C1;
// border-radius: 4px; // border-radius: 4px;
margin-top: 5px; margin-top: 5px;
padding: 8px 16px; padding: 8px 16px;
overflow-y: auto; overflow-y: auto;
li { li {
color: #F80000; color: #F80000;
font-size: 14px; font-size: 14px;
line-height: 22px; line-height: 22px;
} }
} }
} }
& > .right-box { & > .right-box {
width: calc(100% - 205px); width: calc(100% - 205px);
height: 100%; height: 100%;
.video-box { .video-box {
position: relative; position: relative;
width: 100%; width: 100%;
height: 270px; height: 270px;
background: $main-color; background: $main-color;
/* background: url(@/assets/imgs/video_bck.png); /* background: url(@/assets/imgs/video_bck.png);
background-size: 100% 100%; */ background-size: 100% 100%; */
&:hover { &:hover {
.icon-box { .icon-box {
display: flex; display: flex;
} }
} }
.icon-box { .icon-box {
display: none; display: none;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
font-size: 60px; font-size: 60px;
color: white; color: white;
background: rgba(black, .3); background: rgba(black, .3);
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
video { video {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
} }
} }
.message-box { .message-box {
width: 100%; width: 100%;
height: 270px; // height: 270px;
// margin-bottom: 5px; height: 149px;
// margin-bottom: 5px;
.message-log { .message-log {
width: 100%; width: 100%;
height: calc(100% - 40px); height: calc(100% - 40px);
padding: 16px 20px; max-height: 109px;
box-sizing: border-box; padding: 16px 20px;
border: 1px solid #c8c8c8; box-sizing: border-box;
background: #f8f8f8; border: 1px solid #c8c8c8;
overflow-y: auto; background: #f8f8f8;
overflow-y: auto;
li { li {
width: 100%; width: 100%;
font-size: 14px; font-size: 14px;
line-height: 1.6; line-height: 1.6;
margin: 5px 0; margin: 5px 0;
&.align-right { &.align-right {
text-align: right; text-align: right;
} }
span { span {
display: inline-block; display: inline-block;
max-width: 80%; max-width: 80%;
padding: 6px 8px; padding: 6px 8px;
box-sizing: border-box; box-sizing: border-box;
border-radius: 8px; border-radius: 8px;
color: white; color: white;
letter-spacing: 1px; letter-spacing: 1px;
background: $main-color; background: $main-color;
text-align: left; text-align: left;
} }
} }
} }
.send-box { .send-box {
width: 100%; width: 100%;
height: 40px; height: 40px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: flex-end; align-items: flex-end;
.el-input { .el-input {
width: calc(100% - 110px); width: calc(100% - 110px);
height: 32px; height: 32px;
:deep(.el-input__wrapper) { :deep(.el-input__wrapper) {
background-color: #F2F3F5; background-color: #F2F3F5;
border-color: #C1C1C1; border-color: #C1C1C1;
} }
} }
.el-button { .el-button {
padding: 0; padding: 0;
width: 100px; width: 100px;
line-height: 30px; line-height: 30px;
} }
} }
} }
} }
} }
.table-box { .table-box {
width: 100%; width: 100%;
height: calc(50% - 264.5px); height: calc(50% - 264.5px);
margin-bottom: 20px; margin-bottom: 20px;
flex-grow: 1; flex-grow: 1;
:deep(.el-table__inner-wrapper) { :deep(.el-table__inner-wrapper) {
.el-table__cell { .el-table__cell {
padding: 6px 0; padding: 6px 0;
} }
.cell { .cell {
padding: 0 2px; padding: 0 2px;
} }
.el-table__header-wrapper { .el-table__header-wrapper {
tr { tr {
background-color: $main-color; background-color: $main-color;
} }
th.el-table__cell { th.el-table__cell {
color: white; color: white;
background-color: $main-color; background-color: $main-color;
padding: 8px 0; padding: 8px 0;
font-weight: 400; font-weight: 400;
} }
} }
} }
.table-btn-box { .table-btn-box {
.el-button { .el-button {
padding: 0 7px; padding: 0 7px;
height: 24px; height: 24px;
line-height: 22px; line-height: 22px;
&:not(:first-of-type) { &:not(:first-of-type) {
margin-left: 4px; margin-left: 4px;
} }
} }
} }
} }
} }
} }
}</style> }</style>