feat(web): knowledge base

This commit is contained in:
zhaoying
2026-05-06 14:13:13 +08:00
parent b0a4f9fa18
commit a947d6d095
9 changed files with 181 additions and 68 deletions

View File

@@ -55,6 +55,10 @@ const CreateDatasetModal = forwardRef<CreateDatasetModalRef,CreateDatasetModalRe
title: t('knowledgeBase.customText'),
description: t('knowledgeBase.manuallyInputText')
},
{
title: t('knowledgeBase.csvFile'),
description: t('knowledgeBase.csvUploadFileTypes')
},
]
// 封装取消方法,添加关闭弹窗逻辑
const handleClose = () => {
@@ -86,7 +90,7 @@ const CreateDatasetModal = forwardRef<CreateDatasetModalRef,CreateDatasetModalRe
// description: selected.description,
// });
// 跳转到创建数据集页面并携带来源参数
const source = value === 0 ? 'local' : value === 1 ? 'link' : 'text';
const source = value === 3 ? 'csv' : value === 0 ? 'local' : value === 1 ? 'link' : 'text';
if (knowledgeBaseId) {
navigate(`/knowledge-base/${knowledgeBaseId}/create-dataset`,{
state: {
@@ -139,6 +143,12 @@ const CreateDatasetModal = forwardRef<CreateDatasetModalRef,CreateDatasetModalRe
<span className='rb:text-base rb:font-medium rb:text-gray-800'>{items[1].title}</span>
<span className='rb:text-xs rb:text-gray-500'>{items[1].description}</span>
</Flex>
</Radio>
<Radio value={3} style={getActiveRadioStyle(value === 3)} className='rb:w-full'>
<Flex gap="small" align='start' justify='start' vertical>
<span className='rb:text-base rb:font-medium rb:text-gray-800'>{items[2].title}</span>
<span className='rb:text-xs rb:text-gray-500'>{items[2].description}</span>
</Flex>
</Radio>
</Radio.Group>
</div>

View File

@@ -7,20 +7,22 @@
* @LastEditTime: 2025-12-22 13:47:53
*/
import { FileOutlined, FieldTimeOutlined, EditOutlined } from '@ant-design/icons';
import { Skeleton, Flex, Space } from 'antd';
import { Skeleton, Flex, Space, App } from 'antd';
import { useTranslation } from 'react-i18next';
import type { RecallTestData } from '@/views/KnowledgeBase/types';
import { NoData } from './noData';
import { formatDateTime } from '@/utils/format';
import InfiniteScroll from 'react-infinite-scroll-component';
import RbMarkdown from '@/components/Markdown';
import { useMemo } from 'react';
import { useMemo, type MouseEvent } from 'react';
import { deleteDocumentChunk } from '@/api/knowledgeBase'
interface RecallTestResultProps {
data: RecallTestData[];
showEmpty?: boolean;
hasMore?: boolean;
loadMore?: () => void;
refresh?: () => void;
loading?: boolean;
scrollableTarget?: string;
editable?: boolean; // Whether editable
@@ -34,6 +36,7 @@ const RecallTestResult = ({
showEmpty = true,
hasMore = false,
loadMore,
refresh,
loading = false,
scrollableTarget,
editable = false,
@@ -42,6 +45,7 @@ const RecallTestResult = ({
handleCopy,
}: RecallTestResultProps) => {
const { t } = useTranslation();
const { modal, message } = App.useApp()
console.log('chunk data', data)
// Parse QA format content
@@ -133,6 +137,24 @@ const RecallTestResult = ({
return 'rb:text-[#FF5D34]';
}
};
const handleDelete = (e: MouseEvent, item: RecallTestData) => {
e.preventDefault();
e.stopPropagation();
modal.confirm({
title: t('common.confirmDeleteDesc', { name: `chunk_${item.metadata?.sort_id}` }),
okText: t('common.delete'),
cancelText: t('common.cancel'),
okType: 'danger',
onOk: () => {
deleteDocumentChunk(item.metadata.knowledge_id, item.metadata.document_id, item.metadata.doc_id)
.then(() => {
message.success(t('common.deleteSuccess'));
refresh?.()
})
}
})
console.log('RecallTestData', item)
}
// Show skeleton when initial loading
if (loading && data.length === 0) {
@@ -186,17 +208,21 @@ const RecallTestResult = ({
{scorePercentage.toFixed(1)}% {t('knowledgeBase.similarity')}
</span>
)}
<div className={`rb:flex rb:mt-2 rb:flex rb:items-end rb:justify-end rb:gap-4 ${!showScore ? 'rb:w-full' : ''}`}>
<div className={`rb:flex rb:mt-2 rb:items-end rb:justify-end rb:gap-4 ${!showScore ? 'rb:w-full' : ''}`}>
<span className='rb:text-gray-800'>
<FileOutlined /> {item.metadata?.file_name || '-'}
</span>
<span className='rb:text-gray-500 rb:text-xs rb:bg-[#DFDFDF] rb:px-1 rb:py-[2px] rb:rounded'>
<span className='rb:text-gray-500 rb:text-xs rb:bg-[#DFDFDF] rb:px-1 rb:py-0.5 rb:rounded'>
chunk_{item.metadata?.sort_id || index}
</span>
<div
className="rb:size-5 rb:cursor-pointer rb:bg-cover rb:bg-[url('@/assets/images/common/delete.svg')] rb:hover:bg-[url('@/assets/images/common/delete_hover.svg')]"
onClick={(e) => handleDelete(e, item)}
></div>
</div>
</div>
<div className='rb:flex rb:text-left rb:px-4 rb:py-3 rb:bg-white rb:rounded-lg rb:mt-2'>
<div className='rb:text-gray-800 rb:text-sm rb:whitespace-pre-wrap rb:break-words rb:w-full'>
<div className='rb:text-gray-800 rb:text-sm rb:whitespace-pre-wrap rb:wrap-break-word rb:w-full'>
{(() => {
const qaContent = parseQAContent(item.page_content);
if (qaContent) {
@@ -239,7 +265,7 @@ const RecallTestResult = ({
<div className='rb:flex rb:h-full rb:flex-col'>
<div className='rb:flex rb:items-center rb:justify-start rb:gap-2'>
<span className='rb:text-lg rb:font-medium'>{t('knowledgeBase.recallResult')}</span>
<span className='rb:text-gray-500 rb:text-xs rb:pt-[2px]'>
<span className='rb:text-gray-500 rb:text-xs rb:pt-0.5'>
(<span className='rb:text-[#155EEF]'>{data.length}</span> results)
</span>
</div>
@@ -262,7 +288,7 @@ const RecallTestResult = ({
<div className='rb:flex rb:flex-col'>
<div className='rb:flex rb:items-center rb:justify-start rb:gap-2'>
<span className='rb:text-lg rb:font-medium'>{t('knowledgeBase.recallResult')}</span>
<span className='rb:text-gray-500 rb:text-xs rb:pt-[2px]'>
<span className='rb:text-gray-500 rb:text-xs rb:pt-0.5'>
(<span className='rb:text-[#155EEF]'>{data.length}</span> results)
</span>
</div>