diff --git a/locales/en_US.json b/locales/en_US.json index de86448..9fc48b6 100644 --- a/locales/en_US.json +++ b/locales/en_US.json @@ -51,7 +51,8 @@ "closeAll": "Close all", "closeLeft": "Close left", "closeRight": "Close right", - "backHome": "Back to the homepage" + "backHome": "Back to the homepage", + "getRouteError": "Failed to obtain route, please try again later." }, "login": { "signInTitle": "Login", @@ -118,7 +119,6 @@ "accountSetting": "User settings" }, "http": { - "defaultTip": "Request error", "400": "Syntax error in the request", "401": "User unauthorized", "403": "Server refused access", @@ -130,7 +130,8 @@ "502": "Bad gateway", "503": "Service unavailable", "504": "Gateway timeout", - "505": "HTTP version not supported for this request" + "505": "HTTP version not supported for this request", + "defaultTip": "Request error" }, "components": { "iconSelector": { diff --git a/locales/zh_CN.json b/locales/zh_CN.json index da911ba..cf3a879 100644 --- a/locales/zh_CN.json +++ b/locales/zh_CN.json @@ -51,7 +51,9 @@ "closeLeft": "关闭左侧", "closeRight": "关闭右侧", "closeAll": "全部关闭", - "backHome": "回到首页" + "backHome": "回到首页", + "getRouteError": "获取路由失败,请稍后再试" + }, "http": { "defaultTip": "请求错误", diff --git a/src/store/route.ts b/src/store/route.ts index 9d3eeba..8fe1626 100644 --- a/src/store/route.ts +++ b/src/store/route.ts @@ -1,7 +1,7 @@ import type { MenuOption } from 'naive-ui' import { RouterLink } from 'vue-router' import { h } from 'vue' -import { clone, construct } from 'radash' +import { clone, construct, min } from 'radash' import type { RouteRecordRaw } from 'vue-router' import { $t, arrayToTree, local, renderIcon } from '@/utils' import { router } from '@/router' @@ -34,29 +34,29 @@ export const useRouteStore = defineStore('route-store', { this.$reset() }, resetRoutes() { - /* 删除后面添加的路由 */ router.removeRoute('appRoot') }, - /* 设置当前高亮的菜单key */ + // set the currently highlighted menu key setActiveMenu(key: string) { this.activeMenu = key }, /* 生成侧边菜单的数据 */ createMenus(userRoutes: AppRoute.RowRoute[]) { const resultMenus = clone(userRoutes).map(i => construct(i)) as AppRoute.Route[] - // arrayToTree2() - /** 过滤不需要显示的菜单 */ + + // filter menus that do not need to be displayed const visibleMenus = resultMenus.filter(route => !route.meta.hide) - // 生成侧边菜单 + + // generate side menu this.menus = arrayToTree(this.transformAuthRoutesToMenus(visibleMenus)) }, - //* 将返回的路由表渲染成侧边栏 */ + // render the returned routing table as a sidebar transformAuthRoutesToMenus(userRoutes: AppRoute.Route[]): MenuOption[] { const { hasPermission } = usePermission() - /** 过滤没有权限的侧边菜单 */ + // Filter out side menus without permission return userRoutes.filter(i => hasPermission(i.meta.roles)) - /** 根据order大小菜单排序 */ + // Sort the menu according to the order size .sort((a, b) => { if (a.meta && a.meta.order && b.meta && b.meta.order) return a.meta.order - b.meta.order @@ -66,7 +66,8 @@ export const useRouteStore = defineStore('route-store', { return 1 else return 0 }) - /** 转换为侧边菜单数据结构 */ + + // Convert to side menu data structure .map((item) => { const target: MenuOption = { id: item.id, @@ -92,32 +93,30 @@ export const useRouteStore = defineStore('route-store', { }, createRoutes(routes: AppRoute.RowRoute[]) { const { hasPermission } = usePermission() - // 结构化meta字段 + + // Structure the meta field let resultRouter = clone(routes).map(i => construct(i)) as AppRoute.Route[] - // 路由权限过滤 + + // Route permission filtering resultRouter = resultRouter.filter(i => hasPermission(i.meta.roles)) - // 生成需要keepAlive的路由name数组 + // Generate an array of route names that need to be kept alive this.cacheRoutes = resultRouter.filter((i) => { return i.meta.keepAlive }) .map(i => i.name) - // 生成路由,有redirect的不需要引入文件 + // Generate routes, no need to import files for those with redirect const modules = import.meta.glob('@/views/**/*.vue') resultRouter = resultRouter.map((item: AppRoute.Route) => { if (item.componentPath && !item.redirect) item.component = modules[`/src/views${item.componentPath}`] - - // 判断是否是目录,代表目录的路由没有实际页面 - if (item.meta.menuType === 'dir') - item.redirect = '/404' - return item }) - // 生成路由表 + // Generate route tree resultRouter = arrayToTree(resultRouter) as AppRoute.Route[] + const appRootRoute: RouteRecordRaw = { path: '/appRoot', name: 'appRoot', @@ -129,14 +128,39 @@ export const useRouteStore = defineStore('route-store', { }, children: [], } - // 根据角色过滤后的插入根路由中 + + // Set the correct redirect path for the route + this.setRedirect(resultRouter) + + // Insert the processed route into the root route appRootRoute.children = resultRouter as unknown as RouteRecordRaw[] - // 插入路由表 router.addRoute(appRootRoute) }, + setRedirect(routes: AppRoute.Route[]) { + routes.forEach((route) => { + if (route.children) { + if (!route.redirect) { + // Filter out a collection of child elements that are not hidden + const visibleChilds = route.children.filter(child => !child.meta.hide) + + // Redirect page to the path of the first child element by default + let target = visibleChilds[0] + + // Filter out pages with the order attribute + const orderChilds = visibleChilds.filter(child => child.meta.order) + + if (orderChilds.length > 0) + target = min(orderChilds, i => i.meta.order!) as AppRoute.Route + + route.redirect = target.path + } + + this.setRedirect(route.children) + } + }) + }, async initRouteInfo() { if (import.meta.env.VITE_AUTH_ROUTE_MODE === 'dynamic') { - // 根据用户id来获取用户的路由 const userInfo = local.get('userInfo') if (!userInfo || !userInfo.id) { @@ -145,6 +169,7 @@ export const useRouteStore = defineStore('route-store', { return } + // Get user's route const { data } = await fetchUserRoutes({ id: userInfo.id, }) @@ -161,16 +186,19 @@ export const useRouteStore = defineStore('route-store', { }, async initAuthRoute() { this.isInitAuthRoute = false - // 初始化路由信息 + + // Initialize route information const rowRoutes = await this.initRouteInfo() if (!rowRoutes) { - window.$message.error('获取路由失败,请稍后再试') + window.$message.error($t(`app.getRouteError`)) return } this.rowRoutes = rowRoutes - // 生成真实路由并插入 + + // Generate actual route and insert this.createRoutes(rowRoutes) - // 生成侧边菜单 + + // Generate side menu this.createMenus(rowRoutes) this.isInitAuthRoute = true