Files
PingChuan 5bee9288b9 feat:替换 Dify 为自建 RAG去实现
1、修复了若干无权限时的失败提示语
2、新增了一个生成后续建议问题的功能
3、重构了知识问答部分的权限管理模块
4、修复了若干渲染不恰当的样式渲染
2026-04-10 16:20:32 +08:00

131 lines
5.5 KiB
TypeScript

import { Button, Tooltip, Select, Spin } from 'antd';
import {
FileTextOutlined,
SearchOutlined,
SettingOutlined,
ArrowLeftOutlined,
DatabaseOutlined,
AppstoreOutlined,
SwapOutlined,
} from '@ant-design/icons';
import type { DatasetLayoutProps, MenuTab, MenuItem } from '~/types/dify-dataset-manager/layout';
import { usePermission } from '~/hooks/usePermission';
/**
* 知识库布局组件
* 包含左侧菜单栏和右侧内容区
*/
export default function DatasetLayout({
dataset,
activeTab,
onTabChange,
showBackButton = false,
onBack,
children,
availableDatasets = [],
loadingAvailableDatasets = false,
onDatasetChange,
}: DatasetLayoutProps) {
const { hasPermission } = usePermission();
const menuItems: MenuItem[] = [
...(hasPermission('dify:dataset:read') ? [{ key: 'documents' as MenuTab, icon: <FileTextOutlined />, label: '文档' }] : []),
...(hasPermission('dify:retrieve:test') ? [{ key: 'retrieve' as MenuTab, icon: <SearchOutlined />, label: '召回测试' }] : []),
...(hasPermission('dify:config:manage') ? [{ key: 'area-config' as MenuTab, icon: <AppstoreOutlined />, label: '配置管理' }] : []),
...(hasPermission('dify:settings:write') ? [{ key: 'settings' as MenuTab, icon: <SettingOutlined />, label: '设置' }] : []),
];
// 是否显示知识库选择器(有多个知识库时显示)
const showDatasetSelector = availableDatasets.length > 1;
return (
<div className="dataset-layout">
{/* 左侧侧边栏 */}
<aside className="dataset-sidebar">
{/* 知识库信息 / 选择器 */}
<div className="sidebar-header">
<div className="dataset-icon">
<DatabaseOutlined />
</div>
{showDatasetSelector ? (
/* 多个知识库时显示下拉选择器 */
<div className="dataset-selector">
<Select
value={dataset?.id}
onChange={onDatasetChange}
loading={loadingAvailableDatasets}
className="dataset-select"
placeholder="选择知识库"
suffixIcon={<SwapOutlined />}
popupMatchSelectWidth={false}
styles={{ popup: { root: { minWidth: 200 } } }}
>
{availableDatasets.map(ds => (
<Select.Option key={ds.dataset_id} value={ds.dataset_id}>
<div className="dataset-option">
<span className="dataset-option-name">{ds.dataset_name}</span>
{ds.is_default && <span className="dataset-option-tag"></span>}
{ds.is_public && <span className="dataset-option-tag public"></span>}
</div>
</Select.Option>
))}
</Select>
<span className="dataset-type"></span>
</div>
) : (
/* 单个或无知识库时显示名称 */
<div className="dataset-info">
<Tooltip title={dataset?.name} placement="right">
<h2 className="dataset-name">{dataset?.name || '知识库'}</h2>
</Tooltip>
<span className="dataset-type"></span>
</div>
)}
</div>
{/* 统计信息 */}
<div className="sidebar-stats">
<span className="stat-item">
{dataset?.document_count || 0}
</span>
</div>
{/* 导航菜单 */}
<nav className="sidebar-menu">
{menuItems.map((item) => (
<button
key={item.key}
className={`menu-item ${activeTab === item.key ? 'active' : ''}`}
onClick={() => onTabChange(item.key)}
>
<span className="menu-icon">{item.icon}</span>
<span className="menu-label">{item.label}</span>
</button>
))}
</nav>
</aside>
{/* 右侧内容区 */}
<main className="dataset-main">
{/* 返回按钮 */}
{showBackButton && onBack && (
<div className="sidebar-back">
<Button
type="text"
icon={<ArrowLeftOutlined />}
onClick={onBack}
className="back-btn"
>
</Button>
</div>
)}
{children}
</main>
</div>
);
}
// 重新导出类型,保持向后兼容
export type { MenuTab } from '~/types/dify-dataset-manager/layout';