From 6b988bd582bfcd17fee48c476a5a6e5cc172b0d5 Mon Sep 17 00:00:00 2001
From: baoshiwei <baoshiwei@shlanbao.cn>
Date: 星期三, 12 三月 2025 10:08:33 +0800
Subject: [PATCH] dev-2

---
 src/store/modules/permission.ts |  317 ++++++++++++++++++++++++++++++++--------------------
 1 files changed, 197 insertions(+), 120 deletions(-)

diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts
index 271518e..43fcef8 100644
--- a/src/store/modules/permission.ts
+++ b/src/store/modules/permission.ts
@@ -2,143 +2,220 @@
 import router, { constantRoutes, dynamicRoutes } from '@/router';
 import store from '@/store';
 import { getRouters } from '@/api/menu';
+import auth from '@/plugins/auth';
+import { RouteRecordRaw } from 'vue-router';
+
 import Layout from '@/layout/index.vue';
 import ParentView from '@/components/ParentView/index.vue';
 import InnerLink from '@/layout/components/InnerLink/index.vue';
-import auth from '@/plugins/auth';
-import { RouteOption } from 'vue-router';
+
+import { createCustomNameComponent } from '@/utils/createCustomNameComponent';
+
 // 鍖归厤views閲岄潰鎵�鏈夌殑.vue鏂囦欢
 const modules = import.meta.glob('./../../views/**/*.vue');
