WholeProcessPlatform/frontend/src/store/modules/permission.ts

91 lines
2.7 KiB
TypeScript
Raw Normal View History

2026-03-25 10:02:19 +08:00
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(() => {});
});
};
2026-03-25 10:02:19 +08:00
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
const res: RouteRecordRaw[] = [];
routes.forEach(route => {
const tmp = { ...route } as any;
2026-03-27 14:50:35 +08:00
// ✅ 保存原始名称到 meta用于菜单显示
tmp.meta = {
...tmp.meta,
2026-07-03 15:59:05 +08:00
title: tmp.name || tmp.menuName, // 原始名称用于显示
moduleId: tmp.id // 保存菜单ID供地图模块使用
2026-03-27 14:50:35 +08:00
};
// ✅ name 使用路径生成唯一值
tmp.name = tmp.path || tmp.opturl;
2026-03-25 10:02:19 +08:00
// 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;
2026-03-25 10:02:19 +08:00
} else {
tmp.component = modules[`../../views/error-page/404.vue`];
2026-03-25 10:02:19 +08:00
}
}
res.push(tmp);
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles);
}
2026-03-25 10:02:19 +08:00
// }
});
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);
}
2026-03-25 10:02:19 +08:00
function generateRoutes(roles: string[]) {
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
listRoutes()
.then(response => {
const asyncRoutes: any = response;
2026-03-25 10:02:19 +08:00
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
setRoutes(accessedRoutes);
// 后台预取页面 chunk不等结果不阻塞导航
prefetchViewChunks();
2026-03-25 10:02:19 +08:00
resolve(accessedRoutes);
})
.catch(error => {
reject(error);
});
});
}
return { routes, setRoutes, generateRoutes };
});
// 非setup
export function usePermissionStoreHook() {
return usePermissionStore(store);
}