94 lines
2.6 KiB
TypeScript
94 lines
2.6 KiB
TypeScript
import { RouteRecordRaw } from "vue-router";
|
||
import { constantRoutes } from "@/router";
|
||
import { store } from "@/store";
|
||
import MenuAPI, { RouteVO } from "@/api/menu";
|
||
|
||
const modules = import.meta.glob("../../views/**/**.vue");
|
||
const Layout = () => import("@/layout/index.vue");
|
||
|
||
export const usePermissionStore = defineStore("permission", () => {
|
||
/**
|
||
* 应用中所有的路由列表,包括静态路由和动态路由
|
||
*/
|
||
const routes = ref<RouteRecordRaw[]>([]);
|
||
/**
|
||
* 混合模式左侧菜单列表
|
||
*/
|
||
const mixLeftMenus = ref<RouteRecordRaw[]>([]);
|
||
|
||
/**
|
||
* 生成动态路由
|
||
*/
|
||
function generateRoutes() {
|
||
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
|
||
MenuAPI.getRoutes()
|
||
.then((data) => {
|
||
const dynamicRoutes = transformRoutes(data);
|
||
routes.value = constantRoutes.concat(dynamicRoutes);
|
||
resolve(dynamicRoutes);
|
||
})
|
||
.catch((error) => {
|
||
reject(error);
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 混合模式菜单下根据顶部菜单路径设置左侧菜单
|
||
*
|
||
* @param topMenuPath - 顶部菜单路径
|
||
*/
|
||
const setMixLeftMenus = (topMenuPath: string) => {
|
||
const matchedItem = routes.value.find((item) => item.path === topMenuPath);
|
||
if (matchedItem && matchedItem.children) {
|
||
mixLeftMenus.value = matchedItem.children;
|
||
}
|
||
};
|
||
|
||
return {
|
||
routes,
|
||
generateRoutes,
|
||
mixLeftMenus,
|
||
setMixLeftMenus,
|
||
};
|
||
});
|
||
|
||
/**
|
||
* 转换路由数据为组件
|
||
*/
|
||
const transformRoutes = (routes: RouteVO[]) => {
|
||
const asyncRoutes: RouteRecordRaw[] = [];
|
||
routes.forEach((route) => {
|
||
const tmpRoute = { ...route } as RouteRecordRaw;
|
||
// 顶级目录,替换为 Layout 组件
|
||
if (tmpRoute.component?.toString() == "Layout") {
|
||
tmpRoute.component = Layout;
|
||
} else {
|
||
// 其他菜单,根据组件路径动态加载组件
|
||
const component = modules[`../../views/${tmpRoute.component}.vue`];
|
||
if (component) {
|
||
tmpRoute.component = component;
|
||
} else {
|
||
tmpRoute.component = modules[`../../views/error-page/404.vue`];
|
||
}
|
||
}
|
||
|
||
if (tmpRoute.children) {
|
||
tmpRoute.children = transformRoutes(route.children);
|
||
}
|
||
|
||
asyncRoutes.push(tmpRoute);
|
||
});
|
||
|
||
return asyncRoutes;
|
||
};
|
||
|
||
/**
|
||
* 用于在组件外部(如在Pinia Store 中)使用 Pinia 提供的 store 实例。
|
||
* 官方文档解释了如何在组件外部使用 Pinia Store:
|
||
* https://pinia.vuejs.org/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component
|
||
*/
|
||
export function usePermissionStoreHook() {
|
||
return usePermissionStore(store);
|
||
}
|