Blame view

src/store/modules/permission.ts 4.57 KB
陈文彬 authored
1
2
import type { AppRouteRecordRaw, Menu } from '/@/router/types';
Vben authored
3
4
5
6
7
import { defineStore } from 'pinia';
import { store } from '/@/store';
import { useI18n } from '/@/hooks/web/useI18n';
import { useUserStore } from './user';
import { useAppStoreWidthOut } from './app';
8
import { toRaw } from 'vue';
Vben authored
9
10
import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper';
import { transformRouteToMenu } from '/@/router/helper/menuHelper';
陈文彬 authored
11
Vben authored
12
import projectSetting from '/@/settings/projectSetting';
13
陈文彬 authored
14
15
import { PermissionModeEnum } from '/@/enums/appEnum';
vben authored
16
import { asyncRoutes } from '/@/router/routes';
17
18
import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
陈文彬 authored
19
import { filter } from '/@/utils/helper/treeHelper';
20
21
22
import { getMenuList } from '/@/api/sys/menu';
import { getPermCode } from '/@/api/sys/user';
陈文彬 authored
23
24

import { useMessage } from '/@/hooks/web/useMessage';
vben authored
25
Vben authored
26
interface PermissionState {
vben authored
27
  // Permission code list
Vben authored
28
  permCodeList: string[];
陈文彬 authored
29
  // Whether the route has been dynamically added
Vben authored
30
  isDynamicAddedRoute: boolean;
vben authored
31
  // To trigger a menu update
Vben authored
32
  lastBuildMenuTime: number;
vben authored
33
  // Backstage menu list
Vben authored
34
35
36
37
38
39
40
41
42
43
44
45
46
47
  backMenuList: Menu[];
}
export const usePermissionStore = defineStore({
  id: 'app-permission',
  state: (): PermissionState => ({
    permCodeList: [],
    // Whether the route has been dynamically added
    isDynamicAddedRoute: false,
    // To trigger a menu update
    lastBuildMenuTime: 0,
    // Backstage menu list
    backMenuList: [],
  }),
  getters: {
vben authored
48
    getPermCodeList() {
Vben authored
49
50
      return this.permCodeList;
    },
vben authored
51
    getBackMenuList() {
Vben authored
52
53
      return this.backMenuList;
    },
vben authored
54
    getLastBuildMenuTime() {
Vben authored
55
56
      return this.lastBuildMenuTime;
    },
vben authored
57
    getIsDynamicAddedRoute() {
Vben authored
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
      return this.isDynamicAddedRoute;
    },
  },
  actions: {
    setPermCodeList(codeList: string[]) {
      this.permCodeList = codeList;
    },

    setBackMenuList(list: Menu[]) {
      this.backMenuList = list;
    },

    setLastBuildMenuTime() {
      this.lastBuildMenuTime = new Date().getTime();
    },

    setDynamicAddedRoute(added: boolean) {
      this.isDynamicAddedRoute = added;
    },
    resetState(): void {
      this.isDynamicAddedRoute = false;
      this.permCodeList = [];
      this.backMenuList = [];
      this.lastBuildMenuTime = 0;
    },
83
84
    async changePermissionCode() {
      const codeList = await getPermCode();
Vben authored
85
86
      this.setPermCodeList(codeList);
    },
87
    async buildRoutesAction(): Promise<AppRouteRecordRaw[]> {
Vben authored
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
      const { t } = useI18n();
      const userStore = useUserStore();
      const appStore = useAppStoreWidthOut();

      let routes: AppRouteRecordRaw[] = [];
      const roleList = toRaw(userStore.getRoleList);
      const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig;
      // role permissions
      if (permissionMode === PermissionModeEnum.ROLE) {
        const routeFilter = (route: AppRouteRecordRaw) => {
          const { meta } = route;
          const { roles } = meta || {};
          if (!roles) return true;
          return roleList.some((role) => roles.includes(role));
        };
        routes = filter(asyncRoutes, routeFilter);
        routes = routes.filter(routeFilter);
        // Convert multi-level routing to level 2 routing
        routes = flatMultiLevelRoutes(routes);
        //  If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below
      } else if (permissionMode === PermissionModeEnum.BACK) {
        const { createMessage } = useMessage();

        createMessage.loading({
          content: t('sys.app.menuLoading'),
          duration: 1,
        });

        // !Simulate to obtain permission codes from the background,
        // this function may only need to be executed once, and the actual project can be put at the right time by itself
118
        let routeList: AppRouteRecordRaw[] = [];
Vben authored
119
        try {
120
121
          this.changePermissionCode();
          routeList = (await getMenuList()) as AppRouteRecordRaw[];
122
123
124
        } catch (error) {
          console.error(error);
        }
Vben authored
125
126
127
128
129
130
131
132
133
134

        // Dynamically introduce components
        routeList = transformObjToRoute(routeList);

        //  Background routing to menu structure
        const backMenuList = transformRouteToMenu(routeList);
        this.setBackMenuList(backMenuList);

        routeList = flatMultiLevelRoutes(routeList);
        routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
陈文彬 authored
135
      }
Vben authored
136
137
138
139
140
141
142
143
144
      routes.push(ERROR_LOG_ROUTE);
      return routes;
    },
  },
});

// Need to be used outside the setup
export function usePermissionStoreWidthOut() {
  return usePermissionStore(store);
陈文彬 authored
145
}