feat(platform): load authorized menus from backend
This commit is contained in:
@@ -11,6 +11,6 @@
|
||||
"menuWidth": 220,
|
||||
"device": "desktop",
|
||||
"tabBar": false,
|
||||
"menuFromServer": false,
|
||||
"menuFromServer": true,
|
||||
"serverMenu": []
|
||||
}
|
||||
|
||||
@@ -1,10 +1,63 @@
|
||||
import { Notification } from '@arco-design/web-vue';
|
||||
import type { NotificationReturn } from '@arco-design/web-vue/es/notification/interface';
|
||||
import { defineStore } from 'pinia';
|
||||
import type { RouteRecordNormalized } from 'vue-router';
|
||||
import type { RouteRecordNormalized, RouteRecordRaw } from 'vue-router';
|
||||
import { platformApi, type PlatformMenu } from '@/api/platform';
|
||||
import defaultSettings from '@/config/settings.json';
|
||||
import appClientMenus from '@/router/app-menus';
|
||||
import type { AppState } from './types';
|
||||
|
||||
function indexClientMenus(
|
||||
routes: RouteRecordRaw[],
|
||||
index = new Map<string, RouteRecordRaw>(),
|
||||
) {
|
||||
for (const route of routes) {
|
||||
const menuCode = route.meta?.menuCode;
|
||||
if (menuCode && route.meta?.hideInMenu !== true && !index.has(menuCode)) {
|
||||
index.set(menuCode, route);
|
||||
}
|
||||
if (route.children) indexClientMenus(route.children, index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
function buildServerMenuTree(menus: PlatformMenu[]): RouteRecordRaw[] {
|
||||
const clientMenus = indexClientMenus(
|
||||
appClientMenus as unknown as RouteRecordRaw[],
|
||||
);
|
||||
const nodes = new Map<string, RouteRecordRaw>();
|
||||
|
||||
for (const menu of [...menus].sort((a, b) => a.sort_no - b.sort_no)) {
|
||||
const clientRoute = clientMenus.get(menu.identity);
|
||||
if (!clientRoute) continue;
|
||||
nodes.set(menu.identity, {
|
||||
...clientRoute,
|
||||
path: menu.path,
|
||||
meta: {
|
||||
...clientRoute.meta,
|
||||
title: menu.name,
|
||||
icon: menu.icon || clientRoute.meta?.icon,
|
||||
order: menu.sort_no,
|
||||
menuCode: menu.identity,
|
||||
requiresAuth: clientRoute.meta?.requiresAuth ?? true,
|
||||
},
|
||||
children: [],
|
||||
});
|
||||
}
|
||||
|
||||
const roots: RouteRecordRaw[] = [];
|
||||
for (const menu of menus) {
|
||||
const node = nodes.get(menu.identity);
|
||||
if (!node) continue;
|
||||
if (menu.parent_identity) {
|
||||
const parent = nodes.get(menu.parent_identity);
|
||||
if (parent) parent.children?.push(node);
|
||||
} else {
|
||||
roots.push(node);
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
const useAppStore = defineStore('app', {
|
||||
state: (): AppState => ({ ...defaultSettings }),
|
||||
|
||||
@@ -44,21 +97,23 @@ const useAppStore = defineStore('app', {
|
||||
this.hideMenu = value;
|
||||
},
|
||||
async fetchServerMenuConfig() {
|
||||
let notifyInstance: NotificationReturn | null = null;
|
||||
try {
|
||||
notifyInstance = Notification.info({
|
||||
Notification.info({
|
||||
id: 'menuNotice', // Keep the instance id the same
|
||||
content: 'loading',
|
||||
closable: true,
|
||||
});
|
||||
this.serverMenu = [];
|
||||
notifyInstance = Notification.success({
|
||||
const response = await platformApi.listMenu();
|
||||
this.serverMenu = buildServerMenuTree(
|
||||
response.list,
|
||||
) as unknown as RouteRecordNormalized[];
|
||||
Notification.success({
|
||||
id: 'menuNotice',
|
||||
content: 'success',
|
||||
closable: true,
|
||||
});
|
||||
} catch {
|
||||
notifyInstance = Notification.error({
|
||||
Notification.error({
|
||||
id: 'menuNotice',
|
||||
content: 'error',
|
||||
closable: true,
|
||||
|
||||
@@ -56,6 +56,7 @@ const useUserStore = defineStore('user', {
|
||||
// Get user's information
|
||||
async info() {
|
||||
const profile = await authApi.profile();
|
||||
const appStore = useAppStore();
|
||||
this.setInfo({
|
||||
name: profile.display_name || profile.username,
|
||||
avatar: profile.avatar,
|
||||
@@ -63,6 +64,9 @@ const useUserStore = defineStore('user', {
|
||||
role: profile.role_code,
|
||||
menuCodes: profile.menu_codes,
|
||||
});
|
||||
if (appStore.menuFromServer) {
|
||||
await appStore.fetchServerMenuConfig();
|
||||
}
|
||||
},
|
||||
|
||||
// Login
|
||||
|
||||
Reference in New Issue
Block a user