-
 export const usePermissionStore = defineStore('permission', () => {
-	const routes = ref<RouteOption[]>([]);
-	const addRoutes = ref<RouteOption[]>([]);
-	const defaultRoutes = ref<RouteOption[]>([]);
-	const topbarRouters = ref<RouteOption[]>([]);
-	const sidebarRouters = ref<RouteOption[]>([]);
+  const routes = ref<RouteRecordRaw[]>([]);
+  const addRoutes = ref<RouteRecordRaw[]>([]);
+  const defaultRoutes = ref<RouteRecordRaw[]>([]);
+  const topbarRouters = ref<RouteRecordRaw[]>([]);
+  const sidebarRouters = ref<RouteRecordRaw[]>([]);
 
-	const setRoutes = (newRoutes: RouteOption[]): void => {
-		addRoutes.value = newRoutes;
-		routes.value = constantRoutes.concat(newRoutes);
-	};
-	const setDefaultRoutes = (routes: RouteOption[]): void => {
-		defaultRoutes.value = constantRoutes.concat(routes);
-	};
-	const setTopbarRoutes = (routes: RouteOption[]): void => {
-		topbarRouters.value = routes;
-	};
-	const setSidebarRouters = (routes: RouteOption[]): void => {
-		sidebarRouters.value = routes;
-	};
-	const generateRoutes = async (): Promise<RouteOption[]> => {
-		const res = await getRouters();
-		const { data } = res;
-		const sdata = JSON.parse(JSON.stringify(data));
-		const rdata = JSON.parse(JSON.stringify(data));
-		const defaultData = JSON.parse(JSON.stringify(data));
-		const sidebarRoutes = filterAsyncRouter(sdata);
-		const rewriteRoutes = filterAsyncRouter(rdata, undefined, true);
-		const defaultRoutes = filterAsyncRouter(defaultData);
-		const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
-		asyncRoutes.forEach((route) => {
-			router.addRoute(route);
-		});
-		setRoutes(rewriteRoutes);
-		setSidebarRouters(constantRoutes.concat(sidebarRoutes));
-		setDefaultRoutes(sidebarRoutes);
-		setTopbarRoutes(defaultRoutes);
-		return new Promise<RouteOption[]>((resolve) => resolve(rewriteRoutes));
-	};
+  const getRoutes = (): RouteRecordRaw[] => {
+    return routes.value as RouteRecordRaw[];
+  };
+  const getSidebarRoutes = (): RouteRecordRaw[] => {
+    return sidebarRouters.value as RouteRecordRaw[];
+  };
+  const getTopbarRoutes = (): RouteRecordRaw[] => {
+    return topbarRouters.value as RouteRecordRaw[];
+  };
 
-	/**
-	 * 閬嶅巻鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆锛岃浆鎹负缁勪欢瀵硅薄
-	 * @param asyncRouterMap 鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆
-	 * @param lastRouter 涓婁竴绾ц矾鐢�
-	 * @param type 鏄惁鏄噸鍐欒矾鐢�
-	 */
-	const filterAsyncRouter = (asyncRouterMap: RouteOption[], lastRouter?: RouteOption, type = false): RouteOption[] => {
-		return asyncRouterMap.filter((route) => {
-			if (type && route.children) {
-				route.children = filterChildren(route.children, undefined);
-			}
-			if (route.component) {
-				// Layout ParentView 缁勪欢鐗规畩澶勭悊
-				if (route.component === 'Layout') {
-					route.component = Layout;
-				} else if (route.component === 'ParentView') {
-					route.component = ParentView;
-				} else if (route.component === 'InnerLink') {
-					route.component = InnerLink;
-				} else {
-					route.component = loadView(route.component);
-				}
-			}
-			if (route.children != null && route.children && route.children.length) {
-				route.children = filterAsyncRouter(route.children, route, type);
-			} else {
-				delete route.children;
-				delete route.redirect;
-			}
-			return true;
-		});
-	};
-	const filterChildren = (childrenMap: RouteOption[], lastRouter?: RouteOption): RouteOption[] => {
-		let children: RouteOption[] = [];
-		childrenMap.forEach((el) => {
-			if (el.children && el.children.length) {
-				if (el.component === 'ParentView' && !lastRouter) {
-					el.children.forEach((c) => {
-						c.path = el.path + '/' + c.path;
-						if (c.children && c.children.length) {
-							children = children.concat(filterChildren(c.children, c));
-							return;
-						}
-						children.push(c);
-					});
-					return;
-				}
-			}
-			if (lastRouter) {
-				el.path = lastRouter.path + '/' + el.path;
-			}
-			children = children.concat(el);
-		});
-		return children;
-	};
-	return { routes, setRoutes, generateRoutes, setSidebarRouters, topbarRouters, sidebarRouters, defaultRoutes };
+  const setRoutes = (newRoutes: RouteRecordRaw[]): void => {
+    addRoutes.value = newRoutes;
+    routes.value = constantRoutes.concat(newRoutes);
+  };
+  const setDefaultRoutes = (routes: RouteRecordRaw[]): void => {
+    defaultRoutes.value = constantRoutes.concat(routes);
+  };
+  const setTopbarRoutes = (routes: RouteRecordRaw[]): void => {
+    topbarRouters.value = routes;
+  };
+  const setSidebarRouters = (routes: RouteRecordRaw[]): void => {
+    sidebarRouters.value = routes;
+  };
+  const generateRoutes = async (): Promise<RouteRecordRaw[]> => {
+    const res = await getRouters();
+    const { data } = res;
+    const sdata = JSON.parse(JSON.stringify(data));
+    const rdata = JSON.parse(JSON.stringify(data));
+    const defaultData = JSON.parse(JSON.stringify(data));
+    const sidebarRoutes = filterAsyncRouter(sdata);
+    const rewriteRoutes = filterAsyncRouter(rdata, undefined, true);
+    const defaultRoutes = filterAsyncRouter(defaultData);
+    const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
+    asyncRoutes.forEach((route) => {
+      router.addRoute(route);
+    });
+    setRoutes(rewriteRoutes);
+    setSidebarRouters(constantRoutes.concat(sidebarRoutes));
+    setDefaultRoutes(sidebarRoutes);
+    setTopbarRoutes(defaultRoutes);
+    // 璺敱name閲嶅妫�鏌�
+    duplicateRouteChecker(asyncRoutes, sidebarRoutes);
+    return new Promise<RouteRecordRaw[]>((resolve) => resolve(rewriteRoutes));
+  };
+
+  /**
+   * 閬嶅巻鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆锛岃浆鎹负缁勪欢瀵硅薄
+   * @param asyncRouterMap 鍚庡彴浼犳潵鐨勮矾鐢卞瓧绗︿覆
+   * @param lastRouter 涓婁竴绾ц矾鐢�
+   * @param type 鏄惁鏄噸鍐欒矾鐢�
+   */
+  const filterAsyncRouter = (asyncRouterMap: RouteRecordRaw[], lastRouter?: RouteRecordRaw, type = false): RouteRecordRaw[] => {
+    return asyncRouterMap.filter((route) => {
+      if (type && route.children) {
+        route.children = filterChildren(route.children, undefined);
+      }
+      // Layout ParentView 缁勪欢鐗规畩澶勭悊
+      if (route.component?.toString() === 'Layout') {
+        route.component = Layout;
+      } else if (route.component?.toString() === 'ParentView') {
+        route.component = ParentView;
+      } else if (route.component?.toString() === 'InnerLink') {
+        route.component = InnerLink;
+      } else {
+        route.component = loadView(route.component, route.name as string);
+      }
+      if (route.children != null && route.children && route.children.length) {
+        route.children = filterAsyncRouter(route.children, route, type);
+      } else {
+        delete route.children;
+        delete route.redirect;
+      }
+      return true;
+    });
+  };
+  const filterChildren = (childrenMap: RouteRecordRaw[], lastRouter?: RouteRecordRaw): RouteRecordRaw[] => {
+    let children: RouteRecordRaw[] = [];
+    childrenMap.forEach((el) => {
+      if (el.children && el.children.length) {
+        if (el.component?.toString() === 'ParentView' && !lastRouter) {
+          el.children.forEach((c) => {
+            c.path = el.path + '/' + c.path;
+            if (c.children && c.children.length) {
+              children = children.concat(filterChildren(c.children, c));
+              return;
+            }
+            children.push(c);
+          });
+          return;
+        }
+      }
+      if (lastRouter) {
+        el.path = lastRouter.path + '/' + el.path;
+        if (el.children && el.children.length) {
+          children = children.concat(filterChildren(el.children, el));
+          return;
+        }
+      }
+      children = children.concat(el);
+    });
+    return children;
+  };
+  return {
+    routes,
+    topbarRouters,
+    sidebarRouters,
+    defaultRoutes,
+
+    getRoutes,
+    getSidebarRoutes,
+    getTopbarRoutes,
+
+    setRoutes,
+    generateRoutes,
+    setSidebarRouters
+  };
 });
 
 // 鍔ㄦ�佽矾鐢遍亶鍘嗭紝楠岃瘉鏄惁鍏峰鏉冮檺
