auto-generate breadcrumb navigation for tool pages
This commit is contained in:
parent
0a23ee2587
commit
66036da8e9
@ -79,9 +79,75 @@ const appName = computed(() => localStorage.getItem('appName') || 'Jingrow')
|
|||||||
|
|
||||||
const isSystemUser = computed(() => authStore.user?.user_type === 'System User')
|
const isSystemUser = computed(() => authStore.user?.user_type === 'System User')
|
||||||
|
|
||||||
|
// 将路径段转换为可读标签
|
||||||
|
function pathSegmentToLabel(segment: string): string {
|
||||||
|
// 将 kebab-case 或 snake_case 转换为标题格式
|
||||||
|
return segment
|
||||||
|
.split(/[-_]/)
|
||||||
|
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||||
|
.join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从路由路径自动生成面包屑
|
||||||
|
function generateBreadcrumbFromPath(path: string): Array<{ label: string; href?: string }> {
|
||||||
|
const items: Array<{ label: string; href?: string }> = []
|
||||||
|
const segments = path.split('/').filter(Boolean)
|
||||||
|
|
||||||
|
// 构建路径前缀,用于生成 href
|
||||||
|
let currentPath = ''
|
||||||
|
|
||||||
|
segments.forEach((segment, index) => {
|
||||||
|
currentPath += `/${segment}`
|
||||||
|
const isLast = index === segments.length - 1
|
||||||
|
|
||||||
|
// 特殊处理:tools 路径
|
||||||
|
if (segment === 'tools') {
|
||||||
|
items.push({
|
||||||
|
label: t('Tools'),
|
||||||
|
href: isLast ? undefined : currentPath
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 对于最后一项,不添加链接
|
||||||
|
items.push({
|
||||||
|
label: pathSegmentToLabel(segment),
|
||||||
|
href: isLast ? undefined : currentPath
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
const breadcrumbItems = computed(() => {
|
const breadcrumbItems = computed(() => {
|
||||||
const items: Array<{ label: string; href?: string }> = []
|
const items: Array<{ label: string; href?: string }> = []
|
||||||
|
|
||||||
|
// 优先检查路由 meta 中的 toolName(工具路由)
|
||||||
|
if (route.meta?.toolName) {
|
||||||
|
// 工具路由:显示 Tools / 工具名称
|
||||||
|
// 自动解析 Tools 路由的路径(用于面包屑链接)
|
||||||
|
let toolsPath = '/app/tools' // 默认值
|
||||||
|
try {
|
||||||
|
const resolved = router.resolve({ name: 'Tools' })
|
||||||
|
if (resolved.matched.length > 0) {
|
||||||
|
toolsPath = resolved.path
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 解析失败,使用默认值
|
||||||
|
}
|
||||||
|
items.push({
|
||||||
|
label: t('Tools'),
|
||||||
|
href: toolsPath
|
||||||
|
})
|
||||||
|
// 使用 meta.toolName(工具的显示名称)
|
||||||
|
const toolLabel = route.meta.toolName as string
|
||||||
|
if (toolLabel) {
|
||||||
|
items.push({
|
||||||
|
label: toolLabel
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
// 根据路由名称和参数生成面包屑
|
// 根据路由名称和参数生成面包屑
|
||||||
if (route.name === 'PageTypeList') {
|
if (route.name === 'PageTypeList') {
|
||||||
const entity = route.params.entity as string
|
const entity = route.params.entity as string
|
||||||
@ -105,8 +171,15 @@ const breadcrumbItems = computed(() => {
|
|||||||
label: id === 'new' ? t('Create') : id
|
label: id === 'new' ? t('Create') : id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
} else if (route.name === 'WorkspacePage') {
|
||||||
|
const name = route.params.name as string
|
||||||
|
if (name) {
|
||||||
|
items.push({
|
||||||
|
label: pathSegmentToLabel(name)
|
||||||
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 其他页面的标题映射
|
// 其他页面的标题映射(保留向后兼容)
|
||||||
const map: Record<string, string> = {
|
const map: Record<string, string> = {
|
||||||
Dashboard: t('Dashboard'),
|
Dashboard: t('Dashboard'),
|
||||||
AgentList: t('Agents'),
|
AgentList: t('Agents'),
|
||||||
@ -123,8 +196,24 @@ const breadcrumbItems = computed(() => {
|
|||||||
SearchResults: t('Search Results')
|
SearchResults: t('Search Results')
|
||||||
}
|
}
|
||||||
const title = map[route.name as string]
|
const title = map[route.name as string]
|
||||||
|
|
||||||
if (title) {
|
if (title) {
|
||||||
items.push({ label: title })
|
items.push({ label: title })
|
||||||
|
} else {
|
||||||
|
// 如果没有匹配的标题,尝试从路径自动生成
|
||||||
|
// 排除根路径和已知的特殊路径
|
||||||
|
if (route.path !== '/' && !route.path.startsWith('/app/') && !route.path.startsWith('/page/')) {
|
||||||
|
const pathItems = generateBreadcrumbFromPath(route.path)
|
||||||
|
if (pathItems.length > 0) {
|
||||||
|
items.push(...pathItems)
|
||||||
|
} else {
|
||||||
|
// 最后的后备方案:使用路由名称
|
||||||
|
const routeName = route.name as string
|
||||||
|
if (routeName) {
|
||||||
|
items.push({ label: pathSegmentToLabel(routeName) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -256,7 +256,7 @@ router.beforeEach(async (to, _from, next) => {
|
|||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
// 路由不存在,重定向到工具列表页
|
// 路由不存在,重定向到工具列表页
|
||||||
next('/tools')
|
next({ name: 'Tools' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user