import React, { useCallback, useState, useRef, forwardRef, useImperativeHandle, ForwardedRef } from 'react'; import { useRouter } from 'next/router'; import { Box, Flex, Button, FormControl, IconButton, Input } from '@chakra-ui/react'; import { QuestionOutlineIcon, DeleteIcon } from '@chakra-ui/icons'; import { delKbById, putKbById } from '@/api/plugins/kb'; import { useSelectFile } from '@/hooks/useSelectFile'; import { useToast } from '@/hooks/useToast'; import { useUserStore } from '@/store/user'; import { useConfirm } from '@/hooks/useConfirm'; import { UseFormReturn } from 'react-hook-form'; import { compressImg } from '@/utils/file'; import type { KbItemType } from '@/types/plugin'; import Avatar from '@/components/Avatar'; import Tag from '@/components/Tag'; import MyTooltip from '@/components/MyTooltip'; export interface ComponentRef { initInput: (tags: string) => void; } const Info = ( { kbId, form }: { kbId: string; form: UseFormReturn }, ref: ForwardedRef ) => { const { getValues, formState, setValue, register, handleSubmit } = form; const InputRef = useRef(null); const { toast } = useToast(); const router = useRouter(); const [btnLoading, setBtnLoading] = useState(false); const [refresh, setRefresh] = useState(false); const { openConfirm, ConfirmModal } = useConfirm({ content: '确认删除该知识库?数据将无法恢复,请确认!' }); const { File, onOpen: onOpenSelectFile } = useSelectFile({ fileType: '.jpg,.png', multiple: false }); const { kbDetail, getKbDetail, loadKbList, myKbList } = useUserStore(); /* 点击删除 */ const onclickDelKb = useCallback(async () => { setBtnLoading(true); try { await delKbById(kbId); toast({ title: '删除成功', status: 'success' }); router.replace(`/kb/list`); await loadKbList(); } catch (err: any) { toast({ title: err?.message || '删除失败', status: 'error' }); } setBtnLoading(false); }, [setBtnLoading, kbId, toast, router, loadKbList]); const saveSubmitSuccess = useCallback( async (data: KbItemType) => { setBtnLoading(true); try { await putKbById({ id: kbId, ...data }); await getKbDetail(kbId, true); toast({ title: '更新成功', status: 'success' }); loadKbList(); } catch (err: any) { toast({ title: err?.message || '更新失败', status: 'error' }); } setBtnLoading(false); }, [getKbDetail, kbId, loadKbList, toast] ); const saveSubmitError = useCallback(() => { // deep search message const deepSearch = (obj: any): string => { if (!obj) return '提交表单错误'; if (!!obj.message) { return obj.message; } return deepSearch(Object.values(obj)[0]); }; toast({ title: deepSearch(formState.errors), status: 'error', duration: 4000, isClosable: true }); }, [formState.errors, toast]); const onSelectFile = useCallback( async (e: File[]) => { const file = e[0]; if (!file) return; try { const src = await compressImg({ file, maxW: 100, maxH: 100 }); setValue('avatar', src); setRefresh((state) => !state); } catch (err: any) { toast({ title: typeof err === 'string' ? err : '头像选择异常', status: 'warning' }); } }, [setRefresh, setValue, toast] ); useImperativeHandle(ref, () => ({ initInput: (tags: string) => { if (InputRef.current) { InputRef.current.value = tags; } } })); return ( 知识库 ID {kbDetail._id} 索引模型 {getValues('vectorModelName')} 知识库头像 知识库名称 标签 { setValue('tags', e.target.value); setRefresh(!refresh); }} /> {getValues('tags') .split(' ') .filter((item) => item) .map((item, i) => ( {item} ))} } aria-label={''} variant={'outline'} size={'sm'} _hover={{ color: 'red.600', borderColor: 'red.600' }} onClick={openConfirm(onclickDelKb)} /> ); }; export default forwardRef(Info);