Bläddra i källkod

优化权限展示

lxr 2 månader sedan
förälder
incheckning
1a5f71142e
1 ändrade filer med 132 tillägg och 175 borttagningar
  1. 132 175
      src/views/accountRoleManagement/subAccountManagement/create.vue

+ 132 - 175
src/views/accountRoleManagement/subAccountManagement/create.vue

@@ -40,15 +40,25 @@
             </el-select>
           </el-form-item>
 
-          <!-- 权限列表 -->
-          <el-form-item label="权限" prop="permissions" v-if="permissionList.length > 0">
-            <div class="permission-list">
-              <template v-if="permissionList.length > 0">
-                <PermissionItem v-for="permission in permissionList" :key="permission.id" :permission="permission" :level="0" />
-              </template>
-              <div v-else class="permission-empty">
-                <span class="empty-text">暂无权限</span>
-              </div>
+          <!-- 权限展示:与角色管理相同的树状图,仅禁用展示 -->
+          <el-form-item label="权限" v-if="subAccountForm.roleId && permissionTreeData.length > 0">
+            <div class="permission-tree-container">
+              <el-tree
+                ref="permissionTreeRef"
+                :data="permissionTreeData"
+                :props="treeProps"
+                show-checkbox
+                node-key="id"
+                :default-expand-all="true"
+                :default-checked-keys="defaultCheckedKeys"
+                :expand-on-click-node="false"
+              >
+                <template #default="{ data }">
+                  <span class="tree-node-label">
+                    <span>{{ data.label }}</span>
+                  </span>
+                </template>
+              </el-tree>
             </div>
           </el-form-item>
         </div>
@@ -66,7 +76,7 @@
 </template>
 
 <script setup lang="ts" name="subAccountCreate">
-import { ref, reactive, onMounted, computed } from "vue";
+import { ref, reactive, onMounted, computed, nextTick } from "vue";
 import { useRouter, useRoute } from "vue-router";
 import { ElMessage, type FormInstance, type FormRules } from "element-plus";
 import { ArrowLeft } from "@element-plus/icons-vue";
@@ -80,7 +90,6 @@ import {
   updateSubAccount
 } from "@/api/modules/accountRoleManagement";
 import { localGet } from "@/utils";
-import PermissionItem from "./PermissionItem.vue";
 // 路由
 const router = useRouter();
 const route = useRoute();
@@ -98,7 +107,6 @@ const subAccountForm = reactive({
   accountName: "",
   phone: "",
   roleId: undefined as number | undefined,
-  permissions: [] as number[],
   userId: undefined as number | undefined
 });
 
@@ -115,17 +123,17 @@ const subAccountFormRules: FormRules = {
 // 角色列表
 const roleList = ref<RoleItem[]>([]);
 
-// 权限项接口
-interface PermissionItem {
-  id: number;
-  name: string;
-  checked: boolean;
-  expanded: boolean;
-  children?: PermissionItem[];
-}
+// 树形组件配置(disabled 用于只读展示)
+const treeProps = {
+  children: "children",
+  label: "label",
+  disabled: "disabled"
+};
 
-// 权限列表
-const permissionList = ref<PermissionItem[]>([]);
+// 权限树数据(与角色管理同结构,节点全部 disabled)
+const permissionTreeData = ref<any[]>([]);
+const permissionTreeRef = ref<any>();
+const defaultCheckedKeys = ref<number[]>([]);
 
 // 保存加载状态
 const saveLoading = ref(false);
@@ -155,155 +163,96 @@ const loadRoleList = async () => {
   }
 };
 
