// 模拟路由配置数据,基于实际项目结构 const mockRoutes = [ { path: '/underwriting', name: 'PreliminaryUnderwriting', component: () => import('@/views/ebiz/underwriting/PreliminaryUnderwritingContainer.vue'), children: [ { path: 'list', name: 'UnderwritingOrderList', meta: { title: '预核保订单列表' }, component: () => import('@/views/ebiz/underwriting/OrderList.vue') }, { path: 'data-collection', name: 'UnderwritingDataCollection', meta: { title: '信息录入' }, component: () => import('@/views/ebiz/underwriting/UnderwritingDataCollection.vue') }, { path: 'supplementary-information', name: 'UnderwritingSupplementaryInformation', meta: { title: '补传资料' }, component: () => import('@/views/ebiz/underwriting/SupplementaryInformation.vue') }, { path: 'result', name: 'UnderwritingResult', meta: { title: '预核保结果' }, component: () => import('@/views/ebiz/underwriting/Result.vue') }, { path: 'contract-sign', name: 'UnderwritingContractSign', meta: { title: '签名确认' }, component: () => import('@/views/ebiz/underwriting/SignContract.vue') }, { path: 'document-info', name: 'UnderwritingDocumentInfo', meta: { title: '预核保资料' }, component: () => import('@/views/ebiz/underwriting/DocumentInfo.vue') } ] }, { path: '/other', name: 'Other', component: () => import('@/views/other/OtherContainer.vue'), children: [ { path: 'nested', name: 'Nested', component: () => import('@/views/other/Nested.vue'), children: [ { path: 'deep', name: 'DeepNested', meta: { title: '深层嵌套路由' }, component: () => import('@/views/other/DeepNested.vue') } ] } ] }, { path: '/', name: 'Home', component: () => import('@/views/Home.vue') }, { path: '/simple', name: 'SimpleRoute', meta: { title: '简单路由' }, component: () => import('@/views/Simple.vue') } ]; /** * 递归查找具有指定路径的路由(支持多层嵌套) * @param routes 路由数组 * @param targetPath 目标路径 * @param parentPath 父级路径 * @returns 匹配的路由信息或undefined */ function findRouteByPath(routes, targetPath, parentPath = '') { if (!routes || !Array.isArray(routes)) return undefined // 规范化目标路径,移除多余的斜杠 targetPath = targetPath.replace(/\/+/g, '/') for (const route of routes) { // 构造当前路由的完整路径 let currentPath = parentPath if (currentPath && !currentPath.endsWith('/') && route.path && !route.path.startsWith('/')) { currentPath += '/' + route.path } else { currentPath += route.path } // 移除多余的斜杠 currentPath = currentPath.replace(/\/+/g, '/') // 检查当前路由是否匹配 if (currentPath === targetPath) { return { route: route, fullPath: currentPath } } // 递归检查子路由 if (route.children && route.children.length > 0) { const matchedChild = findRouteByPath(route.children, targetPath, currentPath) if (matchedChild) { return matchedChild } } } return undefined } /** * 递归查找具有指定名称的路由(支持多层嵌套) * @param routes 路由数组 * @param targetName 目标名称 * @param routeStack 用于追踪路由层级的堆栈 * @returns 包含路由和路由堆栈的对象,或undefined */ function findRouteByName(routes, targetName, routeStack = []) { if (!routes || !Array.isArray(routes)) return undefined for (const route of routes) { // 创建当前路由的堆栈副本 const currentStack = [...routeStack, route] // 检查当前路由是否匹配 if (route.name === targetName) { return { route: route, routeStack: currentStack } } // 递归检查子路由 if (route.children && route.children.length > 0) { const matchedChild = findRouteByName(route.children, targetName, currentStack) if (matchedChild) { return matchedChild } } } return undefined } /** * 根据路由堆栈构建完整路径 * @param routeStack 路由堆栈 * @returns 完整路径字符串 */ function buildFullPath(routeStack) { if (!routeStack || routeStack.length === 0) return '' // 提取所有路由的路径并正确拼接 let fullPath = '' routeStack.forEach((route, index) => { // 特殊处理第一个路由 if (index === 0) { fullPath += route.path } else { if (fullPath && !fullPath.endsWith('/') && route.path && !route.path.startsWith('/')) { fullPath += '/' + route.path } else if (fullPath.endsWith('/') && route.path.startsWith('/')) { // 如果fullPath以/结尾,而route.path以/开头,则需要去掉一个/ fullPath += route.path.substring(1) } else { fullPath += route.path } } }) // 移除多余的斜杠 fullPath = fullPath.replace(/\/+/g, '/') // 确保不会在末尾留下斜杠(除非是根路径) if (fullPath.length > 1 && fullPath.endsWith('/')) { fullPath = fullPath.slice(0, -1) } return fullPath } describe('Underwriting Navigate Functions', () => { describe('findRouteByPath', () => { it('应该能找到根路径路由', () => { const result = findRouteByPath(mockRoutes, '/') expect(result).not.toBeUndefined() expect(result.route.name).toBe('Home') }) it('应该能找到简单路径路由', () => { const result = findRouteByPath(mockRoutes, '/simple') expect(result).not.toBeUndefined() expect(result.route.name).toBe('SimpleRoute') }) it('应该能找到一级嵌套路由', () => { const result = findRouteByPath(mockRoutes, '/underwriting') expect(result).not.toBeUndefined() expect(result.route.name).toBe('PreliminaryUnderwriting') }) it('应该能找到二级嵌套路由', () => { const result = findRouteByPath(mockRoutes, '/underwriting/list') expect(result).not.toBeUndefined() expect(result.route.name).toBe('UnderwritingOrderList') }) it('应该能找到三级嵌套路由', () => { const result = findRouteByPath(mockRoutes, '/other/nested/deep') expect(result).not.toBeUndefined() expect(result.route.name).toBe('DeepNested') }) it('应该返回undefined当找不到路由时', () => { const result = findRouteByPath(mockRoutes, '/nonexistent') expect(result).toBeUndefined() }) it('应该正确处理带有多个斜杠的路径', () => { // 实际上我们查找的是 /underwriting/list,只是输入路径中有多余的斜杠 const result = findRouteByPath(mockRoutes, '/underwriting///list') expect(result).not.toBeUndefined() expect(result.route.name).toBe('UnderwritingOrderList') }) }) describe('findRouteByName', () => { it('应该通过名称找到根路径路由', () => { const result = findRouteByName(mockRoutes, 'Home') expect(result).not.toBeUndefined() expect(result.route.name).toBe('Home') }) it('应该通过名称找到简单路径路由', () => { const result = findRouteByName(mockRoutes, 'SimpleRoute') expect(result).not.toBeUndefined() expect(result.route.name).toBe('SimpleRoute') }) it('应该通过名称找到一级嵌套路由', () => { const result = findRouteByName(mockRoutes, 'PreliminaryUnderwriting') expect(result).not.toBeUndefined() expect(result.route.name).toBe('PreliminaryUnderwriting') }) it('应该通过名称找到二级嵌套路由', () => { const result = findRouteByName(mockRoutes, 'UnderwritingOrderList') expect(result).not.toBeUndefined() expect(result.route.name).toBe('UnderwritingOrderList') }) it('应该通过名称找到三级嵌套路由', () => { const result = findRouteByName(mockRoutes, 'DeepNested') expect(result).not.toBeUndefined() expect(result.route.name).toBe('DeepNested') }) it('应该返回undefined当找不到路由时', () => { const result = findRouteByName(mockRoutes, 'NonExistent') expect(result).toBeUndefined() }) }) describe('buildFullPath', () => { it('应该正确构建根路径', () => { const routeStack = [{ path: '/' }] const result = buildFullPath(routeStack) expect(result).toBe('/') }) it('应该正确构建简单路径', () => { const routeStack = [ { path: '/' }, { path: 'simple' } ] const result = buildFullPath(routeStack) expect(result).toBe('/simple') }) it('应该正确构建嵌套路径', () => { const routeStack = [ { path: '/underwriting' }, { path: 'list' } ] const result = buildFullPath(routeStack) expect(result).toBe('/underwriting/list') }) it('应该正确构建深层嵌套路径', () => { const routeStack = [ { path: '/other' }, { path: 'nested' }, { path: 'deep' } ] const result = buildFullPath(routeStack) expect(result).toBe('/other/nested/deep') }) it('应该正确处理空路由堆栈', () => { const result = buildFullPath([]) expect(result).toBe('') }) it('应该正确处理多余的斜杠', () => { const routeStack = [ { path: '/underwriting/' }, { path: '/list/' } ] const result = buildFullPath(routeStack) // 由于路径规范化处理,结果应该是 /underwriting/list 而不是 /underwriting//list expect(result).toBe('/underwriting/list') }) }) })