Quellcode durchsuchen

perf(views): 优化登陆后导航菜单与操作按钮权限逻辑

wangshun vor 3 Tagen
Ursprung
Commit
00e7f9d64b

+ 10 - 0
src/api/index.ts

@@ -207,6 +207,16 @@ export const getPermissionCheckTree = async (roleId: number) => {
   return data;
 };
 
+export const getCurrentUser = async () => {
+  const data = await request<TreeStructure[]>(apiSys('/sysPermission/currentUser'));
+  return data;
+};
+
+export const getPermIdsByCurrentUser = async () => {
+  const data = await request<number[]>(apiSys('/sysPermission/PermIdsByCurrentUser'));
+  return data;
+};
+
 // 角色和菜单关联表
 export const addGrantRolePermissions = async (params: RolePermissionsParams) => {
   await request(apiSys('/sysRolePermission/grantRolePermissions'), {

+ 33 - 3
src/layout/HvacAside.vue

@@ -14,13 +14,14 @@ import { addRevisePassword, getNoticePageList, getPageList, getUnreadNotificatio
 import { translateNavigation } from '@/utils';
 import { removeToken } from '@/utils/auth';
 
+import type { RouteRecordRaw } from 'vue-router';
 import type { FormInstance, Rule } from 'ant-design-vue/es/form';
 import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
 import type { ChangePasswordForm, DeviceGroupItem, NoticePageItem, PageParams } from '@/types';
 
 const router = useRouter();
 const route = useRoute();
-const { resetToken } = useUserInfoStore();
+const { permission, resetToken } = useUserInfoStore();
 
 const menuRef = useTemplateRef('menu');
 const selectedKeys = ref<string[]>([route.path]);
@@ -44,15 +45,44 @@ const messageTotal = ref<number>();
 const { handleRequest } = useRequest();
 let timer: number | null = null; // 保存定时器ID
 const countNumber = ref<number>();
+
+// 递归过滤函数
+const filterRoutes = (routeList: Readonly<RouteRecordRaw[]>) => {
+  return routeList.filter((route) => {
+    const routeHasPermission =
+      route.meta &&
+      permission
+        ?.split(',')
+        .map(Number)
+        .includes(route.meta.permission as number);
+    let childrenHavePermission = false;
+
+    // 如果有子路由,递归过滤
+    if (routeHasPermission) {
+      if (route.children && route.children.length > 0) {
+        const filteredChildren: RouteRecordRaw[] = filterRoutes(route.children);
+        childrenHavePermission = filteredChildren.length > 0;
+
+        // 更新子路由为过滤后的结果
+        if (childrenHavePermission) {
+          route.children = filteredChildren;
+        }
+      }
+    }
+
+    // 只有当路由自身有权限或子路由有权限才保留
+    return routeHasPermission || childrenHavePermission;
+  });
+};
 const menuGroupList = computed(() => {
   return [
     {
       category: t('common.dataCenter'),
-      routes: dataCenterRoutes,
+      routes: filterRoutes(dataCenterRoutes),
     },
     {
       category: t('common.opsCenter'),
-      routes: opsCenterRoutes,
+      routes: filterRoutes(opsCenterRoutes),
     },
   ];
 });

+ 20 - 0
src/stores/user-info.ts

@@ -3,6 +3,7 @@ import { defineStore } from 'pinia';
 
 export const useUserInfoStore = defineStore('userInfo', () => {
   const token = ref<string>();
+  const permission = ref<string>();
 
   const saveToken = (val: string) => {
     token.value = val;
@@ -12,9 +13,28 @@ export const useUserInfoStore = defineStore('userInfo', () => {
     token.value = undefined;
   };
 
+  const savePermission = (val: number[]) => {
+    permission.value = val.join(',');
+  };
+
+  const resetPermission = () => {
+    permission.value = undefined;
+  };
+
+  const booleanPermission = (val: number) => {
+    if (permission.value) {
+      const data = permission.value.split(',').map(Number);
+      return data.includes(val);
+    }
+  };
+
   return {
     token,
+    permission,
     saveToken,
     resetToken,
+    savePermission,
+    resetPermission,
+    booleanPermission,
   };
 });

+ 13 - 0
src/utils/auth.ts

@@ -1,6 +1,7 @@
 import Cookies from 'js-cookie';
 
 export const TOKEN_KEY = 'X-Token';
+export const PERMISSION_KEY = 'Permission';
 
 export const setToken = (token: string) => {
   Cookies.set(TOKEN_KEY, token);
@@ -13,3 +14,15 @@ export const getToken = () => {
 export const removeToken = () => {
   Cookies.remove(TOKEN_KEY);
 };
+
+export const setPermission = (permission: number[]) => {
+  Cookies.set(PERMISSION_KEY, permission.join(','));
+};
+
+export const getPermission = () => {
+  return Cookies.get(PERMISSION_KEY);
+};
+
+export const removePermission = () => {
+  Cookies.remove(PERMISSION_KEY);
+};

+ 50 - 0
src/utils/permission-type.ts

@@ -0,0 +1,50 @@
+export const enum ViewPermission {
+  大屏 = 101,
+  环境监控 = 102,
+  能耗分析 = 103,
+  数据查询 = 104,
+  事件响应 = 105,
+  用户管理 = 106,
+  组织管理 = 10601,
+  角色管理 = 10602,
+  账号管理 = 10603,
+  算法配置 = 107,
+  协议管理 = 108,
+  设备 = 109,
+  设备管理 = 10901,
+  网关管理 = 10902,
+  日志中心 = 110,
+  智控日志 = 11101,
+  操作日志 = 11102,
+  实时监控 = 111,
+  设备工况 = 112,
+}
+
+export const enum OperatePermission {
+  大屏编辑 = 20101,
+  新增监测点 = 20201,
+  删除监测点 = 20202,
+  编辑检测点 = 20203,
+  编辑平面图 = 20204,
+  新增事件响应 = 20301,
+  删除事件响应 = 20302,
+  编辑事件响应 = 20303,
+  新增组织 = 20401,
+  删除组织 = 20402,
+  编辑组织 = 20403,
+  新增角色 = 20501,
+  删除角色 = 20502,
+  编辑角色 = 20503,
+  新增账户 = 20601,
+  删除账户 = 20602,
+  编辑账户 = 20603,
+  算法配置编辑 = 20701,
+  新增网关 = 20801,
+  删除网关 = 20802,
+  编辑设备 = 20903,
+  新增设备 = 20901,
+  删除设备 = 20902,
+  新增协议 = 21001,
+  删除协议 = 21002,
+  编辑协议 = 21003,
+}

+ 26 - 18
src/views/login-component/LoginView.vue

@@ -6,15 +6,16 @@ import SvgIcon from '@/components/SvgIcon.vue';
 import { useRequest } from '@/hooks/request';
 import { useUserInfoStore } from '@/stores/user-info';
 import { t } from '@/i18n';
-import { getNeedFirstWizard, loginUser } from '@/api';
+import { getNeedFirstWizard, getPermIdsByCurrentUser, loginUser } from '@/api';
 
-import { setToken } from '../../utils/auth';
+import { setPermission, setToken } from '../../utils/auth';
 
-import type { Rule } from 'ant-design-vue/es/form';
+import type { FormInstance, Rule } from 'ant-design-vue/es/form';
 import type { LoginUser } from '@/types';
 
+const formRef = ref<FormInstance>();
 const router = useRouter();
-const { saveToken } = useUserInfoStore();
+const { saveToken, savePermission } = useUserInfoStore();
 const { handleRequest } = useRequest();
 const loginForm = ref<LoginUser>({
   mobile: '',
@@ -38,21 +39,28 @@ const isValidPhone = (phone: string): boolean => {
   return /^1[3-9]\d{9}$/.test(phone);
 };
 const addLog = () => {
-  handleRequest(async () => {
-    const { access_token } = await loginUser({
-      grant_type: 'mobile_password',
-      ...loginForm.value,
-    });
-    if (access_token) {
-      saveToken(access_token);
-      setToken(access_token);
-      const data = await getNeedFirstWizard();
-      if (data) {
-        router.push('/first-usage');
-      } else {
-        router.push('/env-monitor/index');
+  formRef.value?.validate().then(() => {
+    handleRequest(async () => {
+      const { access_token } = await loginUser({
+        grant_type: 'mobile_password',
+        ...loginForm.value,
+      });
+      if (access_token) {
+        saveToken(access_token);
+        setToken(access_token);
+        const data = await getPermIdsByCurrentUser();
+        if (data.length) {
+          setPermission(data);
+          savePermission(data);
+        }
+        const value = await getNeedFirstWizard();
+        if (value) {
+          router.push('/first-usage');
+        } else {
+          router.push('/env-monitor/index');
+        }
       }
-    }
+    });
   });
 };