From 20b3eacce9070ab514b03c06c6344993f900cd9a Mon Sep 17 00:00:00 2001 From: Chika <wbs_2018@sina.com> Date: Sat, 1 Apr 2023 10:03:11 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E9=87=8D=E6=9E=84=E3=80=91Vue3=20?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0=EF=BC=9A[=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E7=AE=A1=E7=90=86=20->=20=E8=A7=92=E8=89=B2=E7=AE=A1?= =?UTF-8?q?=E7=90=86]=20=E4=BD=BF=E7=94=A8=20Element=20Plus=20=E5=8E=9F?= =?UTF-8?q?=E7=94=9F=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/system/role/DataPermissionForm.vue | 174 +++++++++++++++++++ src/views/system/role/MenuPermissionForm.vue | 84 ++------- src/views/system/role/index.vue | 14 +- 3 files changed, 203 insertions(+), 69 deletions(-) create mode 100644 src/views/system/role/DataPermissionForm.vue diff --git a/src/views/system/role/DataPermissionForm.vue b/src/views/system/role/DataPermissionForm.vue new file mode 100644 index 00000000..bccc5f46 --- /dev/null +++ b/src/views/system/role/DataPermissionForm.vue @@ -0,0 +1,174 @@ +<template> + <Dialog :title="dialogScopeTitle" v-model="dialogScopeVisible" width="800"> + <el-form + ref="dataPermissionFormRef" + :model="dataScopeForm" + :inline="true" + label-width="80px" + v-loading="formLoading" + > + <el-form-item label="角色名称"> + <el-tag>{{ dataScopeForm.name }}</el-tag> + </el-form-item> + <el-form-item label="角色标识"> + <el-tag>{{ dataScopeForm.code }}</el-tag> + </el-form-item> + <!-- 分配角色的数据权限对话框 --> + <el-form-item label="权限范围"> + <el-select v-model="dataScopeForm.dataScope"> + <el-option + v-for="item in dataScopeDictDatas" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + </el-form> + <!-- 分配角色的菜单权限对话框 --> + <el-row> + <el-col :span="24"> + <el-form-item + label="权限范围" + v-if=" + actionScopeType === 'menu' || + dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM + " + style="display: flex" + > + <el-card class="card" shadow="never"> + <template #header> + 父子联动(选中父节点,自动选择子节点): + <el-switch + v-model="checkStrictly" + inline-prompt + active-text="是" + inactive-text="否" + /> + 全选/全不选: + <el-switch + v-model="treeNodeAll" + inline-prompt + active-text="是" + inactive-text="否" + @change="handleCheckedTreeNodeAll()" + /> + </template> + <el-tree + ref="treeRef" + node-key="id" + show-checkbox + :check-strictly="!checkStrictly" + :props="defaultProps" + :data="treeOptions" + empty-text="加载中,请稍后" + /> + </el-card> + </el-form-item> </el-col + ></el-row> + + <!-- 操作按钮 --> + <template #footer> + <div class="dialog-footer"> + <el-button + :title="t('action.save')" + :loading="actionLoading" + @click="submitScope()" + type="primary" + :disabled="formLoading" + > + 保存 + </el-button> + <el-button + :loading="actionLoading" + :title="t('dialog.close')" + @click="dialogScopeVisible = false" + >取 消</el-button + > + </div> + </template> + </Dialog> +</template> + +<script setup lang="ts"> +import * as RoleApi from '@/api/system/role' +import type { ElTree } from 'element-plus' +import type { FormExpose } from '@/components/Form' +import { handleTree, defaultProps } from '@/utils/tree' +import { SystemDataScopeEnum } from '@/utils/constants' +import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' +import * as DeptApi from '@/api/system/dept' +import * as PermissionApi from '@/api/system/permission' +// ========== CRUD 相关 ========== +const actionLoading = ref(false) // 遮罩层 +const dataPermissionFormRef = ref<FormExpose>() // 表单 Ref +const { t } = useI18n() // 国际化 +const dialogScopeTitle = ref('菜单权限') +const dataScopeDictDatas = ref() +const message = useMessage() // 消息弹窗 +const actionScopeType = ref('') +// 选项 +const treeNodeAll = ref(false) +const checkStrictly = ref(true) +const dialogScopeVisible = ref(false) // 弹窗的是否展示 +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 +const treeOptions = ref<any[]>([]) // 菜单树形结构 +const treeRef = ref<InstanceType<typeof ElTree>>() +// ========== 数据权限 ========== +const dataScopeForm = reactive({ + id: 0, + name: '', + code: '', + dataScope: 0, + checkList: [] +}) + +/** 打开弹窗 */ +const openModal = async (type: string, row: RoleApi.RoleVO) => { + dataScopeForm.id = row.id + dataScopeForm.name = row.name + dataScopeForm.code = row.code + actionScopeType.value = type + dialogScopeVisible.value = true + const deptRes = await DeptApi.getSimpleDeptList() + treeOptions.value = handleTree(deptRes) + const role = await RoleApi.getRole(row.id) + dataScopeForm.dataScope = role.dataScope + if (role.dataScopeDeptIds) { + role.dataScopeDeptIds?.forEach((item: any) => { + unref(treeRef)?.setChecked(item, true, false) + }) + } +} + +// 保存权限 +const submitScope = async () => { + const data = ref<PermissionApi.PermissionAssignRoleDataScopeReqVO>({ + roleId: dataScopeForm.id, + dataScope: dataScopeForm.dataScope, + dataScopeDeptIds: + dataScopeForm.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM + ? [] + : (treeRef.value!.getCheckedKeys(false) as unknown as Array<number>) + }) + await PermissionApi.assignRoleDataScopeApi(data.value) + + message.success(t('common.updateSuccess')) + dialogScopeVisible.value = false +} + +// 全选/全不选 +const handleCheckedTreeNodeAll = () => { + treeRef.value!.setCheckedNodes(treeNodeAll.value ? treeOptions.value : []) +} + +const init = () => { + dataScopeDictDatas.value = getIntDictOptions(DICT_TYPE.SYSTEM_DATA_SCOPE) +} + +defineExpose({ openModal }) // 提供 openModal 方法,用于打开弹窗 +// ========== 初始化 ========== +onMounted(() => { + init() +}) +</script> diff --git a/src/views/system/role/MenuPermissionForm.vue b/src/views/system/role/MenuPermissionForm.vue index 70971781..a7995fec 100644 --- a/src/views/system/role/MenuPermissionForm.vue +++ b/src/views/system/role/MenuPermissionForm.vue @@ -13,28 +13,10 @@ <el-form-item label="角色标识"> <el-tag>{{ dataScopeForm.code }}</el-tag> </el-form-item> - <!-- 分配角色的数据权限对话框 --> - <el-form-item label="权限范围" v-if="actionScopeType === 'data'"> - <el-select v-model="dataScopeForm.dataScope"> - <el-option - v-for="item in dataScopeDictDatas" - :key="item.value" - :label="item.label" - :value="item.value" - /> - </el-select> - </el-form-item> <!-- 分配角色的菜单权限对话框 --> <el-row> <el-col :span="24"> - <el-form-item - label="权限范围" - v-if=" - actionScopeType === 'menu' || - dataScopeForm.dataScope === SystemDataScopeEnum.DEPT_CUSTOM - " - style="display: flex" - > + <el-form-item label="权限范围" style="display: flex"> <el-card class="card" shadow="never"> <template #header> 父子联动(选中父节点,自动选择子节点): @@ -94,10 +76,8 @@ import * as RoleApi from '@/api/system/role' import type { ElTree } from 'element-plus' import type { FormExpose } from '@/components/Form' import { handleTree, defaultProps } from '@/utils/tree' -import { SystemDataScopeEnum } from '@/utils/constants' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import * as MenuApi from '@/api/system/menu' -import * as DeptApi from '@/api/system/dept' import * as PermissionApi from '@/api/system/permission' // ========== CRUD 相关 ========== const actionLoading = ref(false) // 遮罩层 @@ -130,50 +110,27 @@ const openModal = async (type: string, row: RoleApi.RoleVO) => { dataScopeForm.code = row.code actionScopeType.value = type dialogScopeVisible.value = true - if (type === 'menu') { - const menuRes = await MenuApi.getSimpleMenusList() - treeOptions.value = handleTree(menuRes) - const role = await PermissionApi.listRoleMenusApi(row.id) - if (role) { - role?.forEach((item: any) => { - unref(treeRef)?.setChecked(item, true, false) - }) - } - } else if (type === 'data') { - const deptRes = await DeptApi.getSimpleDeptList() - treeOptions.value = handleTree(deptRes) - const role = await RoleApi.getRole(row.id) - dataScopeForm.dataScope = role.dataScope - if (role.dataScopeDeptIds) { - role.dataScopeDeptIds?.forEach((item: any) => { - unref(treeRef)?.setChecked(item, true, false) - }) - } + const menuRes = await MenuApi.getSimpleMenusList() + treeOptions.value = handleTree(menuRes) + const role = await PermissionApi.listRoleMenusApi(row.id) + if (role) { + role?.forEach((item: any) => { + unref(treeRef)?.setChecked(item, true, false) + }) } } // 保存权限 const submitScope = async () => { - if ('data' === actionScopeType.value) { - const data = ref<PermissionApi.PermissionAssignRoleDataScopeReqVO>({ - roleId: dataScopeForm.id, - dataScope: dataScopeForm.dataScope, - dataScopeDeptIds: - dataScopeForm.dataScope !== SystemDataScopeEnum.DEPT_CUSTOM - ? [] - : (treeRef.value!.getCheckedKeys(false) as unknown as Array<number>) - }) - await PermissionApi.assignRoleDataScopeApi(data.value) - } else if ('menu' === actionScopeType.value) { - const data = ref<PermissionApi.PermissionAssignRoleMenuReqVO>({ - roleId: dataScopeForm.id, - menuIds: [ - ...(treeRef.value!.getCheckedKeys(false) as unknown as Array<number>), - ...(treeRef.value!.getHalfCheckedKeys() as unknown as Array<number>) - ] - }) - await PermissionApi.assignRoleMenuApi(data.value) - } + const data = ref<PermissionApi.PermissionAssignRoleMenuReqVO>({ + roleId: dataScopeForm.id, + menuIds: [ + ...(treeRef.value!.getCheckedKeys(false) as unknown as Array<number>), + ...(treeRef.value!.getHalfCheckedKeys() as unknown as Array<number>) + ] + }) + await PermissionApi.assignRoleMenuApi(data.value) + message.success(t('common.updateSuccess')) dialogScopeVisible.value = false } @@ -193,10 +150,3 @@ onMounted(() => { init() }) </script> -<style scoped> -.card { - width: 100%; - max-height: 400px; - overflow-y: scroll; -} -</style> diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index af8e0d3a..4be8e48c 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -146,11 +146,14 @@ <RoleForm ref="formRef" @success="getList" /> <!-- 表单弹窗:菜单权限 --> <MenuPermissionForm ref="menuPermissionFormRef" @success="getList" /> + <!-- 表单弹窗:数据权限 --> + <DataPermissionForm ref="dataPermissionFormRef" @success="getList" /> </template> <script setup lang="tsx"> import * as RoleApi from '@/api/system/role' import RoleForm from './RoleForm.vue' import MenuPermissionForm from './MenuPermissionForm.vue' +import DataPermissionForm from './DataPermissionForm.vue' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { dateFormatter } from '@/utils/formatTime' import download from '@/utils/download' @@ -201,10 +204,17 @@ const openForm = (type: string, id?: number) => { formRef.value.open(type, id) } -/** 数据权限操作 */ +/** 菜单权限操作 */ const menuPermissionFormRef = ref() +/** 数据权限操作 */ +const dataPermissionFormRef = ref() + const handleScope = async (type: string, row: RoleApi.RoleVO) => { - menuPermissionFormRef.value.openModal(type, row) + if (type === 'menu') { + menuPermissionFormRef.value.openModal(type, row) + } else if (type === 'data') { + dataPermissionFormRef.value.openModal(type, row) + } } /** 删除按钮操作 */