diff --git a/src/store/modules/route/index.ts b/src/store/modules/route/index.ts index 2b5df4b20..ca3bc9f64 100644 --- a/src/store/modules/route/index.ts +++ b/src/store/modules/route/index.ts @@ -6,12 +6,13 @@ import { getCacheRoutes, getConstantRouteNames, getUserInfo, + transformAuthRouteToVueRoutes, + transformAuthRouteToVueRoute, transformAuthRouteToMenu, transformAuthRouteToSearchMenus, transformRouteNameToRoutePath, transformRoutePathToRouteName } from '@/utils'; -import { transformAuthRouteToVueRoutes, transformAuthRouteToVueRoute } from '@/utils/router/transform'; import { useAuthStore } from '../auth'; import { useTabStore } from '../tab'; diff --git a/src/utils/router/component.ts b/src/utils/router/component.ts new file mode 100644 index 000000000..dda2f46d3 --- /dev/null +++ b/src/utils/router/component.ts @@ -0,0 +1,54 @@ +import type { RouteComponent } from 'vue-router'; +import { BasicLayout, BlankLayout } from '@/layouts'; +import { views } from '@/views'; +import { isFunction } from '../common'; + +type Lazy = () => Promise; + +interface ModuleComponent { + default: RouteComponent; +} + +type LayoutComponent = Record>; + +/** + * 获取布局的vue文件(懒加载的方式) + * @param layoutType - 布局类型 + */ +export function getLayoutComponent(layoutType: EnumType.LayoutComponentName) { + const layoutComponent: LayoutComponent = { + basic: BasicLayout, + blank: BlankLayout + }; + return layoutComponent[layoutType]; +} + +/** + * 获取页面导入的vue文件 + * @param routeKey - 路由key + */ +export function getViewComponent(routeKey: AuthRoute.LastDegreeRouteKey) { + if (!views[routeKey]) { + throw new Error(`路由“${routeKey}”没有对应的组件文件!`); + } + return setViewComponentName(views[routeKey], routeKey); +} + +/** 给页面组件设置名称 */ +function setViewComponentName(component: RouteComponent | Lazy, name: string) { + if (isAsyncComponent(component)) { + return async () => { + const result = await component(); + Object.assign(result.default, { name }); + return result; + }; + } + + Object.assign(component, { name }); + + return component; +} + +function isAsyncComponent(component: RouteComponent | Lazy): component is Lazy { + return isFunction(component); +} diff --git a/src/utils/router/helpers.ts b/src/utils/router/helpers.ts index 028387454..1e01598db 100644 --- a/src/utils/router/helpers.ts +++ b/src/utils/router/helpers.ts @@ -6,64 +6,14 @@ export function getConstantRouteNames(routes: AuthRoute.Route[]) { return routes.map(route => getConstantRouteName(route)).flat(1); } -/** - * 将权限路由转换成搜索的菜单数据 - * @param routes - 权限路由 - * @param treeMap - */ -export function transformAuthRouteToSearchMenus(routes: AuthRoute.Route[], treeMap: AuthRoute.Route[] = []) { - if (routes && routes.length === 0) return []; - return routes.reduce((acc, cur) => { - if (!cur.meta?.hide) { - acc.push(cur); - } - if (cur.children && cur.children.length > 0) { - transformAuthRouteToSearchMenus(cur.children, treeMap); - } - return acc; - }, treeMap); -} - -/** 将路由名字转换成路由路径 */ -export function transformRouteNameToRoutePath(name: Exclude): AuthRoute.RoutePath { - const rootPath: AuthRoute.RoutePath = '/'; - if (name === 'root') return rootPath; - - const splitMark = '_'; - const pathSplitMark = '/'; - const path = name.split(splitMark).join(pathSplitMark); - - return (pathSplitMark + path) as AuthRoute.RoutePath; -} - -/** 将路由路径转换成路由名字 */ -export function transformRoutePathToRouteName(path: K) { - if (path === '/') return 'root'; - - const pathSplitMark = '/'; - const routeSplitMark = '_'; - - const name = path.split(pathSplitMark).slice(1).join(routeSplitMark) as AuthRoute.AllRouteKey; - - return name; -} - /** * 获取所有固定路由的名称集合 * @param route - 固定路由 */ function getConstantRouteName(route: AuthRoute.Route) { const names = [route.name]; - if (hasChildren(route)) { + if (route.children?.length) { names.push(...route.children!.map(item => getConstantRouteName(item)).flat(1)); } return names; } - -/** - * 是否有子路由 - * @param item - 权限路由 - */ -function hasChildren(item: AuthRoute.Route) { - return Boolean(item.children && item.children.length); -} diff --git a/src/utils/router/index.ts b/src/utils/router/index.ts index f74f45384..e97e7ebe2 100644 --- a/src/utils/router/index.ts +++ b/src/utils/router/index.ts @@ -5,3 +5,4 @@ export * from './auth'; export * from './menu'; export * from './breadcrumb'; export * from './regexp'; +export * from './transform'; diff --git a/src/utils/router/menu.ts b/src/utils/router/menu.ts index 0f5b03139..05d0fbf32 100644 --- a/src/utils/router/menu.ts +++ b/src/utils/router/menu.ts @@ -1,37 +1,5 @@ import { useIconRender } from '@/composables'; -/** 路由不转换菜单 */ -function hideInMenu(route: AuthRoute.Route) { - return Boolean(route.meta.hide); -} - -/** 给菜单添加可选属性 */ -function addPartialProps(config: { - menu: App.GlobalMenuOption; - icon?: string; - localIcon?: string; - children?: App.GlobalMenuOption[]; -}) { - const { iconRender } = useIconRender(); - - const item = { ...config.menu }; - - const { icon, localIcon, children } = config; - - if (localIcon) { - Object.assign(item, { icon: iconRender({ localIcon }) }); - } - - if (icon) { - Object.assign(item, { icon: iconRender({ icon }) }); - } - - if (children) { - Object.assign(item, { children }); - } - return item; -} - /** * 将权限路由转换成菜单 * @param routes - 路由 @@ -85,3 +53,35 @@ function getActiveKeyPathsOfMenu(activeKey: string, menu: App.GlobalMenuOption) } return keys; } + +/** 路由不转换菜单 */ +function hideInMenu(route: AuthRoute.Route) { + return Boolean(route.meta.hide); +} + +/** 给菜单添加可选属性 */ +function addPartialProps(config: { + menu: App.GlobalMenuOption; + icon?: string; + localIcon?: string; + children?: App.GlobalMenuOption[]; +}) { + const { iconRender } = useIconRender(); + + const item = { ...config.menu }; + + const { icon, localIcon, children } = config; + + if (localIcon) { + Object.assign(item, { icon: iconRender({ localIcon }) }); + } + + if (icon) { + Object.assign(item, { icon: iconRender({ icon }) }); + } + + if (children) { + Object.assign(item, { children }); + } + return item; +} diff --git a/src/utils/router/transform.ts b/src/utils/router/transform.ts index f2d4addc4..843359ca1 100644 --- a/src/utils/router/transform.ts +++ b/src/utils/router/transform.ts @@ -1,97 +1,5 @@ -import type { RouteComponent, RouteRecordRaw } from 'vue-router'; -import { BasicLayout, BlankLayout } from '@/layouts'; -import { views } from '@/views'; -import { isFunction } from '@/utils'; - -type Lazy = () => Promise; - -type LayoutComponent = Record>; - -/** - * 获取布局的vue文件(懒加载的方式) - * @param layoutType - 布局类型 - */ -export function getLayoutComponent(layoutType: EnumType.LayoutComponentName) { - const layoutComponent: LayoutComponent = { - basic: BasicLayout, - blank: BlankLayout - }; - return layoutComponent[layoutType]; -} - -/** - * 获取页面导入的vue文件 - * @param routeKey - 路由key - */ -export function getViewComponent(routeKey: AuthRoute.LastDegreeRouteKey) { - if (!views[routeKey]) { - throw new Error(`路由“${routeKey}”没有对应的组件文件!`); - } - return setViewComponentName(views[routeKey], routeKey); -} - -interface ModuleComponent { - default: RouteComponent; -} - -/** 给页面组件设置名称 */ -function setViewComponentName(component: RouteComponent | Lazy, name: string) { - if (isAsyncComponent(component)) { - return async () => { - const result = await component(); - Object.assign(result.default, { name }); - return result; - }; - } - - Object.assign(component, { name }); - - return component; -} - -function isAsyncComponent(component: RouteComponent | Lazy): component is Lazy { - return isFunction(component); -} - -/** - * 是否有外链 - * @param item - 权限路由 - */ -function hasHref(item: AuthRoute.Route) { - return Boolean(item.meta.href); -} - -/** - * 是否有动态路由path - * @param item - 权限路由 - */ -function hasDynamicPath(item: AuthRoute.Route) { - return Boolean(item.meta.dynamicPath); -} - -/** - * 是否有路由组件 - * @param item - 权限路由 - */ -function hasComponent(item: AuthRoute.Route) { - return Boolean(item.component); -} - -/** - * 是否有子路由 - * @param item - 权限路由 - */ -function hasChildren(item: AuthRoute.Route) { - return Boolean(item.children && item.children.length); -} - -/** - * 是否是单层级路由 - * @param item - 权限路由 - */ -function isSingleRoute(item: AuthRoute.Route) { - return Boolean(item.meta.singleLayout); -} +import type { RouteRecordRaw } from 'vue-router'; +import { getLayoutComponent, getViewComponent } from './component'; /** * 将权限路由转换成vue路由 @@ -212,3 +120,85 @@ export function transformAuthRouteToVueRoute(item: AuthRoute.Route) { return resultRoute; } + +/** + * 将权限路由转换成搜索的菜单数据 + * @param routes - 权限路由 + * @param treeMap + */ +export function transformAuthRouteToSearchMenus(routes: AuthRoute.Route[], treeMap: AuthRoute.Route[] = []) { + if (routes && routes.length === 0) return []; + return routes.reduce((acc, cur) => { + if (!cur.meta?.hide) { + acc.push(cur); + } + if (cur.children && cur.children.length > 0) { + transformAuthRouteToSearchMenus(cur.children, treeMap); + } + return acc; + }, treeMap); +} + +/** 将路由名字转换成路由路径 */ +export function transformRouteNameToRoutePath(name: Exclude): AuthRoute.RoutePath { + const rootPath: AuthRoute.RoutePath = '/'; + if (name === 'root') return rootPath; + + const splitMark = '_'; + const pathSplitMark = '/'; + const path = name.split(splitMark).join(pathSplitMark); + + return (pathSplitMark + path) as AuthRoute.RoutePath; +} + +/** 将路由路径转换成路由名字 */ +export function transformRoutePathToRouteName(path: K) { + if (path === '/') return 'root'; + + const pathSplitMark = '/'; + const routeSplitMark = '_'; + + const name = path.split(pathSplitMark).slice(1).join(routeSplitMark) as AuthRoute.AllRouteKey; + + return name; +} + +/** + * 是否有外链 + * @param item - 权限路由 + */ +function hasHref(item: AuthRoute.Route) { + return Boolean(item.meta.href); +} + +/** + * 是否有动态路由path + * @param item - 权限路由 + */ +function hasDynamicPath(item: AuthRoute.Route) { + return Boolean(item.meta.dynamicPath); +} + +/** + * 是否有路由组件 + * @param item - 权限路由 + */ +function hasComponent(item: AuthRoute.Route) { + return Boolean(item.component); +} + +/** + * 是否有子路由 + * @param item - 权限路由 + */ +function hasChildren(item: AuthRoute.Route) { + return Boolean(item.children && item.children.length); +} + +/** + * 是否是单层级路由 + * @param item - 权限路由 + */ +function isSingleRoute(item: AuthRoute.Route) { + return Boolean(item.meta.singleLayout); +} diff --git a/vite.config.ts b/vite.config.ts index 42995f1c7..6c14493e1 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -16,7 +16,8 @@ export default defineConfig(configEnv => { resolve: { alias: { '~': rootPath, - '@': srcPath + '@': srcPath, + 'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js' } }, define: viteDefine,