-export const filterDynamicRoutes = (routes: RouteOption[]) => {
-	const res: RouteOption[] = [];
-	routes.forEach((route) => {
-		if (route.permissions) {
-			if (auth.hasPermiOr(route.permissions)) {
-				res.push(route);
-			}
-		} else if (route.roles) {
-			if (auth.hasRoleOr(route.roles)) {
-				res.push(route);
-			}
-		}
-	});
-	return res;
+export const filterDynamicRoutes = (routes: RouteRecordRaw[]) => {
+  const res: RouteRecordRaw[] = [];
+  routes.forEach((route) => {
+    if (route.permissions) {
+      if (auth.hasPermiOr(route.permissions)) {
+        res.push(route);
+      }
+    } else if (route.roles) {
+      if (auth.hasRoleOr(route.roles)) {
+        res.push(route);
+      }
+    }
+  });
+  return res;
 };
 
-export const loadView = (view: any) => {
-	let res;
-	for (const path in modules) {
-		const dir = path.split('views/')[1].split('.vue')[0];
-		if (dir === view) {
-			res = () => modules[path]();
-		}
-	}
-	return res;
+export const loadView = (view: any, name: string) => {
+  let res;
+  for (const path in modules) {
+    const viewsIndex = path.indexOf('/views/');
+    let dir = path.substring(viewsIndex + 7);
+    dir = dir.substring(0, dir.lastIndexOf('.vue'));
+    if (dir === view) {
+      res = createCustomNameComponent(modules[path], { name });
+      return res;
+    }
+  }
+  return res;
 };
 
 // 闈瀞etup
 export const usePermissionStoreHook = () => {
-	return usePermissionStore(store);
+  return usePermissionStore(store);
 };
 
+interface Route {
+  name?: string | symbol;
+  path: string;
+  children?: Route[];
+}
+
+/**
+ * 妫�鏌ヨ矾鐢眓ame鏄惁閲嶅
+ * @param localRoutes 鏈湴璺敱
+ * @param routes 鍔ㄦ�佽矾鐢�
+ */
+function duplicateRouteChecker(localRoutes: Route[], routes: Route[]) {
+  // 灞曞钩
+  function flatRoutes(routes: Route[]) {
+    const res: Route[] = [];
+    routes.forEach((route) => {
+      if (route.children) {
+        res.push(...flatRoutes(route.children));
+      } else {
+        res.push(route);
+      }
+    });
+    return res;
+  }
+
+  const allRoutes = flatRoutes([...localRoutes, ...routes]);
+
+  const nameList: string[] = [];
+  allRoutes.forEach((route) => {
+    const name = route.name.toString();
+    if (name && nameList.includes(name)) {
+      const message = `璺敱鍚嶇О: [${name}] 閲嶅, 浼氶�犳垚 404`;
+      console.error(message);
+      ElNotification({
+        title: '璺敱鍚嶇О閲嶅',
+        message,
+        type: 'error'
+      });
+      return;
+    }
+    nameList.push(route.name.toString());
+  });
+}
+
 export default usePermissionStore;

--
Gitblit v1.9.3