-// 将扁平格式的权限数据转换为树形结构
-const transformFlatPermissionsToTree = (permissionList: RolePermissionItem[]): PermissionItem[] => {
-  const level1Map = new Map<string, PermissionItem>();
-  const level2Map = new Map<string, PermissionItem>();
-  const level3Map = new Map<string, PermissionItem>();
+// 将角色权限(仅已选中的)转成树结构,不包含未选中的节点
+const transformRolePermissionsToTree = (list: RolePermissionItem[]): { tree: any[]; allIds: number[] } => {
+  const level1Map = new Map<string, any>();
+  const level2Map = new Map<string, any>();
+  const level3Map = new Map<string, any>();
+  const allIds: number[] = [];
   let idCounter = 1;
 
-  // 遍历所有权限项,构建树形结构
-  permissionList.forEach(item => {
-    // 处理一级权限
-    if (item.level1Permission) {
-      let level1 = level1Map.get(item.level1Permission);
-
-      if (!level1) {
-        level1 = {
-          id: idCounter++,
-          name: item.level1Permission,
-          checked: false,
-          expanded: true, // 一级权限默认展开
-          children: []
-        };
-        level1Map.set(item.level1Permission, level1);
-      }
+  for (const item of list || []) {
+    if (!item.level1Permission) continue;
 
-      // 处理二级权限
-      if (item.level2Permission) {
-        const level2Key = `${item.level1Permission}-${item.level2Permission}`;
-        let level2 = level2Map.get(level2Key);
-
-        if (!level2) {
-          level2 = {
-            id: idCounter++,
-            name: item.level2Permission,
-            checked: false,
-            expanded: false,
-            children: []
-          };
-          level2Map.set(level2Key, level2);
-
-          // 确保一级权限的children数组存在并添加二级权限
-          if (!level1.children) {
-            level1.children = [];
-          }
-          // 检查是否已存在,避免重复添加
-          const existingLevel2 = level1.children.find(child => child.id === level2!.id);
-          if (!existingLevel2) {
-            level1.children.push(level2);
-          }
-        }
+    let level1 = level1Map.get(item.level1Permission);
+    if (!level1) {
+      level1 = { id: idCounter++, label: item.level1Permission, disabled: true, children: [] };
+      allIds.push(level1.id);
+      level1Map.set(item.level1Permission, level1);
+    }
 
-        // 处理三级权限
-        if (item.level3Permission) {
-          // 重新获取 level2,确保它存在
-          const currentLevel2 = level2Map.get(level2Key);
-
-          if (currentLevel2) {
-            const level3Key = `${level2Key}-${item.level3Permission}`;
-            let level3 = level3Map.get(level3Key);
-
-            if (!level3) {
-              level3 = {
-                id: idCounter++,
-                name: item.level3Permission,
-                checked: false,
-                expanded: false
-              };
-              level3Map.set(level3Key, level3);
-
-              // 确保二级权限的children数组存在并添加三级权限
-              if (!currentLevel2.children) {
-                currentLevel2.children = [];
-              }
-              // 检查是否已存在,避免重复添加
-              const existingLevel3 = currentLevel2.children.find(child => child.id === level3!.id);
-              if (!existingLevel3) {
-                currentLevel2.children.push(level3);
-              }
-            }
-          }
+    if (item.level2Permission) {
+      const k2 = `${item.level1Permission}-${item.level2Permission}`;
+      let level2 = level2Map.get(k2);
+      if (!level2) {
+        level2 = { id: idCounter++, label: item.level2Permission, disabled: true, children: [] };
+        allIds.push(level2.id);
+        level2Map.set(k2, level2);
+        level1.children.push(level2);
+      }
+
+      if (item.level3Permission?.trim()) {
+        const names = item.level3Permission
+          .split(/\s+/)
+          .map(s => s.trim())
+          .filter(Boolean);
+        for (const name of names) {
+          const k3 = `${k2}-${name}`;
+          if (level3Map.has(k3)) continue;
+          const level3 = { id: idCounter++, label: name, disabled: true };
+          allIds.push(level3.id);
+          level3Map.set(k3, level3);
+          level2.children.push(level3);
         }
       }
     }
-  });
+  }
 
-  // 返回所有一级权限
-  return Array.from(level1Map.values());
+  return { tree: Array.from(level1Map.values()), allIds };
 };
 
-// 加载权限列表
+// 加载当前角色权限:只展示已选中的权限树(不展示未选中的)
 const loadPermissionList = async () => {
   if (!subAccountForm.roleId) {
-    permissionList.value = [];
+    permissionTreeData.value = [];
+    defaultCheckedKeys.value = [];
     return;
   }
 
   try {
     const roleId = Number(subAccountForm.roleId);
     if (!roleId || isNaN(roleId)) {
-      permissionList.value = [];
+      permissionTreeData.value = [];
+      defaultCheckedKeys.value = [];
       return;
     }
 
     const res = await getRolePermissionTable({ roleId });
     const code = typeof res.code === "string" ? parseInt(res.code) : res.code;
     if (code === 200 && res.data) {
-      permissionList.value = transformFlatPermissionsToTree(res.data);
+      const { tree, allIds } = transformRolePermissionsToTree(res.data);
+      permissionTreeData.value = tree;
+      defaultCheckedKeys.value = allIds;
+      nextTick(() => {
+        permissionTreeRef.value?.setCheckedKeys(allIds);
+      });
     } else {
       ElMessage.error(res.msg || "获取权限列表失败");
-      permissionList.value = [];
+      permissionTreeData.value = [];
+      defaultCheckedKeys.value = [];
     }
   } catch (error) {
     console.error("获取权限列表失败:", error);
     ElMessage.error("获取权限列表失败,请重试");
-    permissionList.value = [];
-  }
-};
-
-// 递归收集所有选中的权限ID
-const collectCheckedPermissions = (permission: PermissionItem): number[] => {
-  const permissions: number[] = [];
-  if (permission.checked) {
-    permissions.push(permission.id);
-  }
-  if (permission.children) {
-    permission.children.forEach(child => {
-      permissions.push(...collectCheckedPermissions(child));
-    });
+    permissionTreeData.value = [];
+    defaultCheckedKeys.value = [];
   }
-  return permissions;
-};
-
-// 重置权限列表选中状态
-const resetPermissions = () => {
-  const resetItem = (item: PermissionItem) => {
-    item.checked = false;
-    if (item.children) {
-      item.children.forEach(child => resetItem(child));
-    }
-  };
-  permissionList.value.forEach(item => resetItem(item));
-  subAccountForm.permissions = [];
 };
 
 // 初始化数据
 onMounted(() => {
   loadRoleList();
-  // 不在这里加载权限列表,等用户选择角色后再加载
   if (isEdit.value || isView.value) {
-    // 编辑或查看模式:加载子账号数据
     loadSubAccountData();
   }
 });
@@ -330,16 +279,9 @@ const loadSubAccountData = async () => {
       subAccountForm.roleId = accountData.roleId;
       subAccountForm.userId = accountData.userId || Number(accountId.value);
 
-      // 如果有权限数据,先加载角色权限列表,然后设置选中状态
+      // 按角色加载权限树勾选(权限由角色决定,仅展示)
       if (subAccountForm.roleId) {
         await loadPermissionList();
-
-        // 如果接口返回了权限ID列表,设置选中状态
-        if (accountData.permissions && Array.isArray(accountData.permissions)) {
-          const permissionIds = accountData.permissions.map((p: any) => (typeof p === "object" ? p.id || p.permissionId : p));
-          subAccountForm.permissions = permissionIds;
-          setPermissionsChecked(permissionIds);
-        }
       }
     } else {
       ElMessage.error(res.msg || "获取子账号详情失败");
@@ -350,19 +292,6 @@ const loadSubAccountData = async () => {
   }
 };
 
-// 设置权限选中状态
-const setPermissionsChecked = (permissionIds: number[]) => {
-  const setItemChecked = (item: PermissionItem) => {
-    if (permissionIds.includes(item.id)) {
-      item.checked = true;
-    }
-    if (item.children) {
-      item.children.forEach(child => setItemChecked(child));
-    }
-  };
-  permissionList.value.forEach(item => setItemChecked(item));
-};
-
 // 返回
 const handleBack = () => {
   router.back();
@@ -401,13 +330,11 @@ const handleSave = async () => {
         };
         const res = await updateSubAccount(updateAccountDto);
         const code = typeof res.code === "string" ? parseInt(res.code) : res.code;
-        if (code === 200) {
+        if (code == 200) {
           ElMessage.success("编辑成功");
           setTimeout(() => {
             router.push("/accountRoleManagement/subAccountManagement");
           }, 1000);
-        } else {
-          ElMessage.error(res.msg || "编辑失败");
         }
       } else {
         // 创建模式:调用创建接口
@@ -420,17 +347,14 @@ const handleSave = async () => {
         const res = await createAccountAndAssignRole(createAccountDto);
         const code = typeof res.code === "string" ? parseInt(res.code) : res.code;
         if (code === 200) {
-          ElMessage.success("创建成功");
+          ElMessage.success("创建成功后,员工可以使用手机号与验证码进行登录");
           setTimeout(() => {
             router.push("/accountRoleManagement/subAccountManagement");
           }, 1000);
-        } else {
-          ElMessage.error(res.msg || "创建失败");
         }
       }
     } catch (error) {
       console.error("保存失败:", error);
-      ElMessage.error("保存失败,请重试");
     } finally {
       saveLoading.value = false;
     }
@@ -439,12 +363,12 @@ const handleSave = async () => {
 // 处理角色选择变化
 const handleRoleChange = (value: number | null | undefined) => {
   subAccountForm.roleId = value as number | undefined;
-  permissionList.value = [];
+  permissionTreeData.value = [];
+  defaultCheckedKeys.value = [];
   if (value) {
     loadPermissionList();
   } else {
-    // 如果清空了角色选择,重置权限列表
-    resetPermissions();
+    nextTick(() => permissionTreeRef.value?.setCheckedKeys([]));
   }
 };
 </script>
@@ -484,18 +408,51 @@ const handleRoleChange = (value: number | null | undefined) => {
     }
   }
 
-  // 权限列表
-  .permission-list {
+  // 权限树(与角色管理同款样式,仅禁用展示)
+  .permission-tree-container {
     width: 100%;
-    .permission-empty {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      padding: 40px 0;
-      color: var(--el-text-color-placeholder);
-      .empty-text {
+    min-height: 200px;
+    max-height: 500px;
+    padding: 16px;
+    overflow-y: auto;
+    background: #f5f7fa;
+    border: 1px solid #e4e7ed;
+    border-radius: 4px;
+    :deep(.el-tree) {
+      background: transparent;
+      .el-tree-node {
+        .el-tree-node__content {
+          height: 40px;
+          padding: 0 12px;
+          margin-bottom: 2px;
+          border-radius: 4px;
+          transition: background-color 0.2s;
+          &:hover {
+            background-color: #ecf5ff;
+          }
+          .tree-node-label {
+            display: flex;
+            flex: 1;
+            align-items: center;
+            font-size: 14px;
+            color: var(--el-text-color-primary);
+          }
+        }
+        .el-checkbox {
+          margin-right: 8px;
+        }
+        .el-tree-node__children {
+          padding-left: 20px;
+        }
+      }
+      .el-tree-node__expand-icon {
+        margin-right: 6px;
         font-size: 14px;
-        color: var(--el-text-color-secondary);
+        color: #909399;
+        transform: translateX(-5px);
+      }
+      .el-tree-node__expand-icon.is-leaf {
+        display: none;
       }
     }
   }