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)
+  }
 }
 
 /** 删除按钮操作 */