Files
vue3-element-admin/src/store/modules/permission-store.ts
Ray.Hao 23b52872c5 refactor: 重命名 API 文件并更新引用路径
- 重命名 13 个 API 文件,去掉 -api 后缀
  * src/api/auth-api.ts  auth.ts
  * src/api/codegen-api.ts  codegen.ts
  * src/api/file-api.ts  file.ts
  * src/api/system/*.ts (9个文件)

- 批量更新 50+ 处 API 引用路径
- 修复 websocket 和枚举导入路径
- 确保零编码问题(使用 UTF-8 编码)
2025-12-12 14:02:07 +08:00

105 lines
3.2 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 type { RouteRecordRaw } from "vue-router";
import { constantRoutes } from "@/router";
import { store } from "@/store";
import router from "@/router";
import MenuAPI, { type RouteVO } from "@/api/system/menu";
const modules = import.meta.glob("../../views/**/**.vue");
const Layout = () => import("../../layouts/index.vue");
export const usePermissionStore = defineStore("permission", () => {
// 所有路由(静态路由 + 动态路由)
const routes = ref<RouteRecordRaw[]>([]);
// 混合布局的左侧菜单路由
const mixLayoutSideMenus = ref<RouteRecordRaw[]>([]);
// 动态路由是否已生成
const isRouteGenerated = ref(false);
/** 生成动态路由 */
async function generateRoutes(): Promise<RouteRecordRaw[]> {
try {
const data = await MenuAPI.getRoutes(); // 获取当前登录人的菜单路由
const dynamicRoutes = transformRoutes(data);
routes.value = [...constantRoutes, ...dynamicRoutes];
isRouteGenerated.value = true;
return dynamicRoutes;
} catch (error) {
// 路由生成失败,重置状态
isRouteGenerated.value = false;
throw error;
}
}
/** 设置混合布局左侧菜单 */
const setMixLayoutSideMenus = (parentPath: string) => {
const parentMenu = routes.value.find((item) => item.path === parentPath);
mixLayoutSideMenus.value = parentMenu?.children || [];
};
/** 重置路由状态 */
const resetRouter = () => {
// 移除动态添加的路由
const constantRouteNames = new Set(constantRoutes.map((route) => route.name).filter(Boolean));
routes.value.forEach((route) => {
if (route.name && !constantRouteNames.has(route.name)) {
router.removeRoute(route.name);
}
});
// 重置所有状态
routes.value = [...constantRoutes];
mixLayoutSideMenus.value = [];
isRouteGenerated.value = false;
};
return {
routes,
mixLayoutSideMenus,
isRouteGenerated,
generateRoutes,
setMixLayoutSideMenus,
resetRouter,
};
});
/**
* 转换后端路由数据为Vue Router配置
* 处理组件路径映射和Layout层级嵌套
*/
const transformRoutes = (routes: RouteVO[], isTopLevel: boolean = true): RouteRecordRaw[] => {
return routes.map((route) => {
const { component, children, ...args } = route;
// 处理组件顶层或非Layout保留组件中间层Layout设为undefined
const processedComponent = isTopLevel || component !== "Layout" ? component : undefined;
const normalizedRoute = { ...args } as RouteRecordRaw;
if (!processedComponent) {
// 多级菜单的父级菜单,不需要组件
normalizedRoute.component = undefined;
} else {
// 动态导入组件Layout特殊处理找不到组件时返回404
normalizedRoute.component =
processedComponent === "Layout"
? Layout
: modules[`../../views/${processedComponent}.vue`] ||
modules[`../../views/error/404.vue`];
}
// 递归处理子路由
if (children && children.length > 0) {
normalizedRoute.children = transformRoutes(children, false);
}
return normalizedRoute;
});
};
/** 非组件环境使用权限store */
export function usePermissionStoreHook() {
return usePermissionStore(store);
}