import React, { useCallback, useState, useRef } from 'react'; import { Box, TableContainer, Table, Thead, Tbody, Tr, Th, Td, IconButton, Flex, Button, useDisclosure, Menu, MenuButton, MenuList, MenuItem, Input, Tooltip } from '@chakra-ui/react'; import { QuestionOutlineIcon } from '@chakra-ui/icons'; import type { BoxProps } from '@chakra-ui/react'; import type { KbDataItemType } from '@/types/plugin'; import { usePagination } from '@/hooks/usePagination'; import { getKbDataList, getExportDataList, delOneKbDataByDataId, getTrainingData } from '@/api/plugins/kb'; import { DeleteIcon, RepeatIcon, EditIcon } from '@chakra-ui/icons'; import { useLoading } from '@/hooks/useLoading'; import { fileDownload } from '@/utils/file'; import { useMutation, useQuery } from '@tanstack/react-query'; import { useToast } from '@/hooks/useToast'; import Papa from 'papaparse'; import dynamic from 'next/dynamic'; import InputModal, { FormData as InputDataType } from './InputDataModal'; const SelectFileModal = dynamic(() => import('./SelectFileModal')); const SelectCsvModal = dynamic(() => import('./SelectCsvModal')); const DataCard = ({ kbId }: { kbId: string }) => { const lastSearch = useRef(''); const tdStyles = useRef({ fontSize: 'xs', minW: '150px', maxW: '500px', maxH: '250px', whiteSpace: 'pre-wrap', overflowY: 'auto' }); const [searchText, setSearchText] = useState(''); const { Loading, setIsLoading } = useLoading(); const { toast } = useToast(); const { data: modelDataList, isLoading, Pagination, total, getData, pageNum } = usePagination({ api: getKbDataList, pageSize: 10, params: { kbId, searchText }, defaultRequest: false }); useQuery(['getKbData', kbId], () => { getData(1); return null; }); const [editInputData, setEditInputData] = useState(); const { isOpen: isOpenSelectFileModal, onOpen: onOpenSelectFileModal, onClose: onCloseSelectFileModal } = useDisclosure(); const { isOpen: isOpenSelectCsvModal, onOpen: onOpenSelectCsvModal, onClose: onCloseSelectCsvModal } = useDisclosure(); const { data: { qaListLen = 0, vectorListLen = 0 } = {}, refetch } = useQuery( ['getModelSplitDataList', kbId], () => getTrainingData({ kbId, init: false }), { onError(err) { console.log(err); } } ); const refetchData = useCallback( (num = 1) => { getData(num); refetch(); return null; }, [getData, refetch] ); // interval get data useQuery(['refetchData'], () => refetchData(pageNum), { refetchInterval: 5000, enabled: qaListLen > 0 || vectorListLen > 0 }); // get al data and export csv const { mutate: onclickExport, isLoading: isLoadingExport = false } = useMutation({ mutationFn: () => getExportDataList(kbId), onSuccess(res) { try { setIsLoading(true); const text = Papa.unparse({ fields: ['question', 'answer'], data: res }); fileDownload({ text, type: 'text/csv', filename: 'data.csv' }); toast({ title: '导出成功,下次导出需要半小时后', status: 'success' }); } catch (error) { error; } setIsLoading(false); }, onError(err: any) { toast({ title: typeof err === 'string' ? err : err?.message || '导出异常', status: 'error' }); console.log(err); } }); return ( 知识库数据: {total}组 } aria-label={'refresh'} variant={'outline'} mr={[2, 4]} size={'sm'} onClick={() => { refetchData(pageNum); getTrainingData({ kbId, init: true }); }} /> 导入 setEditInputData({ a: '', q: '' }) } > 手动输入 文本/文件拆分 csv 问答对导入 {(qaListLen > 0 || vectorListLen > 0) && ( {qaListLen > 0 ? `${qaListLen}条数据正在拆分,` : ''} {vectorListLen > 0 ? `${vectorListLen}条数据正在生成索引,` : ''} 请耐心等待... )} setSearchText(e.target.value)} onBlur={() => { if (searchText === lastSearch.current) return; getData(1); lastSearch.current = searchText; }} onKeyDown={(e) => { if (searchText === lastSearch.current) return; if (e.key === 'Enter') { getData(1); lastSearch.current = searchText; } }} /> {modelDataList.map((item) => ( ))}
匹配的知识点 补充知识 操作
{item.q} {item.a || '-'} } variant={'outline'} aria-label={'delete'} size={'sm'} onClick={() => setEditInputData({ dataId: item.id, q: item.q, a: item.a }) } /> } variant={'outline'} colorScheme={'gray'} aria-label={'delete'} size={'sm'} onClick={async () => { await delOneKbDataByDataId(item.id); refetchData(pageNum); }} />
{editInputData !== undefined && ( setEditInputData(undefined)} onSuccess={refetchData} /> )} {isOpenSelectFileModal && ( )} {isOpenSelectCsvModal && ( )}
); }; export default DataCard;