123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- import { ChatContext } from '@/app/chat-context';
- import { apiInterceptors, delSpace, getSpaceConfig, getSpaceList, newDialogue } from '@/client/api';
- import DocPanel from '@/components/knowledge/doc-panel';
- import DocTypeForm from '@/components/knowledge/doc-type-form';
- import DocUploadForm from '@/components/knowledge/doc-upload-form';
- import Segmentation from '@/components/knowledge/segmentation';
- import SpaceForm from '@/components/knowledge/space-form';
- import BlurredCard, { ChatButton, InnerDropdown } from '@/new-components/common/blurredCard';
- import ConstructLayout from '@/new-components/layout/Construct';
- import { File, ISpace, IStorage, StepChangeParams } from '@/types/knowledge';
- import { PlusOutlined, ReadOutlined, SearchOutlined, WarningOutlined } from '@ant-design/icons';
- import { Avatar, Button, Input, Modal, Spin, Steps, Tag } from 'antd';
- import classNames from 'classnames';
- import { debounce } from 'lodash';
- import moment from 'moment';
- import { useRouter } from 'next/router';
- import { useContext, useEffect, useState } from 'react';
- import { useTranslation } from 'react-i18next';
- const Knowledge = () => {
- const { setCurrentDialogInfo } = useContext(ChatContext);
- const [spaceList, setSpaceList] = useState<Array<ISpace> | null>([]);
- const [isAddShow, setIsAddShow] = useState<boolean>(false);
- const [isPanelShow, setIsPanelShow] = useState<boolean>(false);
- const [currentSpace, setCurrentSpace] = useState<ISpace>();
- const [activeStep, setActiveStep] = useState<number>(0);
- const [spaceName, setSpaceName] = useState<string>('');
- const [files, setFiles] = useState<Array<File>>([]);
- const [docType, setDocType] = useState<string>('');
- const [addStatus, setAddStatus] = useState<string>('');
- const [loading, setLoading] = useState<boolean>(false);
- const [spaceConfig, setSpaceConfig] = useState<IStorage | null>(null);
- const { t } = useTranslation();
- const addKnowledgeSteps = [
- { title: t('Knowledge_Space_Config') },
- { title: t('Choose_a_Datasource_type') },
- { title: t('Upload') },
- { title: t('Segmentation') },
- ];
- const router = useRouter();
- async function getSpaces(params?: any) {
- setLoading(true);
- const [_, data] = await apiInterceptors(getSpaceList({ ...params }));
- setLoading(false);
- setSpaceList([...data, ...data, ...data, ...data, ...data, ...data, ...data,]);
- }
- async function getSpaceConfigs() {
- const [_, data] = await apiInterceptors(getSpaceConfig());
- if (!data) return null;
- setSpaceConfig(data.storage);
- }
- useEffect(() => {
- getSpaces();
- getSpaceConfigs();
- }, []);
- const handleChat = async (space: ISpace) => {
- const [_, data] = await apiInterceptors(
- newDialogue({
- chat_mode: 'chat_knowledge',
- }),
- );
- // 知识库对话都默认私有知识库应用下
- if (data?.conv_uid) {
- setCurrentDialogInfo?.({
- chat_scene: data.chat_mode,
- app_code: data.chat_mode,
- });
- localStorage.setItem(
- 'cur_dialog_info',
- JSON.stringify({
- chat_scene: data.chat_mode,
- app_code: data.chat_mode,
- }),
- );
- router.push(`/chat?scene=chat_knowledge&id=${data?.conv_uid}&knowledge_id=${space.name}`);
- }
- };
- const handleStepChange = ({ label, spaceName, docType, files }: StepChangeParams) => {
- if (label === 'finish') {
- setIsAddShow(false);
- getSpaces();
- setSpaceName('');
- setDocType('');
- setAddStatus('finish');
- localStorage.removeItem('cur_space_id');
- } else if (label === 'forward') {
- activeStep === 0 && getSpaces();
- setActiveStep(step => step + 1);
- } else {
- setActiveStep(step => step - 1);
- }
- files && setFiles(files);
- spaceName && setSpaceName(spaceName);
- docType && setDocType(docType);
- };
- function onAddDoc(spaceName: string) {
- setSpaceName(spaceName);
- setActiveStep(1);
- setIsAddShow(true);
- setAddStatus('start');
- }
- const showDeleteConfirm = (space: ISpace) => {
- Modal.confirm({
- title: t('Tips'),
- icon: <WarningOutlined />,
- content: `${t('Del_Knowledge_Tips')}?`,
- okText: 'Yes',
- okType: 'danger',
- cancelText: 'No',
- async onOk() {
- await apiInterceptors(delSpace({ name: space?.name }));
- getSpaces();
- },
- });
- };
- const onSearch = async (e: any) => {
- getSpaces({ name: e.target.value });
- };
- return (
- <ConstructLayout>
- <div className='page-body h-[90vh] overflow-aut mr-8 bg-[#fff]'>
- <div className='mt-2 rounded-[10px] flex h-16 justify-between items-center px-4'>
- <Input
- variant='filled'
- prefix={<SearchOutlined />}
- placeholder={t('please_enter_the_keywords')}
- allowClear
- className='w-[400px] h-[40px]
- border-1 border-[#d1d1d1]
- backdrop-filter
- backdrop-blur-lg
- dark:border-[#6f7f95]
- dark:bg-[#6f7f95]
- dark:bg-opacity-60'
- />
- <span className='flex gap-2 items-center'>
- <Avatar className='bg-gradient-to-tr from-[#31afff] to-[#1677ff] cursor-pointer'>
- </Avatar>
- <span
- >
- admin
- </span>
- </span>
- </div>
- <div className='flex justify-between items-center mb-6'>
- <div className='flex items-center gap-4'>
-
- </div>
- <div className='flex items-center gap-4'>
- <Button
- className='border-none text-white bg-button-gradient'
- onClick={() => {
- setIsAddShow(true);
- }}
- >
- 创建知识库
- </Button>
- </div>
- </div>
- <div className='rounded-[10px] mx-4 w-full mr-14 flex flex-wrap pb-12 bg-slate-200 p-4 border-1 mb-2'>
- {spaceList?.map((space: ISpace) => (
- <BlurredCard
- style={{ height: '200px!important'}}
- onClick={() => {
- setCurrentSpace(space);
- setIsPanelShow(true);
- localStorage.setItem('cur_space_id', JSON.stringify(space.id));
- }}
- description={space.desc}
- name={space.name}
- key={space.id}
- logo={
- space.domain_type === 'FinancialReport'
- ? '/models/fin_report.jpg'
- : space.vector_type === 'KnowledgeGraph'
- ? '/models/knowledge-graph.png'
- : space.vector_type === 'FullText'
- ? '/models/knowledge-full-text.jpg'
- : '/models/knowledge-default.jpg'
- }
- RightTop={
- <InnerDropdown
- menu={{
- items: [
- {
- key: 'del',
- label: (
- <span className='text-red-400' onClick={() => showDeleteConfirm(space)}>
- {t('Delete')}
- </span>
- ),
- },
- ],
- }}
- />
- }
- rightTopHover={false}
- Tags={
- <div className='flex item-center'>
- <Tag>
- <span className='flex items-center gap-1'>
- <ReadOutlined className='mt-[1px]' />
- {space.docs}
- </span>
- </Tag>
- <Tag>
- <span className='flex items-center gap-1'>{space.domain_type || 'Normal'}</span>
- </Tag>
- {space.vector_type ? (
- <Tag>
- <span className='flex items-center gap-1'>{space.vector_type}</span>
- </Tag>
- ) : null}
- </div>
- }
- LeftBottom={
- <div className='flex gap-2'>
- <span>{space.owner}</span>
- <span>•</span>
- {space?.gmt_modified && <span>{moment(space?.gmt_modified).fromNow() + ' ' + t('update')}</span>}
- </div>
- }
- RightBottom={
- <ChatButton
- text={t('start_chat')}
- onClick={() => {
- handleChat(space);
- }}
- />
- }
- />
- ))}
- </div>
- </div>
- <Modal
- className='h-5/6 overflow-hidden'
- open={isPanelShow}
- width={'70%'}
- onCancel={() => setIsPanelShow(false)}
- footer={null}
- destroyOnClose={true}
- >
- <DocPanel space={currentSpace!} onAddDoc={onAddDoc} onDeleteDoc={getSpaces} addStatus={addStatus} />
- </Modal>
- <Modal
- title={t('New_knowledge_base')}
- centered
- open={isAddShow}
- destroyOnClose={true}
- onCancel={() => {
- setIsAddShow(false);
- }}
- width={1000}
- afterClose={() => {
- setActiveStep(0);
- getSpaces();
- }}
- footer={null}
- >
- <Steps current={activeStep} items={addKnowledgeSteps} />
- {activeStep === 0 && <SpaceForm handleStepChange={handleStepChange} spaceConfig={spaceConfig} />}
- {activeStep === 1 && <DocTypeForm handleStepChange={handleStepChange} />}
- <DocUploadForm
- className={classNames({ hidden: activeStep !== 2 })}
- spaceName={spaceName}
- docType={docType}
- handleStepChange={handleStepChange}
- />
- {activeStep === 3 && (
- <Segmentation
- spaceName={spaceName}
- docType={docType}
- uploadFiles={files}
- handleStepChange={handleStepChange}
- />
- )}
- </Modal>
- </ConstructLayout>
- );
- };
- export default Knowledge;
|