225 lines
5.8 KiB
TypeScript
225 lines
5.8 KiB
TypeScript
|
|
|
||
|
|
import React, { useState, useEffect } from 'react';
|
||
|
|
import { useParams, useNavigate } from 'react-router-dom';
|
||
|
|
import { useForm, type UseFormReturn } from 'react-hook-form';
|
||
|
|
import {
|
||
|
|
Box,
|
||
|
|
Container,
|
||
|
|
Typography,
|
||
|
|
Paper,
|
||
|
|
Tabs,
|
||
|
|
Tab,
|
||
|
|
Fab,
|
||
|
|
Snackbar,
|
||
|
|
Alert,
|
||
|
|
} from '@mui/material';
|
||
|
|
import {
|
||
|
|
ArrowBack as ArrowBackIcon,
|
||
|
|
} from '@mui/icons-material';
|
||
|
|
import { useKnowledgeDetail, useKnowledgeOperations } from '@/hooks/knowledge-hooks';
|
||
|
|
import GeneralForm, { type BasicFormData } from './components/GeneralForm';
|
||
|
|
import ChunkMethodForm, { type ConfigFormData } from './components/ChunkMethodForm';
|
||
|
|
import KnowledgeBreadcrumbs from './components/KnowledgeBreadcrumbs';
|
||
|
|
import { useSnackbar } from '@/components/Provider/SnackbarProvider';
|
||
|
|
|
||
|
|
interface TabPanelProps {
|
||
|
|
children?: React.ReactNode;
|
||
|
|
index: number;
|
||
|
|
value: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
function TabPanel(props: TabPanelProps) {
|
||
|
|
const { children, value, index, ...other } = props;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
role="tabpanel"
|
||
|
|
hidden={value !== index}
|
||
|
|
id={`setting-tabpanel-${index}`}
|
||
|
|
aria-labelledby={`setting-tab-${index}`}
|
||
|
|
{...other}
|
||
|
|
>
|
||
|
|
{value === index && (
|
||
|
|
<Box sx={{ p: 3 }}>
|
||
|
|
{children}
|
||
|
|
</Box>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
function a11yProps(index: number) {
|
||
|
|
return {
|
||
|
|
id: `setting-tab-${index}`,
|
||
|
|
'aria-controls': `setting-tabpanel-${index}`,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
function KnowledgeBaseSetting() {
|
||
|
|
const { id } = useParams<{ id: string }>();
|
||
|
|
const navigate = useNavigate();
|
||
|
|
const [tabValue, setTabValue] = useState(0);
|
||
|
|
|
||
|
|
// 获取知识库详情
|
||
|
|
const { knowledge, loading: detailLoading, refresh } = useKnowledgeDetail(id || '');
|
||
|
|
const { showMessage } = useSnackbar();
|
||
|
|
|
||
|
|
// 知识库操作hooks
|
||
|
|
const {
|
||
|
|
updateKnowledgeBasicInfo,
|
||
|
|
updateKnowledgeModelConfig,
|
||
|
|
loading: operationLoading
|
||
|
|
} = useKnowledgeOperations();
|
||
|
|
|
||
|
|
// 基础信息表单
|
||
|
|
const basicForm = useForm<BasicFormData>({
|
||
|
|
defaultValues: {
|
||
|
|
name: '',
|
||
|
|
description: '',
|
||
|
|
permission: 'me',
|
||
|
|
avatar: undefined,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
// 解析配置表单
|
||
|
|
const configForm = useForm<ConfigFormData>({
|
||
|
|
defaultValues: {
|
||
|
|
parser_id: 'naive',
|
||
|
|
chunk_token_count: 512,
|
||
|
|
layout_recognize: false,
|
||
|
|
task_page_size: 0,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
// 当知识库数据加载完成时,更新表单默认值
|
||
|
|
useEffect(() => {
|
||
|
|
if (knowledge) {
|
||
|
|
basicForm.reset({
|
||
|
|
name: knowledge.name || '',
|
||
|
|
description: knowledge.description || '',
|
||
|
|
permission: knowledge.permission || 'me',
|
||
|
|
avatar: knowledge.avatar,
|
||
|
|
});
|
||
|
|
|
||
|
|
configForm.reset({
|
||
|
|
// parser_id: knowledge.parser_id || 'naive',
|
||
|
|
// chunk_token_count: knowledge.chunk_token_count || 512,
|
||
|
|
// layout_recognize: knowledge.layout_recognize || false,
|
||
|
|
// task_page_size: knowledge.task_page_size || 0,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}, [knowledge, basicForm, configForm]);
|
||
|
|
|
||
|
|
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
|
||
|
|
setTabValue(newValue);
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleBasicInfoSubmit = async (data: BasicFormData) => {
|
||
|
|
if (!knowledge) return;
|
||
|
|
|
||
|
|
try {
|
||
|
|
const kb = {
|
||
|
|
...data,
|
||
|
|
// parser_id: knowledge.parser_id,
|
||
|
|
kb_id: knowledge.id,
|
||
|
|
} as any;
|
||
|
|
|
||
|
|
await updateKnowledgeBasicInfo(kb);
|
||
|
|
showMessage.success('基础信息更新成功');
|
||
|
|
// 刷新知识库详情
|
||
|
|
refresh();
|
||
|
|
} catch (error) {
|
||
|
|
// showMessage.error('基础信息更新失败');
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleConfigSubmit = async (data: ConfigFormData) => {
|
||
|
|
if (!id) return;
|
||
|
|
|
||
|
|
try {
|
||
|
|
await updateKnowledgeModelConfig({
|
||
|
|
id,
|
||
|
|
parser_id: data.parser_id,
|
||
|
|
// 可以根据需要添加更多配置字段
|
||
|
|
});
|
||
|
|
showMessage.success('解析配置更新成功');
|
||
|
|
// 刷新知识库详情
|
||
|
|
refresh();
|
||
|
|
} catch (error) {
|
||
|
|
// showMessage.error('解析配置更新失败');
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleBackToDetail = () => {
|
||
|
|
navigate(`/knowledge/${id}`);
|
||
|
|
};
|
||
|
|
|
||
|
|
if (detailLoading) {
|
||
|
|
return (
|
||
|
|
<Container maxWidth="lg" sx={{ py: 4 }}>
|
||
|
|
<Typography>加载中...</Typography>
|
||
|
|
</Container>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Container maxWidth="lg" sx={{ py: 4 }}>
|
||
|
|
{/* 面包屑导航 */}
|
||
|
|
<KnowledgeBreadcrumbs knowledge={knowledge} />
|
||
|
|
|
||
|
|
<Box sx={{ mb: 3 }}>
|
||
|
|
<Typography variant="h4" gutterBottom>
|
||
|
|
知识库设置
|
||
|
|
</Typography>
|
||
|
|
<Typography variant="subtitle1" color="text.secondary">
|
||
|
|
{knowledge?.name}
|
||
|
|
</Typography>
|
||
|
|
</Box>
|
||
|
|
|
||
|
|
<Paper sx={{ width: '100%' }}>
|
||
|
|
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||
|
|
<Tabs value={tabValue} onChange={handleTabChange} aria-label="设置选项卡">
|
||
|
|
<Tab label="基础信息" {...a11yProps(0)} />
|
||
|
|
<Tab label="解析配置" {...a11yProps(1)} />
|
||
|
|
</Tabs>
|
||
|
|
</Box>
|
||
|
|
|
||
|
|
<TabPanel value={tabValue} index={0}>
|
||
|
|
<GeneralForm
|
||
|
|
form={basicForm}
|
||
|
|
onSubmit={handleBasicInfoSubmit}
|
||
|
|
isSubmitting={operationLoading}
|
||
|
|
submitButtonText="保存基础信息"
|
||
|
|
disabled={detailLoading}
|
||
|
|
/>
|
||
|
|
</TabPanel>
|
||
|
|
|
||
|
|
<TabPanel value={tabValue} index={1}>
|
||
|
|
<ChunkMethodForm
|
||
|
|
form={configForm as any}
|
||
|
|
onSubmit={handleConfigSubmit}
|
||
|
|
isSubmitting={operationLoading}
|
||
|
|
submitButtonText="保存解析配置"
|
||
|
|
disabled={detailLoading}
|
||
|
|
/>
|
||
|
|
</TabPanel>
|
||
|
|
</Paper>
|
||
|
|
|
||
|
|
{/* 返回按钮 */}
|
||
|
|
<Fab
|
||
|
|
color="primary"
|
||
|
|
aria-label="返回知识库详情"
|
||
|
|
onClick={handleBackToDetail}
|
||
|
|
sx={{
|
||
|
|
position: 'fixed',
|
||
|
|
bottom: 128,
|
||
|
|
right: 64,
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
<ArrowBackIcon />
|
||
|
|
</Fab>
|
||
|
|
</Container>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export default KnowledgeBaseSetting;
|