WholeProcessPlatform/frontend/src/store/modules/permission.ts
2026-09-02 16:19:28 +08:00

91 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { RouteRecordRaw } from 'vue-router';
import { defineStore } from 'pinia';
import { constantRoutes } from '@/router';
import { store } from '@/store';
import { listRoutes } from '@/api/menu';
import { ref } from 'vue';
const modules = import.meta.glob('../../views/**/**.vue');
export const Layout = () => import('@/layout/index.vue');
// 路由生成后后台预取所有页面 chunk首次导航若依赖懒加载 chunk 下载,
// 会被首页地图加载的十几个接口挤占连接导致页面迟迟不切换,预取后切页即时生效。
let viewPrefetchStarted = false;
const prefetchViewChunks = () => {
if (viewPrefetchStarted) return;
viewPrefetchStarted = true;
Object.values(modules).forEach(load => {
load().catch(() => {});
});
};
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
const res: RouteRecordRaw[] = [];
routes.forEach(route => {
const tmp = { ...route } as any;
// ✅ 保存原始名称到 meta用于菜单显示
tmp.meta = {
...tmp.meta,
title: tmp.name || tmp.menuName, // 原始名称用于显示
moduleId: tmp.id // 保存菜单ID供地图模块使用
};
// ✅ name 使用路径生成唯一值
tmp.name = tmp.path || tmp.opturl;
// if (hasPermission(roles, tmp)) {
tmp.path = tmp.opturl;
if (tmp.type == '0') {
tmp.component = Layout;
} else {
const component = modules[`../../views${tmp.opturl}.vue`] as any;
if (component) {
tmp.component = component;
} else {
tmp.component = modules[`../../views/error-page/404.vue`];
}
}
res.push(tmp);
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles);
}
// }
});
return res;
};
// setup
export const usePermissionStore = defineStore('permission', () => {
// state
const routes = ref<RouteRecordRaw[]>([]);
const addRoutes = ref<RouteRecordRaw[]>([]);
// actions
function setRoutes(newRoutes: RouteRecordRaw[]) {
addRoutes.value = newRoutes;
routes.value = constantRoutes.concat(newRoutes);
}
function generateRoutes(roles: string[]) {
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
listRoutes()
.then(response => {
const asyncRoutes: any = response;
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
setRoutes(accessedRoutes);
// 后台预取页面 chunk不等结果不阻塞导航
prefetchViewChunks();
resolve(accessedRoutes);
})
.catch(error => {
reject(error);
});
});
}
return { routes, setRoutes, generateRoutes };
});
// 非setup
export function usePermissionStoreHook() {
return usePermissionStore(store);
}