Files
MemoryBear/web/src/hooks/useBreadcrumbManager.ts
yujiangping 1bc06e8204 Sync frontend project from dev-yjp branch
- Updated web folder with latest frontend code
- Added new components: CreateContentModal, CreateContentModalExample
- Added new hook: useBreadcrumbManager
- Updated knowledge base components and views
- Updated i18n translations
- Various bug fixes and improvements
2025-12-16 11:58:37 +08:00

248 lines
8.2 KiB
TypeScript

import { useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { useMenu } from '@/store/menu';
import type { MenuItem } from '@/store/menu';
export interface BreadcrumbItem {
id: string;
name: string;
type?: 'knowledgeBase' | 'folder' | 'document';
}
export interface BreadcrumbPath {
knowledgeBaseFolderPath: BreadcrumbItem[]; // 知识库文件夹路径
knowledgeBase?: BreadcrumbItem; // 知识库信息
documentFolderPath: BreadcrumbItem[]; // 文档文件夹路径
document?: BreadcrumbItem; // 文档信息
}
export interface BreadcrumbOptions {
onKnowledgeBaseMenuClick?: () => void;
onKnowledgeBaseFolderClick?: (folderId: string, folderPath: BreadcrumbItem[]) => void;
// 新增:区分面包屑类型
breadcrumbType?: 'list' | 'detail';
}
export const useBreadcrumbManager = (options?: BreadcrumbOptions) => {
const { allBreadcrumbs, setCustomBreadcrumbs } = useMenu();
const navigate = useNavigate();
const updateBreadcrumbs = useCallback((breadcrumbPath: BreadcrumbPath) => {
const breadcrumbType = options?.breadcrumbType || 'list';
// 获取基础面包屑,对于详情页面,使用列表页面的基础面包屑作为起点
const baseBreadcrumbs = breadcrumbType === 'list'
? (allBreadcrumbs['space'] || [])
: (allBreadcrumbs['space'] || []); // 详情页面也从 space 获取基础面包屑
// 只保留知识库菜单项之前的面包屑
const knowledgeBaseMenuIndex = baseBreadcrumbs.findIndex(item => item.path === '/knowledge-base');
const filteredBaseBreadcrumbs = knowledgeBaseMenuIndex >= 0
? baseBreadcrumbs.slice(0, knowledgeBaseMenuIndex + 1)
: baseBreadcrumbs;
// 给"知识库管理"添加点击事件
const breadcrumbsWithClick = filteredBaseBreadcrumbs.map((item) => {
if (item.path === '/knowledge-base') {
return {
...item,
onClick: (e?: React.MouseEvent) => {
e?.preventDefault();
e?.stopPropagation();
if (options?.onKnowledgeBaseMenuClick) {
// 如果提供了回调函数,执行回调
options.onKnowledgeBaseMenuClick();
} else if (breadcrumbType === 'detail') {
// 知识库详情页面:没有回调函数时,返回到知识库列表页面
navigate('/knowledge-base', {
state: {
resetToRoot: true,
}
});
}
return false;
},
};
}
return item;
});
let customBreadcrumbs: MenuItem[] = [...breadcrumbsWithClick];
if (breadcrumbType === 'list') {
// 知识库列表页面:只显示知识库文件夹路径
customBreadcrumbs = [
...breadcrumbsWithClick,
...breadcrumbPath.knowledgeBaseFolderPath.map((folder, index) => ({
id: 0,
parent: 0,
code: null,
label: folder.name,
i18nKey: null,
path: null,
enable: true,
display: true,
level: 0,
sort: 0,
icon: null,
iconActive: null,
menuDesc: null,
deleted: null,
updateTime: 0,
new_: null,
keepAlive: false,
master: null,
disposable: false,
appSystem: null,
subs: [],
onClick: (e?: React.MouseEvent) => {
e?.preventDefault();
e?.stopPropagation();
// 如果有回调函数,直接调用回调函数来更新状态
if (options?.onKnowledgeBaseFolderClick) {
options.onKnowledgeBaseFolderClick(folder.id, breadcrumbPath.knowledgeBaseFolderPath.slice(0, index + 1));
} else {
// 否则使用导航(兜底逻辑)
navigate('/knowledge-base', {
state: {
navigateToFolder: folder.id,
folderPath: breadcrumbPath.knowledgeBaseFolderPath.slice(0, index + 1)
}
});
}
return false;
},
})),
];
} else {
// 知识库详情页面:显示知识库名称 + 文档文件夹路径 + 文档名称
customBreadcrumbs = [
...breadcrumbsWithClick,
// 添加知识库名称
...(breadcrumbPath.knowledgeBase ? [{
id: 0,
parent: 0,
code: null,
label: breadcrumbPath.knowledgeBase.name,
i18nKey: null,
path: null,
enable: true,
display: true,
level: 0,
sort: 0,
icon: null,
iconActive: null,
menuDesc: null,
deleted: null,
updateTime: 0,
new_: null,
keepAlive: false,
master: null,
disposable: false,
appSystem: null,
subs: [],
onClick: (e?: React.MouseEvent) => {
e?.preventDefault();
e?.stopPropagation();
// 返回到知识库详情页的根目录
const navigationState = {
fromKnowledgeBaseList: true,
knowledgeBaseFolderPath: breadcrumbPath.knowledgeBaseFolderPath,
resetToRoot: true, // 添加重置到根目录的标志
refresh: true, // 添加刷新标志
timestamp: Date.now(), // 添加时间戳确保状态变化
};
navigate(`/knowledge-base/${breadcrumbPath.knowledgeBase!.id}/private`, {
state: navigationState,
replace: true // 使用 replace 避免历史记录堆积
});
return false;
},
}] : []),
// 添加文档文件夹路径
...breadcrumbPath.documentFolderPath.map((folder, index) => ({
id: 0,
parent: 0,
code: null,
label: folder.name,
i18nKey: null,
path: null,
enable: true,
display: true,
level: 0,
sort: 0,
icon: null,
iconActive: null,
menuDesc: null,
deleted: null,
updateTime: 0,
new_: null,
keepAlive: false,
master: null,
disposable: false,
appSystem: null,
subs: [],
onClick: (e?: React.MouseEvent) => {
e?.preventDefault();
e?.stopPropagation();
// 返回到知识库详情页的对应文件夹
const navigationState = {
fromKnowledgeBaseList: true,
knowledgeBaseFolderPath: breadcrumbPath.knowledgeBaseFolderPath,
navigateToDocumentFolder: folder.id,
documentFolderPath: breadcrumbPath.documentFolderPath.slice(0, index + 1),
refresh: true, // 添加刷新标志
timestamp: Date.now(), // 添加时间戳确保状态变化
};
navigate(`/knowledge-base/${breadcrumbPath.knowledgeBase!.id}/private`, {
state: navigationState,
replace: true // 使用 replace 避免历史记录堆积
});
return false;
},
})),
// 添加文档名称(如果存在)
...(breadcrumbPath.document ? [{
id: 0,
parent: 0,
code: null,
label: breadcrumbPath.document.name,
i18nKey: null,
path: null,
enable: true,
display: true,
level: 0,
sort: 0,
icon: null,
iconActive: null,
menuDesc: null,
deleted: null,
updateTime: 0,
new_: null,
keepAlive: false,
master: null,
disposable: false,
appSystem: null,
subs: [],
// 文档名称不可点击
}] : []),
];
}
// 根据面包屑类型使用不同的键,实现独立的面包屑路径
const breadcrumbKey = breadcrumbType === 'list' ? 'space' : 'space-detail';
setCustomBreadcrumbs(customBreadcrumbs, breadcrumbKey);
}, [setCustomBreadcrumbs, navigate, options?.breadcrumbType, options?.onKnowledgeBaseMenuClick, options?.onKnowledgeBaseFolderClick]);
return {
updateBreadcrumbs,
};
};