feat(form): add form field components and configuration updates
refactor(knowledge): restructure configuration components to use common items
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -24,4 +24,5 @@ dist-ssr
|
|||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
# rag core
|
# rag core
|
||||||
rag_web_core
|
rag_web_core_v0.20.5
|
||||||
|
rag_web_core_deprecated
|
||||||
@@ -19,6 +19,5 @@ export default defineConfig([
|
|||||||
ecmaVersion: 2020,
|
ecmaVersion: 2020,
|
||||||
globals: globals.browser,
|
globals: globals.browser,
|
||||||
},
|
},
|
||||||
ignores: ['rag_web_core/**'],
|
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"@mui/icons-material": "^7.3.4",
|
"@mui/icons-material": "^7.3.4",
|
||||||
"@mui/material": "^7.3.4",
|
"@mui/material": "^7.3.4",
|
||||||
"@mui/x-data-grid": "^8.14.0",
|
"@mui/x-data-grid": "^8.14.0",
|
||||||
|
"@mui/x-date-pickers": "^8.14.0",
|
||||||
"ahooks": "^3.9.5",
|
"ahooks": "^3.9.5",
|
||||||
"axios": "^1.12.2",
|
"axios": "^1.12.2",
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.18",
|
||||||
|
|||||||
60
pnpm-lock.yaml
generated
60
pnpm-lock.yaml
generated
@@ -23,6 +23,9 @@ importers:
|
|||||||
'@mui/x-data-grid':
|
'@mui/x-data-grid':
|
||||||
specifier: ^8.14.0
|
specifier: ^8.14.0
|
||||||
version: 8.14.0(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@mui/material@7.3.4(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@7.3.3(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 8.14.0(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@mui/material@7.3.4(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@7.3.3(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@mui/x-date-pickers':
|
||||||
|
specifier: ^8.14.0
|
||||||
|
version: 8.14.0(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@mui/material@7.3.4(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@7.3.3(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(dayjs@1.11.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
ahooks:
|
ahooks:
|
||||||
specifier: ^3.9.5
|
specifier: ^3.9.5
|
||||||
version: 3.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 3.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@@ -588,6 +591,43 @@ packages:
|
|||||||
'@emotion/styled':
|
'@emotion/styled':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@mui/x-date-pickers@8.14.0':
|
||||||
|
resolution: {integrity: sha512-fz8z1hoi1tbG1QUcZAkQdiO3GsCOpUeRfyANXDDzDN88L4VqwNEyrv0wmzmCfIX2sgur4gWwWJzMuCvauMgXRw==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@emotion/react': ^11.9.0
|
||||||
|
'@emotion/styled': ^11.8.1
|
||||||
|
'@mui/material': ^5.15.14 || ^6.0.0 || ^7.0.0
|
||||||
|
'@mui/system': ^5.15.14 || ^6.0.0 || ^7.0.0
|
||||||
|
date-fns: ^2.25.0 || ^3.2.0 || ^4.0.0
|
||||||
|
date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0
|
||||||
|
dayjs: ^1.10.7
|
||||||
|
luxon: ^3.0.2
|
||||||
|
moment: ^2.29.4
|
||||||
|
moment-hijri: ^2.1.2 || ^3.0.0
|
||||||
|
moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0
|
||||||
|
react: ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@emotion/react':
|
||||||
|
optional: true
|
||||||
|
'@emotion/styled':
|
||||||
|
optional: true
|
||||||
|
date-fns:
|
||||||
|
optional: true
|
||||||
|
date-fns-jalali:
|
||||||
|
optional: true
|
||||||
|
dayjs:
|
||||||
|
optional: true
|
||||||
|
luxon:
|
||||||
|
optional: true
|
||||||
|
moment:
|
||||||
|
optional: true
|
||||||
|
moment-hijri:
|
||||||
|
optional: true
|
||||||
|
moment-jalaali:
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@mui/x-internals@8.14.0':
|
'@mui/x-internals@8.14.0':
|
||||||
resolution: {integrity: sha512-esYyl61nuuFXiN631TWuPh2tqdoyTdBI/4UXgwH3rytF8jiWvy6prPBPRHEH1nvW3fgw9FoBI48FlOO+yEI8xg==}
|
resolution: {integrity: sha512-esYyl61nuuFXiN631TWuPh2tqdoyTdBI/4UXgwH3rytF8jiWvy6prPBPRHEH1nvW3fgw9FoBI48FlOO+yEI8xg==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
@@ -2175,6 +2215,26 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/react'
|
- '@types/react'
|
||||||
|
|
||||||
|
'@mui/x-date-pickers@8.14.0(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@mui/material@7.3.4(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@7.3.3(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(dayjs@1.11.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.28.4
|
||||||
|
'@mui/material': 7.3.4(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
'@mui/system': 7.3.3(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1)
|
||||||
|
'@mui/utils': 7.3.3(@types/react@19.2.2)(react@18.3.1)
|
||||||
|
'@mui/x-internals': 8.14.0(@types/react@19.2.2)(react@18.3.1)
|
||||||
|
'@types/react-transition-group': 4.4.12(@types/react@19.2.2)
|
||||||
|
clsx: 2.1.1
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
|
optionalDependencies:
|
||||||
|
'@emotion/react': 11.14.0(@types/react@19.2.2)(react@18.3.1)
|
||||||
|
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.2)(react@18.3.1))(@types/react@19.2.2)(react@18.3.1)
|
||||||
|
dayjs: 1.11.18
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/react'
|
||||||
|
|
||||||
'@mui/x-internals@8.14.0(@types/react@19.2.2)(react@18.3.1)':
|
'@mui/x-internals@8.14.0(@types/react@19.2.2)(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.28.4
|
'@babel/runtime': 7.28.4
|
||||||
|
|||||||
74
src/components/FormField/CheckboxFormField.tsx
Normal file
74
src/components/FormField/CheckboxFormField.tsx
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Checkbox, FormControlLabel, FormControl, FormHelperText, Box, Typography } from '@mui/material';
|
||||||
|
import { useFormContext, Controller } from 'react-hook-form';
|
||||||
|
import { type IFormLayoutType } from './index';
|
||||||
|
|
||||||
|
export interface CheckboxFormFieldProps extends IFormLayoutType {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
defaultValue?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
helperText?: string;
|
||||||
|
color?: 'primary' | 'secondary' | 'default';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CheckboxFormField({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
defaultValue = false,
|
||||||
|
required = false,
|
||||||
|
disabled = false,
|
||||||
|
layout = 'vertical',
|
||||||
|
helperText,
|
||||||
|
color = 'primary',
|
||||||
|
}: CheckboxFormFieldProps) {
|
||||||
|
const { control, formState: { errors } } = useFormContext();
|
||||||
|
const error = errors[name];
|
||||||
|
const isHorizontal = layout === 'horizontal';
|
||||||
|
|
||||||
|
const checkbox = (
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormControl error={!!error} disabled={disabled}>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Checkbox
|
||||||
|
{...field}
|
||||||
|
checked={field.value || false}
|
||||||
|
onChange={(e) => field.onChange(e.target.checked)}
|
||||||
|
color={color}
|
||||||
|
required={required}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={isHorizontal ? undefined : label}
|
||||||
|
/>
|
||||||
|
{(error?.message || helperText) && (
|
||||||
|
<FormHelperText>
|
||||||
|
{error?.message as string || helperText}
|
||||||
|
</FormHelperText>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isHorizontal) {
|
||||||
|
return (
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<Typography variant="subtitle1" sx={{ minWidth: 120, pt: 1 }}>
|
||||||
|
{label}
|
||||||
|
{required && <span style={{ color: 'red' }}>*</span>}
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ flex: 1 }}>
|
||||||
|
{checkbox}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkbox;
|
||||||
|
}
|
||||||
140
src/components/FormField/ChipListFormField.tsx
Normal file
140
src/components/FormField/ChipListFormField.tsx
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
Chip,
|
||||||
|
IconButton,
|
||||||
|
TextField,
|
||||||
|
FormHelperText,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Add as AddIcon } from '@mui/icons-material';
|
||||||
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
|
export interface ChipListFormFieldProps {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
helperText?: string;
|
||||||
|
defaultValue?: string[];
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
allowAdd?: boolean;
|
||||||
|
allowDelete?: boolean;
|
||||||
|
maxChips?: number;
|
||||||
|
placeholder?: string;
|
||||||
|
chipColor?: 'default' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';
|
||||||
|
chipVariant?: 'filled' | 'outlined';
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ChipListFormField: React.FC<ChipListFormFieldProps> = ({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
helperText,
|
||||||
|
defaultValue = [],
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
allowAdd = true,
|
||||||
|
allowDelete = true,
|
||||||
|
maxChips,
|
||||||
|
placeholder = '输入后按回车添加',
|
||||||
|
chipColor = 'default',
|
||||||
|
chipVariant = 'outlined',
|
||||||
|
}) => {
|
||||||
|
const { control, setValue, getValues } = useFormContext();
|
||||||
|
const [inputValue, setInputValue] = useState('');
|
||||||
|
|
||||||
|
const handleAddChip = (field: any) => {
|
||||||
|
if (inputValue.trim() && (!maxChips || field.value.length < maxChips)) {
|
||||||
|
const newChips = [...field.value, inputValue.trim()];
|
||||||
|
field.onChange(newChips);
|
||||||
|
setInputValue('');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDeleteChip = (field: any, chipToDelete: string) => {
|
||||||
|
if (allowDelete) {
|
||||||
|
const newChips = field.value.filter((chip: string) => chip !== chipToDelete);
|
||||||
|
field.onChange(newChips);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleKeyPress = (event: React.KeyboardEvent, field: any) => {
|
||||||
|
if (event.key === 'Enter') {
|
||||||
|
event.preventDefault();
|
||||||
|
handleAddChip(field);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="subtitle1" gutterBottom>
|
||||||
|
{required && <span style={{ color: 'red' }}>*</span>}
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
rules={{
|
||||||
|
required: required ? `${label}是必填项` : false,
|
||||||
|
validate: (value) => {
|
||||||
|
if (maxChips && value.length > maxChips) {
|
||||||
|
return `${label}最多只能有${maxChips}个标签`;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<Box>
|
||||||
|
{/* 标签显示区域 */}
|
||||||
|
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mb: 2, minHeight: '40px' }}>
|
||||||
|
{field.value.map((chip: string, index: number) => (
|
||||||
|
<Chip
|
||||||
|
key={index}
|
||||||
|
label={chip}
|
||||||
|
onDelete={allowDelete && !disabled ? () => handleDeleteChip(field, chip) : undefined}
|
||||||
|
variant={chipVariant}
|
||||||
|
color={chipColor}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{field.value.length === 0 && (
|
||||||
|
<Typography variant="body2" color="text.secondary" sx={{ py: 1 }}>
|
||||||
|
暂无标签
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 添加标签输入框 */}
|
||||||
|
{allowAdd && !disabled && (!maxChips || field.value.length < maxChips) && (
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<TextField
|
||||||
|
value={inputValue}
|
||||||
|
onChange={(e) => setInputValue(e.target.value)}
|
||||||
|
onKeyPress={(e) => handleKeyPress(e, field)}
|
||||||
|
placeholder={placeholder}
|
||||||
|
size="small"
|
||||||
|
fullWidth
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => handleAddChip(field)}
|
||||||
|
disabled={!inputValue.trim() || disabled}
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<AddIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 错误信息和帮助文本 */}
|
||||||
|
{(error || helperText) && (
|
||||||
|
<FormHelperText error={!!error}>
|
||||||
|
{error?.message || helperText}
|
||||||
|
</FormHelperText>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
64
src/components/FormField/DatePickerFormField.tsx
Normal file
64
src/components/FormField/DatePickerFormField.tsx
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Box, Typography } from '@mui/material';
|
||||||
|
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
||||||
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
||||||
|
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||||
|
import { useFormContext, Controller } from 'react-hook-form';
|
||||||
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
|
export interface DatePickerFormFieldProps {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
defaultValue?: string | Date | Dayjs | null;
|
||||||
|
required?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
helperText?: string;
|
||||||
|
minDate?: string | Date | Dayjs;
|
||||||
|
maxDate?: string | Date | Dayjs;
|
||||||
|
format?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DatePickerFormField({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
defaultValue = null,
|
||||||
|
required = false,
|
||||||
|
disabled = false,
|
||||||
|
helperText,
|
||||||
|
minDate,
|
||||||
|
maxDate,
|
||||||
|
format = 'YYYY-MM-DD',
|
||||||
|
}: DatePickerFormFieldProps) {
|
||||||
|
const { control, formState: { errors } } = useFormContext();
|
||||||
|
const error = errors[name];
|
||||||
|
|
||||||
|
const datePicker = (
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue ? dayjs(defaultValue) : null}
|
||||||
|
render={({ field }) => (
|
||||||
|
<DatePicker
|
||||||
|
{...field}
|
||||||
|
disabled={disabled}
|
||||||
|
minDate={minDate ? dayjs(minDate) : undefined}
|
||||||
|
maxDate={maxDate ? dayjs(maxDate) : undefined}
|
||||||
|
format={format}
|
||||||
|
slotProps={{
|
||||||
|
textField: {
|
||||||
|
required,
|
||||||
|
error: !!error,
|
||||||
|
helperText: error?.message as string || helperText,
|
||||||
|
fullWidth: true,
|
||||||
|
variant: 'outlined',
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
return datePicker;
|
||||||
|
}
|
||||||
80
src/components/FormField/MultilineTextFormField.tsx
Normal file
80
src/components/FormField/MultilineTextFormField.tsx
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
TextField,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
|
export interface MultilineTextFormFieldProps {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
helperText?: string;
|
||||||
|
defaultValue?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
fullWidth?: boolean;
|
||||||
|
rows?: number;
|
||||||
|
maxRows?: number;
|
||||||
|
minRows?: number;
|
||||||
|
placeholder?: string;
|
||||||
|
size?: 'small' | 'medium';
|
||||||
|
maxLength?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MultilineTextFormField: React.FC<MultilineTextFormFieldProps> = ({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
helperText,
|
||||||
|
defaultValue = '',
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
fullWidth = true,
|
||||||
|
rows = 4,
|
||||||
|
maxRows,
|
||||||
|
minRows,
|
||||||
|
placeholder,
|
||||||
|
size = 'medium',
|
||||||
|
maxLength,
|
||||||
|
}) => {
|
||||||
|
const { control } = useFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="subtitle1" gutterBottom>
|
||||||
|
{required && <span style={{ color: 'red' }}>*</span>}
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
rules={{
|
||||||
|
required: required ? `${label}是必填项` : false,
|
||||||
|
maxLength: maxLength ? {
|
||||||
|
value: maxLength,
|
||||||
|
message: `${label}不能超过${maxLength}个字符`
|
||||||
|
} : undefined,
|
||||||
|
}}
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
multiline
|
||||||
|
rows={rows}
|
||||||
|
maxRows={maxRows}
|
||||||
|
minRows={minRows}
|
||||||
|
fullWidth={fullWidth}
|
||||||
|
disabled={disabled}
|
||||||
|
placeholder={placeholder}
|
||||||
|
size={size}
|
||||||
|
error={!!error}
|
||||||
|
helperText={error?.message || helperText}
|
||||||
|
inputProps={{
|
||||||
|
maxLength: maxLength,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
112
src/components/FormField/NumberInputFormField.tsx
Normal file
112
src/components/FormField/NumberInputFormField.tsx
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
TextField,
|
||||||
|
IconButton,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Add as AddIcon } from '@mui/icons-material';
|
||||||
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
|
export interface NumberInputFormFieldProps {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
helperText?: string;
|
||||||
|
defaultValue?: number;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
fullWidth?: boolean;
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
step?: number;
|
||||||
|
placeholder?: string;
|
||||||
|
size?: 'small' | 'medium';
|
||||||
|
showRandomButton?: boolean;
|
||||||
|
onRandomClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NumberInputFormField: React.FC<NumberInputFormFieldProps> = ({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
helperText,
|
||||||
|
defaultValue = 0,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
fullWidth = true,
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
step,
|
||||||
|
placeholder,
|
||||||
|
size = 'medium',
|
||||||
|
showRandomButton = false,
|
||||||
|
onRandomClick,
|
||||||
|
}) => {
|
||||||
|
const { control } = useFormContext();
|
||||||
|
|
||||||
|
const handleRandomClick = () => {
|
||||||
|
if (onRandomClick) {
|
||||||
|
onRandomClick();
|
||||||
|
} else if (min !== undefined && max !== undefined) {
|
||||||
|
const randomValue = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
// 这里需要通过setValue来更新表单值,但为了保持组件的纯净性,
|
||||||
|
// 建议通过onRandomClick回调来处理
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="subtitle1" gutterBottom>
|
||||||
|
{required && <span style={{ color: 'red' }}>*</span>}
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
rules={{
|
||||||
|
required: required ? `${label}是必填项` : false,
|
||||||
|
min: min !== undefined ? {
|
||||||
|
value: min,
|
||||||
|
message: `${label}不能小于${min}`
|
||||||
|
} : undefined,
|
||||||
|
max: max !== undefined ? {
|
||||||
|
value: max,
|
||||||
|
message: `${label}不能大于${max}`
|
||||||
|
} : undefined,
|
||||||
|
}}
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
type="number"
|
||||||
|
fullWidth={fullWidth}
|
||||||
|
disabled={disabled}
|
||||||
|
placeholder={placeholder}
|
||||||
|
size={size}
|
||||||
|
error={!!error}
|
||||||
|
helperText={error?.message || helperText}
|
||||||
|
inputProps={{
|
||||||
|
min,
|
||||||
|
max,
|
||||||
|
step,
|
||||||
|
}}
|
||||||
|
onChange={(e) => {
|
||||||
|
const value = e.target.value === '' ? '' : Number(e.target.value);
|
||||||
|
field.onChange(value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{showRandomButton && (
|
||||||
|
<IconButton
|
||||||
|
onClick={handleRandomClick}
|
||||||
|
disabled={disabled}
|
||||||
|
size={size}
|
||||||
|
>
|
||||||
|
<AddIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
96
src/components/FormField/SelectFormField.tsx
Normal file
96
src/components/FormField/SelectFormField.tsx
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
FormControl,
|
||||||
|
Select,
|
||||||
|
MenuItem,
|
||||||
|
FormHelperText,
|
||||||
|
InputLabel,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
|
export interface SelectOption {
|
||||||
|
value: string | number;
|
||||||
|
label: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SelectFormFieldProps {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
options: SelectOption[];
|
||||||
|
helperText?: string;
|
||||||
|
defaultValue?: string | number;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
fullWidth?: boolean;
|
||||||
|
size?: 'small' | 'medium';
|
||||||
|
displayEmpty?: boolean;
|
||||||
|
emptyLabel?: string;
|
||||||
|
multiple?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SelectFormField: React.FC<SelectFormFieldProps> = ({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
options,
|
||||||
|
helperText,
|
||||||
|
defaultValue = '',
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
fullWidth = true,
|
||||||
|
size = 'medium',
|
||||||
|
displayEmpty = true,
|
||||||
|
emptyLabel = '请选择',
|
||||||
|
multiple = false,
|
||||||
|
}) => {
|
||||||
|
const { control } = useFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="subtitle1" gutterBottom>
|
||||||
|
{required && <span style={{ color: 'red' }}>*</span>}
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={multiple ? [] : defaultValue}
|
||||||
|
rules={{
|
||||||
|
required: required ? `${label}是必填项` : false,
|
||||||
|
}}
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl fullWidth={fullWidth} error={!!error} size={size}>
|
||||||
|
<Select
|
||||||
|
{...field}
|
||||||
|
disabled={disabled}
|
||||||
|
displayEmpty={displayEmpty}
|
||||||
|
multiple={multiple}
|
||||||
|
>
|
||||||
|
{displayEmpty && !multiple && (
|
||||||
|
<MenuItem value="">
|
||||||
|
{emptyLabel}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
{options.map((option) => (
|
||||||
|
<MenuItem
|
||||||
|
key={option.value}
|
||||||
|
value={option.value}
|
||||||
|
disabled={option.disabled}
|
||||||
|
>
|
||||||
|
{option.label}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
{(error || helperText) && (
|
||||||
|
<FormHelperText>
|
||||||
|
{error?.message || helperText}
|
||||||
|
</FormHelperText>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
86
src/components/FormField/SliderFormField.tsx
Normal file
86
src/components/FormField/SliderFormField.tsx
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Box, Typography, Slider } from '@mui/material';
|
||||||
|
import { useController, useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
|
export interface SliderFormFieldProps {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
step?: number;
|
||||||
|
defaultValue?: number;
|
||||||
|
valueLabelDisplay?: 'on' | 'auto' | 'off';
|
||||||
|
marks?: boolean | Array<{ value: number; label?: string }>;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
sx?: object;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SliderFormField: React.FC<SliderFormFieldProps> = ({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
min = 0,
|
||||||
|
max = 100,
|
||||||
|
step = 1,
|
||||||
|
defaultValue = 0,
|
||||||
|
valueLabelDisplay = 'on',
|
||||||
|
marks = false,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
sx = {},
|
||||||
|
}) => {
|
||||||
|
const { control } = useFormContext();
|
||||||
|
|
||||||
|
const {
|
||||||
|
field,
|
||||||
|
fieldState: { error },
|
||||||
|
} = useController({
|
||||||
|
name,
|
||||||
|
control,
|
||||||
|
defaultValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ mb: 2, ...sx }}>
|
||||||
|
<Typography
|
||||||
|
variant="subtitle1"
|
||||||
|
gutterBottom
|
||||||
|
sx={{
|
||||||
|
color: error ? 'error.main' : 'inherit',
|
||||||
|
fontWeight: required ? 600 : 400,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
{required && <span style={{ color: 'red' }}> *</span>}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box sx={{ px: 2 }}>
|
||||||
|
<Slider
|
||||||
|
{...field}
|
||||||
|
min={min}
|
||||||
|
max={max}
|
||||||
|
step={step}
|
||||||
|
valueLabelDisplay={valueLabelDisplay}
|
||||||
|
marks={marks}
|
||||||
|
disabled={disabled}
|
||||||
|
onChange={(_, value) => field.onChange(value)}
|
||||||
|
sx={{
|
||||||
|
color: error ? 'error.main' : 'primary.main',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<Typography
|
||||||
|
variant="caption"
|
||||||
|
color="error"
|
||||||
|
sx={{ mt: 0.5, display: 'block' }}
|
||||||
|
>
|
||||||
|
{error.message}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SliderFormField;
|
||||||
105
src/components/FormField/SliderInputFormField.tsx
Normal file
105
src/components/FormField/SliderInputFormField.tsx
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import {
|
||||||
|
FormControl,
|
||||||
|
FormHelperText,
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
Slider,
|
||||||
|
TextField,
|
||||||
|
Grid,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { useFormContext, Controller } from 'react-hook-form';
|
||||||
|
import { type ReactNode } from 'react';
|
||||||
|
import type { IFormLayoutType } from '.';
|
||||||
|
|
||||||
|
export type SliderInputFormFieldProps = {
|
||||||
|
max?: number;
|
||||||
|
min?: number;
|
||||||
|
step?: number;
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
tooltip?: ReactNode;
|
||||||
|
defaultValue?: number;
|
||||||
|
className?: string;
|
||||||
|
} & IFormLayoutType;
|
||||||
|
|
||||||
|
export function SliderInputFormField({
|
||||||
|
max = 100,
|
||||||
|
min = 0,
|
||||||
|
step = 1,
|
||||||
|
label,
|
||||||
|
name,
|
||||||
|
tooltip,
|
||||||
|
defaultValue = 0,
|
||||||
|
className,
|
||||||
|
layout = 'horizontal',
|
||||||
|
}: SliderInputFormFieldProps) {
|
||||||
|
const { control, formState: { errors } } = useFormContext();
|
||||||
|
|
||||||
|
const isHorizontal = layout === 'horizontal';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ mb: 3 }} className={className}>
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Box>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
gutterBottom={!isHorizontal}
|
||||||
|
sx={{
|
||||||
|
mb: isHorizontal ? 1 : 2,
|
||||||
|
fontSize: isHorizontal ? '0.875rem' : '1.25rem',
|
||||||
|
color: isHorizontal ? 'text.secondary' : 'text.primary'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
{tooltip && (
|
||||||
|
<Typography
|
||||||
|
component="span"
|
||||||
|
variant="caption"
|
||||||
|
sx={{ ml: 1, color: 'text.secondary' }}
|
||||||
|
>
|
||||||
|
{tooltip}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Grid container spacing={2} alignItems="center">
|
||||||
|
<Grid size={{xs: isHorizontal ? 8 : 9}}>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<Slider
|
||||||
|
{...field}
|
||||||
|
min={min}
|
||||||
|
max={max}
|
||||||
|
step={step}
|
||||||
|
valueLabelDisplay="auto"
|
||||||
|
sx={{ mt: 1 }}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
<Grid size={{xs: isHorizontal ? 4 : 3}}>
|
||||||
|
<FormControl>
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
type="number"
|
||||||
|
size="small"
|
||||||
|
inputProps={{ min, max, step }}
|
||||||
|
sx={{ width: '80px' }}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{errors[name] && (
|
||||||
|
<FormHelperText error sx={{ mt: 1 }}>
|
||||||
|
{errors[name]?.message as string}
|
||||||
|
</FormHelperText>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
72
src/components/FormField/SwitchFormField.tsx
Normal file
72
src/components/FormField/SwitchFormField.tsx
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
FormControlLabel,
|
||||||
|
Switch,
|
||||||
|
FormHelperText,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
|
|
||||||
|
export interface SwitchFormFieldProps {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
helperText?: string;
|
||||||
|
defaultValue?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
required?: boolean;
|
||||||
|
size?: 'small' | 'medium';
|
||||||
|
color?: 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning';
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SwitchFormField: React.FC<SwitchFormFieldProps> = ({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
helperText,
|
||||||
|
defaultValue = false,
|
||||||
|
disabled = false,
|
||||||
|
required = false,
|
||||||
|
size = 'medium',
|
||||||
|
color = 'primary',
|
||||||
|
}) => {
|
||||||
|
const { control } = useFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
rules={{
|
||||||
|
required: required ? `${label}是必填项` : false,
|
||||||
|
}}
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={field.value || false}
|
||||||
|
onChange={field.onChange}
|
||||||
|
disabled={disabled}
|
||||||
|
size={size}
|
||||||
|
color={color}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
<Typography variant="body1">
|
||||||
|
{required && <span style={{ color: 'red' }}>*</span>}
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{(error || helperText) && (
|
||||||
|
<FormHelperText error={!!error}>
|
||||||
|
{error?.message || helperText}
|
||||||
|
</FormHelperText>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
69
src/components/FormField/TextFormField.tsx
Normal file
69
src/components/FormField/TextFormField.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { TextField, Box, Typography } from '@mui/material';
|
||||||
|
import { useFormContext, Controller } from 'react-hook-form';
|
||||||
|
import { type IFormLayoutType } from './index';
|
||||||
|
|
||||||
|
export interface TextFormFieldProps extends IFormLayoutType {
|
||||||
|
name: string;
|
||||||
|
label: string;
|
||||||
|
placeholder?: string;
|
||||||
|
defaultValue?: string;
|
||||||
|
required?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
helperText?: string;
|
||||||
|
type?: 'text' | 'email' | 'password' | 'url' | 'tel';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TextFormField({
|
||||||
|
name,
|
||||||
|
label,
|
||||||
|
placeholder,
|
||||||
|
defaultValue = '',
|
||||||
|
required = false,
|
||||||
|
disabled = false,
|
||||||
|
layout = 'vertical',
|
||||||
|
helperText,
|
||||||
|
type = 'text',
|
||||||
|
}: TextFormFieldProps) {
|
||||||
|
const { control, formState: { errors } } = useFormContext();
|
||||||
|
const error = errors[name];
|
||||||
|
const isHorizontal = layout === 'horizontal';
|
||||||
|
|
||||||
|
const textField = (
|
||||||
|
<Controller
|
||||||
|
name={name}
|
||||||
|
control={control}
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
render={({ field }) => (
|
||||||
|
<TextField
|
||||||
|
{...field}
|
||||||
|
type={type}
|
||||||
|
label={isHorizontal ? undefined : label}
|
||||||
|
placeholder={placeholder}
|
||||||
|
required={required}
|
||||||
|
disabled={disabled}
|
||||||
|
error={!!error}
|
||||||
|
helperText={error?.message as string || helperText}
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isHorizontal) {
|
||||||
|
return (
|
||||||
|
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Typography variant="subtitle1" sx={{ minWidth: 120, pt: 1 }}>
|
||||||
|
{label}
|
||||||
|
{required && <span style={{ color: 'red' }}>*</span>}
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ flex: 1 }}>
|
||||||
|
{textField}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return textField;
|
||||||
|
}
|
||||||
35
src/components/FormField/index.ts
Normal file
35
src/components/FormField/index.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// 基础组件导出
|
||||||
|
export { SliderInputFormField } from './SliderInputFormField';
|
||||||
|
export { SwitchFormField } from './SwitchFormField';
|
||||||
|
export { SelectFormField } from './SelectFormField';
|
||||||
|
export { MultilineTextFormField } from './MultilineTextFormField';
|
||||||
|
export { NumberInputFormField } from './NumberInputFormField';
|
||||||
|
export { ChipListFormField } from './ChipListFormField';
|
||||||
|
export { SliderFormField } from './SliderFormField';
|
||||||
|
export { TextFormField } from './TextFormField';
|
||||||
|
export { DatePickerFormField } from './DatePickerFormField';
|
||||||
|
export { CheckboxFormField } from './CheckboxFormField';
|
||||||
|
|
||||||
|
// 类型导出
|
||||||
|
export type { SliderInputFormFieldProps } from './SliderInputFormField';
|
||||||
|
export type { SwitchFormFieldProps } from './SwitchFormField';
|
||||||
|
export type { SelectFormFieldProps, SelectOption } from './SelectFormField';
|
||||||
|
export type { MultilineTextFormFieldProps } from './MultilineTextFormField';
|
||||||
|
export type { NumberInputFormFieldProps } from './NumberInputFormField';
|
||||||
|
export type { ChipListFormFieldProps } from './ChipListFormField';
|
||||||
|
export type { SliderFormFieldProps } from './SliderFormField';
|
||||||
|
export type { TextFormFieldProps } from './TextFormField';
|
||||||
|
export type { DatePickerFormFieldProps } from './DatePickerFormField';
|
||||||
|
export type { CheckboxFormFieldProps } from './CheckboxFormField';
|
||||||
|
|
||||||
|
export type IFormLayoutType = {
|
||||||
|
layout?: FormLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FORM_LAYOUTS = {
|
||||||
|
Vertical: 'vertical',
|
||||||
|
Horizontal: 'horizontal',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type FormLayout = (typeof FORM_LAYOUTS)[keyof typeof FORM_LAYOUTS];
|
||||||
|
|
||||||
163
src/pages/FormFieldTest.tsx
Normal file
163
src/pages/FormFieldTest.tsx
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Box, Typography, Paper, Divider } from '@mui/material';
|
||||||
|
import { useForm, FormProvider } from 'react-hook-form';
|
||||||
|
import {
|
||||||
|
SliderInputFormField,
|
||||||
|
SwitchFormField,
|
||||||
|
SelectFormField,
|
||||||
|
MultilineTextFormField,
|
||||||
|
NumberInputFormField,
|
||||||
|
ChipListFormField,
|
||||||
|
type SelectOption,
|
||||||
|
} from '@/components/FormField';
|
||||||
|
|
||||||
|
const FormFieldTest: React.FC = () => {
|
||||||
|
const methods = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
parser_config: {
|
||||||
|
auto_keywords: 5,
|
||||||
|
auto_questions: 3,
|
||||||
|
delimiter: '\n',
|
||||||
|
chunk_token_num: 512,
|
||||||
|
layout_recognize: 'DeepDOC',
|
||||||
|
html4excel: false,
|
||||||
|
},
|
||||||
|
pagerank: 50,
|
||||||
|
custom_slider: 25,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = (data: any) => {
|
||||||
|
console.log('Form Data:', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ p: 3, maxWidth: 800, mx: 'auto' }}>
|
||||||
|
<Typography variant="h4" gutterBottom>
|
||||||
|
FormField 组件测试
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Paper sx={{ p: 3, mt: 2 }}>
|
||||||
|
<FormProvider {...methods}>
|
||||||
|
<form onSubmit={methods.handleSubmit(onSubmit)}>
|
||||||
|
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
自动关键词和问题
|
||||||
|
</Typography>
|
||||||
|
<NumberInputFormField
|
||||||
|
name="parser_config.auto_keywords"
|
||||||
|
label="自动关键词"
|
||||||
|
defaultValue={5}
|
||||||
|
min={0}
|
||||||
|
placeholder="输入关键词数量"
|
||||||
|
/>
|
||||||
|
<NumberInputFormField
|
||||||
|
name="parser_config.auto_questions"
|
||||||
|
label="自动问题"
|
||||||
|
defaultValue={3}
|
||||||
|
min={0}
|
||||||
|
placeholder="输入问题数量"
|
||||||
|
/>
|
||||||
|
<Divider sx={{ my: 3 }} />
|
||||||
|
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
分隔符配置
|
||||||
|
</Typography>
|
||||||
|
<MultilineTextFormField
|
||||||
|
name="parser_config.delimiter"
|
||||||
|
label="分隔符"
|
||||||
|
defaultValue="\n"
|
||||||
|
rows={2}
|
||||||
|
/>
|
||||||
|
<Divider sx={{ my: 3 }} />
|
||||||
|
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Token数量配置
|
||||||
|
</Typography>
|
||||||
|
<SliderInputFormField
|
||||||
|
name="parser_config.chunk_token_num"
|
||||||
|
label="最大Token数"
|
||||||
|
min={64}
|
||||||
|
max={2048}
|
||||||
|
step={64}
|
||||||
|
defaultValue={512}
|
||||||
|
layout="horizontal"
|
||||||
|
/>
|
||||||
|
<Divider sx={{ my: 3 }} />
|
||||||
|
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
页面排名
|
||||||
|
</Typography>
|
||||||
|
<NumberInputFormField
|
||||||
|
name="pagerank"
|
||||||
|
label="页面排名"
|
||||||
|
defaultValue={50}
|
||||||
|
min={0}
|
||||||
|
placeholder="输入页面排名"
|
||||||
|
/>
|
||||||
|
<Divider sx={{ my: 3 }} />
|
||||||
|
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
布局识别
|
||||||
|
</Typography>
|
||||||
|
<SelectFormField
|
||||||
|
name="parser_config.layout_recognize"
|
||||||
|
label="布局识别方法"
|
||||||
|
options={[
|
||||||
|
{ value: 'DeepDOC', label: 'DeepDOC' },
|
||||||
|
{ value: 'LayoutLM', label: 'LayoutLM' },
|
||||||
|
{ value: 'OCR', label: 'OCR' }
|
||||||
|
]}
|
||||||
|
defaultValue="DeepDOC"
|
||||||
|
/>
|
||||||
|
<Divider sx={{ my: 3 }} />
|
||||||
|
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
Excel转HTML
|
||||||
|
</Typography>
|
||||||
|
<SwitchFormField
|
||||||
|
name="parser_config.html4excel"
|
||||||
|
label="Excel转HTML"
|
||||||
|
defaultValue={false}
|
||||||
|
/>
|
||||||
|
<Divider sx={{ my: 3 }} />
|
||||||
|
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
自定义滑块(垂直布局)
|
||||||
|
</Typography>
|
||||||
|
<SliderInputFormField
|
||||||
|
name="custom_slider"
|
||||||
|
label="自定义滑块"
|
||||||
|
tooltip="这是一个自定义的滑块组件"
|
||||||
|
max={100}
|
||||||
|
min={0}
|
||||||
|
defaultValue={25}
|
||||||
|
layout={'vertical'}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Box sx={{ mt: 4, display: 'flex', gap: 2 }}>
|
||||||
|
<button type="submit">提交测试</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => methods.reset()}
|
||||||
|
>
|
||||||
|
重置表单
|
||||||
|
</button>
|
||||||
|
</Box>
|
||||||
|
</form>
|
||||||
|
</FormProvider>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Paper sx={{ p: 3, mt: 3 }}>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
当前表单值
|
||||||
|
</Typography>
|
||||||
|
<pre style={{ fontSize: '12px', overflow: 'auto' }}>
|
||||||
|
{JSON.stringify(methods.watch(), null, 2)}
|
||||||
|
</pre>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormFieldTest;
|
||||||
@@ -1,49 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
export function AudioConfiguration() {
|
export function AudioConfiguration() {
|
||||||
return (
|
return (
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
<PageRankItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoQuestionsItem />
|
||||||
PageRank配置 - 待实现
|
<TagsItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动关键词配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动问题配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
Raptor配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
GraphRAG配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
标签配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,60 +1,60 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import {
|
||||||
import { Box, Typography } from '@mui/material';
|
ChunkMethodItem,
|
||||||
|
EmbeddingModelItem,
|
||||||
|
LayoutRecognizeItem,
|
||||||
|
PageRankItem,
|
||||||
|
AutoKeywordsItem,
|
||||||
|
AutoQuestionsItem,
|
||||||
|
UseRaptorItem,
|
||||||
|
RaptorPromptItem,
|
||||||
|
RaptorMaxTokenItem,
|
||||||
|
RaptorThresholdItem,
|
||||||
|
RaptorMaxClusterItem,
|
||||||
|
RaptorRandomSeedItem,
|
||||||
|
UseGraphragItem,
|
||||||
|
EntityTypesItem,
|
||||||
|
GraphragMethodItem,
|
||||||
|
EntityNormalizeItem,
|
||||||
|
CommunityReportItem,
|
||||||
|
TagsItem
|
||||||
|
} from './common-items';
|
||||||
|
|
||||||
export function BookConfiguration() {
|
export function BookConfiguration() {
|
||||||
return (
|
return (
|
||||||
<MainContainer>
|
<MainContainer>
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<LayoutRecognizeItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
布局识别配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
<PageRankItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
PageRank配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<Box sx={{ mb: 2 }}>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoQuestionsItem />
|
||||||
自动关键词配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动问题配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<Box sx={{ mb: 2 }}>
|
<UseRaptorItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<RaptorPromptItem />
|
||||||
Raptor配置 - 待实现
|
<RaptorMaxTokenItem />
|
||||||
</Typography>
|
<RaptorThresholdItem />
|
||||||
</Box>
|
<RaptorMaxClusterItem />
|
||||||
|
<RaptorRandomSeedItem />
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<Box sx={{ mb: 2, p: 2 }}>
|
<ConfigurationFormContainer>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<UseGraphragItem />
|
||||||
GraphRAG配置 - 待实现
|
<EntityTypesItem />
|
||||||
</Typography>
|
<GraphragMethodItem />
|
||||||
</Box>
|
<EntityNormalizeItem />
|
||||||
|
<CommunityReportItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<Box sx={{ mb: 2 }}>
|
<TagsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
标签配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
</MainContainer>
|
</MainContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
import {
|
|
||||||
FormControl,
|
|
||||||
InputLabel,
|
|
||||||
Select,
|
|
||||||
MenuItem,
|
|
||||||
FormHelperText,
|
|
||||||
Box,
|
|
||||||
Typography,
|
|
||||||
ListSubheader,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { useFormContext, Controller } from 'react-hook-form';
|
|
||||||
import { DOCUMENT_PARSER_TYPES } from '@/constants/knowledge';
|
|
||||||
import { useSelectChunkMethodList } from '../hooks';
|
|
||||||
import { useEmbeddingModelOptions } from '@/hooks/llm-hooks';
|
|
||||||
|
|
||||||
// 解析器选项配置
|
|
||||||
const PARSER_OPTIONS = [
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Naive, label: 'General', description: '通用解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Qa, label: 'Q&A', description: 'Q&A解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Resume, label: 'Resume', description: 'Resume解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Manual, label: 'Manual', description: 'Manual解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Table, label: 'Table', description: 'Table解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Paper, label: 'Paper', description: 'Paper解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Book, label: 'Book', description: 'Book解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Laws, label: 'Laws', description: 'Laws解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Presentation, label: 'Presentation', description: 'Presentation解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.One, label: 'One', description: 'One解析器' },
|
|
||||||
{ value: DOCUMENT_PARSER_TYPES.Tag, label: 'Tag', description: 'Tag解析器' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export function ChunkMethodItem() {
|
|
||||||
const { control, formState: { errors } } = useFormContext();
|
|
||||||
const parserIds = useSelectChunkMethodList();
|
|
||||||
|
|
||||||
const parserOptions = parserIds.map((x) => ({
|
|
||||||
value: x,
|
|
||||||
label: PARSER_OPTIONS.find((y) => y.value === x)?.label || x,
|
|
||||||
description: PARSER_OPTIONS.find((y) => y.value === x)?.description || x,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box>
|
|
||||||
<Typography variant="h6" gutterBottom>
|
|
||||||
切片方法
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_id"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl fullWidth error={!!errors.parser_id}>
|
|
||||||
<InputLabel>选择切片方法</InputLabel>
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
label="选择切片方法"
|
|
||||||
>
|
|
||||||
{parserOptions.map((option) => (
|
|
||||||
<MenuItem key={option.value} value={option.value}>
|
|
||||||
<Box>
|
|
||||||
<Typography variant="body1">{option.label}</Typography>
|
|
||||||
<Typography variant="caption" color="text.secondary">
|
|
||||||
{option.description}
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</MenuItem>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
{errors.parser_id && (
|
|
||||||
<FormHelperText>{errors.parser_id.message as string}</FormHelperText>
|
|
||||||
)}
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function EmbeddingModelItem() {
|
|
||||||
const { control, formState: { errors } } = useFormContext();
|
|
||||||
|
|
||||||
const { options: embdOptions } = useEmbeddingModelOptions();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box sx={{ mb: 3 }}>
|
|
||||||
<Typography variant="h6" gutterBottom>
|
|
||||||
嵌入模型
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="embd_id"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl fullWidth error={!!errors.embd_id}>
|
|
||||||
<InputLabel>选择嵌入模型</InputLabel>
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
label="选择嵌入模型"
|
|
||||||
>
|
|
||||||
{
|
|
||||||
embdOptions.map((group) => [
|
|
||||||
<ListSubheader key={`header-${group.label}`} disableSticky>
|
|
||||||
{group.label}
|
|
||||||
</ListSubheader>,
|
|
||||||
...group.options.map((option) => (
|
|
||||||
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
|
|
||||||
{option.label}
|
|
||||||
</MenuItem>
|
|
||||||
))
|
|
||||||
])
|
|
||||||
}
|
|
||||||
</Select>
|
|
||||||
{errors.embd_id && (
|
|
||||||
<FormHelperText>{errors.embd_id.message as string}</FormHelperText>
|
|
||||||
)}
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
416
src/pages/knowledge/configuration/common-items.tsx
Normal file
416
src/pages/knowledge/configuration/common-items.tsx
Normal file
@@ -0,0 +1,416 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import {
|
||||||
|
FormControl,
|
||||||
|
InputLabel,
|
||||||
|
Select,
|
||||||
|
MenuItem,
|
||||||
|
FormHelperText,
|
||||||
|
Box,
|
||||||
|
Typography,
|
||||||
|
ListSubheader,
|
||||||
|
Button,
|
||||||
|
} from '@mui/material';
|
||||||
|
import { Shuffle as ShuffleIcon } from '@mui/icons-material';
|
||||||
|
import { useFormContext, Controller } from 'react-hook-form';
|
||||||
|
import { DOCUMENT_PARSER_TYPES, LLM_MODEL_TYPES, type LlmModelType } from '@/constants/knowledge';
|
||||||
|
import { useSelectChunkMethodList } from '../hooks';
|
||||||
|
import { useEmbeddingModelOptions, useLlmOptionsByModelType } from '@/hooks/llm-hooks';
|
||||||
|
import {
|
||||||
|
SliderInputFormField,
|
||||||
|
SwitchFormField,
|
||||||
|
SelectFormField,
|
||||||
|
MultilineTextFormField,
|
||||||
|
NumberInputFormField,
|
||||||
|
ChipListFormField,
|
||||||
|
TextFormField,
|
||||||
|
type SelectOption,
|
||||||
|
} from '@/components/FormField';
|
||||||
|
|
||||||
|
// 解析器选项配置
|
||||||
|
const PARSER_OPTIONS = [
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Naive, label: 'General', description: '通用解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Qa, label: 'Q&A', description: 'Q&A解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Resume, label: 'Resume', description: 'Resume解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Manual, label: 'Manual', description: 'Manual解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Table, label: 'Table', description: 'Table解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Paper, label: 'Paper', description: 'Paper解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Book, label: 'Book', description: 'Book解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Laws, label: 'Laws', description: 'Laws解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Presentation, label: 'Presentation', description: 'Presentation解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.One, label: 'One', description: 'One解析器' },
|
||||||
|
{ value: DOCUMENT_PARSER_TYPES.Tag, label: 'Tag', description: 'Tag解析器' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function ChunkMethodItem() {
|
||||||
|
const { control, formState: { errors } } = useFormContext();
|
||||||
|
const parserIds = useSelectChunkMethodList();
|
||||||
|
|
||||||
|
const parserOptions = parserIds.map((x) => ({
|
||||||
|
value: x,
|
||||||
|
label: PARSER_OPTIONS.find((y) => y.value === x)?.label || x,
|
||||||
|
description: PARSER_OPTIONS.find((y) => y.value === x)?.description || x,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h6" gutterBottom>
|
||||||
|
切片方法
|
||||||
|
</Typography>
|
||||||
|
<Controller
|
||||||
|
name="parser_id"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormControl fullWidth error={!!errors.parser_id}>
|
||||||
|
<InputLabel>选择切片方法</InputLabel>
|
||||||
|
<Select
|
||||||
|
{...field}
|
||||||
|
label="选择切片方法"
|
||||||
|
>
|
||||||
|
{parserOptions.map((option) => (
|
||||||
|
<MenuItem key={option.value} value={option.value}>
|
||||||
|
<Box>
|
||||||
|
<Typography variant="body1">{option.label}</Typography>
|
||||||
|
<Typography variant="caption" color="text.secondary">
|
||||||
|
{option.description}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
{errors.parser_id && (
|
||||||
|
<FormHelperText>{errors.parser_id.message as string}</FormHelperText>
|
||||||
|
)}
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基于基础FormField组件的业务组合组件
|
||||||
|
|
||||||
|
// 分块token数量配置
|
||||||
|
export function ChunkTokenNumberItem() {
|
||||||
|
return (
|
||||||
|
<SliderInputFormField
|
||||||
|
name="parser_config.chunk_token_num"
|
||||||
|
label="建议文本块大小"
|
||||||
|
min={64}
|
||||||
|
max={2048}
|
||||||
|
step={64}
|
||||||
|
defaultValue={512}
|
||||||
|
layout="horizontal"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面排名配置
|
||||||
|
export function PageRankItem() {
|
||||||
|
return (
|
||||||
|
<NumberInputFormField
|
||||||
|
name="parser_config.page_rank"
|
||||||
|
label="页面排名"
|
||||||
|
defaultValue={0}
|
||||||
|
min={0}
|
||||||
|
placeholder="输入页面排名"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动关键词数量配置
|
||||||
|
export function AutoKeywordsItem() {
|
||||||
|
return (
|
||||||
|
<NumberInputFormField
|
||||||
|
name="parser_config.auto_keywords"
|
||||||
|
label="自动关键词"
|
||||||
|
defaultValue={0}
|
||||||
|
min={0}
|
||||||
|
placeholder="输入关键词数量"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动问题数量配置
|
||||||
|
export function AutoQuestionsItem() {
|
||||||
|
return (
|
||||||
|
<NumberInputFormField
|
||||||
|
name="parser_config.auto_questions"
|
||||||
|
label="自动问题"
|
||||||
|
defaultValue={0}
|
||||||
|
min={0}
|
||||||
|
placeholder="输入问题数量"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格转HTML开关
|
||||||
|
export function HtmlForExcelItem() {
|
||||||
|
return (
|
||||||
|
<SwitchFormField
|
||||||
|
name="parser_config.html4excel"
|
||||||
|
label="表格转HTML"
|
||||||
|
defaultValue={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标签集选择
|
||||||
|
export function TagsItem() {
|
||||||
|
const tagsOptions: SelectOption[] = [
|
||||||
|
{ value: '', label: '请选择' },
|
||||||
|
// 这里可以根据实际需求添加标签选项
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectFormField
|
||||||
|
name="parser_config.tags"
|
||||||
|
label="标签集"
|
||||||
|
options={tagsOptions}
|
||||||
|
defaultValue=""
|
||||||
|
displayEmpty
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAPTOR策略开关
|
||||||
|
export function UseRaptorItem() {
|
||||||
|
return (
|
||||||
|
<SwitchFormField
|
||||||
|
name="parser_config.raptor.use_raptor"
|
||||||
|
label="使用召回增强RAPTOR策略"
|
||||||
|
defaultValue={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAPTOR提示词配置
|
||||||
|
export function RaptorPromptItem() {
|
||||||
|
return (
|
||||||
|
<MultilineTextFormField
|
||||||
|
name="parser_config.raptor.prompt"
|
||||||
|
label="提示词"
|
||||||
|
defaultValue="请总结以下段落。小心数字,不要编造。段落如下:\n{cluster_content}\n以上就是你需要总结的内容。"
|
||||||
|
rows={4}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAPTOR最大token数配置
|
||||||
|
export function RaptorMaxTokenItem() {
|
||||||
|
return (
|
||||||
|
<SliderInputFormField
|
||||||
|
name="parser_config.raptor.max_token"
|
||||||
|
label="最大token数"
|
||||||
|
min={64}
|
||||||
|
max={512}
|
||||||
|
step={32}
|
||||||
|
defaultValue={256}
|
||||||
|
layout="horizontal"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAPTOR阈值配置
|
||||||
|
export function RaptorThresholdItem() {
|
||||||
|
return (
|
||||||
|
<SliderInputFormField
|
||||||
|
name="parser_config.raptor.threshold"
|
||||||
|
label="阈值"
|
||||||
|
min={0}
|
||||||
|
max={1}
|
||||||
|
step={0.1}
|
||||||
|
defaultValue={0.1}
|
||||||
|
layout="horizontal"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAPTOR最大聚类数配置
|
||||||
|
export function RaptorMaxClusterItem() {
|
||||||
|
return (
|
||||||
|
<SliderInputFormField
|
||||||
|
name="parser_config.raptor.max_cluster"
|
||||||
|
label="最大聚类数"
|
||||||
|
min={16}
|
||||||
|
max={128}
|
||||||
|
step={16}
|
||||||
|
defaultValue={64}
|
||||||
|
layout="horizontal"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RAPTOR随机种子配置
|
||||||
|
export function RaptorRandomSeedItem() {
|
||||||
|
return (
|
||||||
|
<NumberInputFormField
|
||||||
|
name="parser_config.raptor.random_seed"
|
||||||
|
label="随机种子"
|
||||||
|
defaultValue={0}
|
||||||
|
showRandomButton
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 知识图谱开关
|
||||||
|
export function UseGraphragItem() {
|
||||||
|
return (
|
||||||
|
<SwitchFormField
|
||||||
|
name="parser_config.graphrag.use_graphrag"
|
||||||
|
label="提取知识图谱"
|
||||||
|
defaultValue={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实体类型配置
|
||||||
|
export function EntityTypesItem() {
|
||||||
|
return (
|
||||||
|
<ChipListFormField
|
||||||
|
name="parser_config.graphrag.entity_types"
|
||||||
|
label="*实体类型"
|
||||||
|
defaultValue={['organization', 'person', 'geo', 'event', 'category']}
|
||||||
|
required
|
||||||
|
allowAdd
|
||||||
|
allowDelete
|
||||||
|
maxChips={10}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GraphRAG方法选择
|
||||||
|
export function GraphragMethodItem() {
|
||||||
|
const methodOptions: SelectOption[] = [
|
||||||
|
{ value: 'Light', label: 'Light' },
|
||||||
|
{ value: 'General', label: 'General' },
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectFormField
|
||||||
|
name="parser_config.graphrag.method"
|
||||||
|
label="方法"
|
||||||
|
options={methodOptions}
|
||||||
|
defaultValue="Light"
|
||||||
|
displayEmpty={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实体归一化开关
|
||||||
|
export function EntityNormalizeItem() {
|
||||||
|
return (
|
||||||
|
<SwitchFormField
|
||||||
|
name="parser_config.graphrag.entity_normalize"
|
||||||
|
label="实体归一化"
|
||||||
|
defaultValue={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 社区报告生成开关
|
||||||
|
export function CommunityReportItem() {
|
||||||
|
return (
|
||||||
|
<SwitchFormField
|
||||||
|
name="parser_config.graphrag.community_report"
|
||||||
|
label="社区报告生成"
|
||||||
|
defaultValue={false}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EmbeddingModelItem() {
|
||||||
|
const { control } = useFormContext();
|
||||||
|
const { options } = useEmbeddingModelOptions();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="subtitle1" sx={{ minWidth: 120 }}>
|
||||||
|
嵌入模型
|
||||||
|
</Typography>
|
||||||
|
<Box sx={{ flex: 1 }}>
|
||||||
|
<Controller
|
||||||
|
name="embd_id"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormControl fullWidth variant="outlined">
|
||||||
|
<Select
|
||||||
|
{...field}
|
||||||
|
>
|
||||||
|
{options.map((group) => [
|
||||||
|
<ListSubheader key={group.label}>{group.label}</ListSubheader>,
|
||||||
|
...group.options.map((option) => (
|
||||||
|
<MenuItem key={option.value} value={option.value} disabled={option.disabled}>
|
||||||
|
{option.label}
|
||||||
|
</MenuItem>
|
||||||
|
))
|
||||||
|
])}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PDF解析器配置
|
||||||
|
export function LayoutRecognizeItem() {
|
||||||
|
const { control, setValue, formState } = useFormContext();
|
||||||
|
const { getOptionsByModelType } = useLlmOptionsByModelType();
|
||||||
|
|
||||||
|
const options = useMemo(() => {
|
||||||
|
// 基础选项
|
||||||
|
const basicOptions = [
|
||||||
|
{ value: 'DeepDOC', label: 'DeepDOC' },
|
||||||
|
{ value: 'Plain Text', label: '纯文本' }
|
||||||
|
];
|
||||||
|
|
||||||
|
// 获取图像转文本模型选项
|
||||||
|
const image2TextOptions = getOptionsByModelType(LLM_MODEL_TYPES.Image2text);
|
||||||
|
|
||||||
|
// 将图像转文本模型选项转换为SelectOption格式
|
||||||
|
const image2TextSelectOptions = image2TextOptions.flatMap(group =>
|
||||||
|
group.options.map(option => ({
|
||||||
|
value: option.value,
|
||||||
|
label: `${option.label} (实验性)`
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
return [...basicOptions, ...image2TextSelectOptions];
|
||||||
|
}, [getOptionsByModelType]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Controller
|
||||||
|
name="parser_config.layout_recognize"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => {
|
||||||
|
// 设置默认值
|
||||||
|
if (typeof field.value === 'undefined') {
|
||||||
|
const defaultValue = formState.defaultValues?.parser_config?.layout_recognize ?? 'DeepDOC';
|
||||||
|
setValue('parser_config.layout_recognize', defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectFormField
|
||||||
|
name="parser_config.layout_recognize"
|
||||||
|
label="PDF解析器"
|
||||||
|
options={options}
|
||||||
|
defaultValue="DeepDOC"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文本分段标识符配置
|
||||||
|
export function DelimiterItem() {
|
||||||
|
return (
|
||||||
|
<TextFormField
|
||||||
|
name="parser_config.delimiter"
|
||||||
|
label="分隔符"
|
||||||
|
placeholder="请输入分隔符"
|
||||||
|
defaultValue="\n!?。;!?"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,49 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
export function EmailConfiguration() {
|
export function EmailConfiguration() {
|
||||||
return (
|
return (
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
<PageRankItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoQuestionsItem />
|
||||||
PageRank配置 - 待实现
|
<TagsItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动关键词配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动问题配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
Raptor配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
GraphRAG配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
标签配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
export { NaiveConfiguration } from './naive';
|
export { NaiveConfiguration } from './naive';
|
||||||
export { QAConfiguration } from './qa';
|
export { QAConfiguration } from './qa';
|
||||||
export { PaperConfiguration } from './paper';
|
export { PaperConfiguration } from './paper';
|
||||||
export { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
export { ChunkMethodItem, EmbeddingModelItem } from './common-items';
|
||||||
export { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
export { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
||||||
|
|
||||||
// 所有解析器配置组件
|
// 所有解析器配置组件
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
import { Box, Typography } from '@mui/material';
|
||||||
|
|
||||||
export function KnowledgeGraphConfiguration() {
|
export function KnowledgeGraphConfiguration() {
|
||||||
|
|||||||
@@ -1,61 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
export function LawsConfiguration() {
|
export function LawsConfiguration() {
|
||||||
return (
|
return (
|
||||||
<MainContainer>
|
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
布局识别配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
<PageRankItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoQuestionsItem />
|
||||||
PageRank配置 - 待实现
|
<TagsItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动关键词配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动问题配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
Raptor配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
GraphRAG配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
标签配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
</MainContainer>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,59 +1,67 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import {
|
||||||
import { Box, Typography } from '@mui/material';
|
ChunkMethodItem,
|
||||||
|
EmbeddingModelItem,
|
||||||
|
ChunkTokenNumberItem,
|
||||||
|
DelimiterItem,
|
||||||
|
LayoutRecognizeItem,
|
||||||
|
PageRankItem,
|
||||||
|
AutoKeywordsItem,
|
||||||
|
AutoQuestionsItem,
|
||||||
|
HtmlForExcelItem,
|
||||||
|
UseRaptorItem,
|
||||||
|
RaptorPromptItem,
|
||||||
|
RaptorMaxTokenItem,
|
||||||
|
RaptorThresholdItem,
|
||||||
|
RaptorMaxClusterItem,
|
||||||
|
RaptorRandomSeedItem,
|
||||||
|
UseGraphragItem,
|
||||||
|
EntityTypesItem,
|
||||||
|
GraphragMethodItem,
|
||||||
|
EntityNormalizeItem,
|
||||||
|
CommunityReportItem,
|
||||||
|
TagsItem
|
||||||
|
} from './common-items';
|
||||||
|
|
||||||
export function ManualConfiguration() {
|
export function ManualConfiguration() {
|
||||||
return (
|
return (
|
||||||
<MainContainer>
|
<MainContainer>
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<ChunkTokenNumberItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<DelimiterItem />
|
||||||
布局识别配置 - 待实现
|
<LayoutRecognizeItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
PageRank配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<Box sx={{ mb: 2 }}>
|
<PageRankItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoKeywordsItem />
|
||||||
自动关键词配置 - 待实现
|
<AutoQuestionsItem />
|
||||||
</Typography>
|
<HtmlForExcelItem />
|
||||||
</Box>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动问题配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<Box sx={{ mb: 2 }}>
|
<UseRaptorItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<RaptorPromptItem />
|
||||||
Raptor配置 - 待实现
|
<RaptorMaxTokenItem />
|
||||||
</Typography>
|
<RaptorThresholdItem />
|
||||||
</Box>
|
<RaptorMaxClusterItem />
|
||||||
|
<RaptorRandomSeedItem />
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
<ConfigurationFormContainer>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<UseGraphragItem />
|
||||||
GraphRAG配置 - 待实现
|
<EntityTypesItem />
|
||||||
</Typography>
|
<GraphragMethodItem />
|
||||||
</Box>
|
<EntityNormalizeItem />
|
||||||
|
<CommunityReportItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
<ConfigurationFormContainer>
|
||||||
<Typography variant="body2" color="text.secondary">
|
<TagsItem />
|
||||||
标签配置 - 待实现
|
</ConfigurationFormContainer>
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</MainContainer>
|
</MainContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2,27 +2,39 @@ import React from 'react';
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Typography,
|
Typography,
|
||||||
FormControl,
|
|
||||||
InputLabel,
|
|
||||||
Select,
|
|
||||||
MenuItem,
|
|
||||||
TextField,
|
|
||||||
FormControlLabel,
|
|
||||||
Switch,
|
|
||||||
Slider,
|
|
||||||
Accordion,
|
Accordion,
|
||||||
AccordionSummary,
|
AccordionSummary,
|
||||||
AccordionDetails,
|
AccordionDetails,
|
||||||
Chip,
|
|
||||||
IconButton,
|
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { ExpandMore as ExpandMoreIcon, Add as AddIcon } from '@mui/icons-material';
|
import { ExpandMore as ExpandMoreIcon } from '@mui/icons-material';
|
||||||
import { useFormContext, Controller } from 'react-hook-form';
|
import { useFormContext } from 'react-hook-form';
|
||||||
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import {
|
||||||
|
ChunkMethodItem,
|
||||||
|
EmbeddingModelItem,
|
||||||
|
ChunkTokenNumberItem,
|
||||||
|
PageRankItem,
|
||||||
|
AutoKeywordsItem,
|
||||||
|
AutoQuestionsItem,
|
||||||
|
HtmlForExcelItem,
|
||||||
|
TagsItem,
|
||||||
|
UseRaptorItem,
|
||||||
|
RaptorPromptItem,
|
||||||
|
RaptorMaxTokenItem,
|
||||||
|
RaptorThresholdItem,
|
||||||
|
RaptorMaxClusterItem,
|
||||||
|
RaptorRandomSeedItem,
|
||||||
|
UseGraphragItem,
|
||||||
|
EntityTypesItem,
|
||||||
|
GraphragMethodItem,
|
||||||
|
EntityNormalizeItem,
|
||||||
|
CommunityReportItem,
|
||||||
|
LayoutRecognizeItem,
|
||||||
|
DelimiterItem
|
||||||
|
} from './common-items';
|
||||||
|
|
||||||
export function NaiveConfiguration() {
|
export function NaiveConfiguration() {
|
||||||
const { control, watch, formState: { errors } } = useFormContext();
|
const { formState: { errors } } = useFormContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
@@ -38,72 +50,16 @@ export function NaiveConfiguration() {
|
|||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
|
|
||||||
{/* PDF解析器 */}
|
{/* PDF解析器 */}
|
||||||
<Box>
|
<LayoutRecognizeItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
PDF解析器
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.pdf_parser"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
displayEmpty
|
|
||||||
defaultValue="Naive"
|
|
||||||
>
|
|
||||||
<MenuItem value="Naive">Naive</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 嵌入模型 */}
|
{/* 嵌入模型 */}
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
|
||||||
{/* 建议文本块大小 */}
|
{/* 建议文本块大小 */}
|
||||||
<Box>
|
<ChunkTokenNumberItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
建议文本块大小
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.chunk_token_num"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Box sx={{ px: 2 }}>
|
|
||||||
<Slider
|
|
||||||
{...field}
|
|
||||||
min={128}
|
|
||||||
max={2048}
|
|
||||||
step={64}
|
|
||||||
valueLabelDisplay="on"
|
|
||||||
defaultValue={512}
|
|
||||||
onChange={(_, value) => field.onChange(value)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 文本分段标识符 */}
|
{/* 文本分段标识符 */}
|
||||||
<Box>
|
<DelimiterItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
*文本分段标识符
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.delimiter"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<TextField
|
|
||||||
{...field}
|
|
||||||
fullWidth
|
|
||||||
placeholder="\\n"
|
|
||||||
defaultValue="\\n"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
@@ -116,250 +72,47 @@ export function NaiveConfiguration() {
|
|||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
||||||
{/* 页面排名 */}
|
{/* 页面排名 */}
|
||||||
<Box>
|
<PageRankItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
页面排名
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.page_rank"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<TextField
|
|
||||||
{...field}
|
|
||||||
type="number"
|
|
||||||
fullWidth
|
|
||||||
defaultValue={0}
|
|
||||||
inputProps={{ min: 0 }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 自动关键词提取 */}
|
{/* 自动关键词提取 */}
|
||||||
<Box>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
自动关键词提取
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.auto_keywords"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<TextField
|
|
||||||
{...field}
|
|
||||||
type="number"
|
|
||||||
fullWidth
|
|
||||||
defaultValue={0}
|
|
||||||
inputProps={{ min: 0 }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 自动问题提取 */}
|
{/* 自动问题提取 */}
|
||||||
<Box>
|
<AutoQuestionsItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
自动问题提取
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.auto_questions"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<TextField
|
|
||||||
{...field}
|
|
||||||
type="number"
|
|
||||||
fullWidth
|
|
||||||
defaultValue={0}
|
|
||||||
inputProps={{ min: 0 }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 表格转HTML */}
|
{/* 表格转HTML */}
|
||||||
<Box>
|
<HtmlForExcelItem />
|
||||||
<Controller
|
|
||||||
name="parser_config.html4excel"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={field.value || false}
|
|
||||||
onChange={field.onChange}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="表格转HTML"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 标签集 */}
|
{/* 标签集 */}
|
||||||
<Box>
|
<TagsItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
标签集
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.tags"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
displayEmpty
|
|
||||||
defaultValue=""
|
|
||||||
>
|
|
||||||
<MenuItem value="">请选择</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|
||||||
{/* 第三部分:RAPTOR策略 */}
|
{/* 第三部分:RAPTOR策略 */}
|
||||||
<Accordion defaultExpanded>
|
<Accordion>
|
||||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||||
<Typography variant="h6">RAPTOR策略</Typography>
|
<Typography variant="h6">RAPTOR策略</Typography>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
||||||
{/* 使用召回增强RAPTOR策略 */}
|
{/* 使用召回增强RAPTOR策略 */}
|
||||||
<Box>
|
<UseRaptorItem />
|
||||||
<Controller
|
|
||||||
name="parser_config.raptor.use_raptor"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={field.value || false}
|
|
||||||
onChange={field.onChange}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="使用召回增强RAPTOR策略"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 提示词 */}
|
{/* 提示词 */}
|
||||||
<Box>
|
<RaptorPromptItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
提示词
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.raptor.prompt"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<TextField
|
|
||||||
{...field}
|
|
||||||
multiline
|
|
||||||
rows={4}
|
|
||||||
fullWidth
|
|
||||||
defaultValue="请总结以下段落。小心数字,不要编造。段落如下:\n{cluster_content}\n以上就是你需要总结的内容。"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 最大token数 */}
|
{/* 最大token数 */}
|
||||||
<Box>
|
<RaptorMaxTokenItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
最大token数
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.raptor.max_token"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Box sx={{ px: 2 }}>
|
|
||||||
<Slider
|
|
||||||
{...field}
|
|
||||||
min={64}
|
|
||||||
max={512}
|
|
||||||
step={32}
|
|
||||||
valueLabelDisplay="on"
|
|
||||||
defaultValue={256}
|
|
||||||
onChange={(_, value) => field.onChange(value)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 阈值 */}
|
{/* 阈值 */}
|
||||||
<Box>
|
<RaptorThresholdItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
阈值
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.raptor.threshold"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Box sx={{ px: 2 }}>
|
|
||||||
<Slider
|
|
||||||
{...field}
|
|
||||||
min={0}
|
|
||||||
max={1}
|
|
||||||
step={0.1}
|
|
||||||
valueLabelDisplay="on"
|
|
||||||
defaultValue={0.1}
|
|
||||||
onChange={(_, value) => field.onChange(value)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 最大聚类数 */}
|
{/* 最大聚类数 */}
|
||||||
<Box>
|
<RaptorMaxClusterItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
最大聚类数
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.raptor.max_cluster"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Box sx={{ px: 2 }}>
|
|
||||||
<Slider
|
|
||||||
{...field}
|
|
||||||
min={16}
|
|
||||||
max={128}
|
|
||||||
step={16}
|
|
||||||
valueLabelDisplay="on"
|
|
||||||
defaultValue={64}
|
|
||||||
onChange={(_, value) => field.onChange(value)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 随机种子 */}
|
{/* 随机种子 */}
|
||||||
<Box>
|
<RaptorRandomSeedItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
随机种子
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.raptor.random_seed"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
|
||||||
<TextField
|
|
||||||
{...field}
|
|
||||||
type="number"
|
|
||||||
defaultValue={0}
|
|
||||||
sx={{ flex: 1 }}
|
|
||||||
/>
|
|
||||||
<IconButton>
|
|
||||||
<AddIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
@@ -372,109 +125,19 @@ export function NaiveConfiguration() {
|
|||||||
<AccordionDetails>
|
<AccordionDetails>
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
|
||||||
{/* 提取知识图谱 */}
|
{/* 提取知识图谱 */}
|
||||||
<Box>
|
<UseGraphragItem />
|
||||||
<Controller
|
|
||||||
name="parser_config.graphrag.use_graphrag"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={field.value || false}
|
|
||||||
onChange={field.onChange}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="提取知识图谱"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 实体类型 */}
|
{/* 实体类型 */}
|
||||||
<Box>
|
<EntityTypesItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
*实体类型
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.graphrag.entity_types"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mb: 2 }}>
|
|
||||||
{['organization', 'person', 'geo', 'event', 'category'].map((type) => (
|
|
||||||
<Chip
|
|
||||||
key={type}
|
|
||||||
label={type}
|
|
||||||
onDelete={() => {}}
|
|
||||||
variant="outlined"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
<IconButton size="small">
|
|
||||||
<AddIcon />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 方法 */}
|
{/* 方法 */}
|
||||||
<Box>
|
<GraphragMethodItem />
|
||||||
<Typography variant="subtitle1" gutterBottom>
|
|
||||||
方法
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.graphrag.method"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
defaultValue="Light"
|
|
||||||
>
|
|
||||||
<MenuItem value="Light">Light</MenuItem>
|
|
||||||
<MenuItem value="General">General</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 实体归一化 */}
|
{/* 实体归一化 */}
|
||||||
<Box>
|
<EntityNormalizeItem />
|
||||||
<Controller
|
|
||||||
name="parser_config.graphrag.entity_normalize"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={field.value || false}
|
|
||||||
onChange={field.onChange}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="实体归一化"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 社区报告生成 */}
|
{/* 社区报告生成 */}
|
||||||
<Box>
|
<CommunityReportItem />
|
||||||
<Controller
|
|
||||||
name="parser_config.graphrag.community_report"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Switch
|
|
||||||
checked={field.value || false}
|
|
||||||
onChange={field.onChange}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="社区报告生成"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
|||||||
@@ -1,48 +1,67 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import {
|
||||||
import { Box, Typography } from '@mui/material';
|
ChunkMethodItem,
|
||||||
|
EmbeddingModelItem,
|
||||||
|
ChunkTokenNumberItem,
|
||||||
|
DelimiterItem,
|
||||||
|
LayoutRecognizeItem,
|
||||||
|
PageRankItem,
|
||||||
|
AutoKeywordsItem,
|
||||||
|
AutoQuestionsItem,
|
||||||
|
HtmlForExcelItem,
|
||||||
|
UseRaptorItem,
|
||||||
|
RaptorPromptItem,
|
||||||
|
RaptorMaxTokenItem,
|
||||||
|
RaptorThresholdItem,
|
||||||
|
RaptorMaxClusterItem,
|
||||||
|
RaptorRandomSeedItem,
|
||||||
|
UseGraphragItem,
|
||||||
|
EntityTypesItem,
|
||||||
|
GraphragMethodItem,
|
||||||
|
EntityNormalizeItem,
|
||||||
|
CommunityReportItem,
|
||||||
|
TagsItem
|
||||||
|
} from './common-items';
|
||||||
|
|
||||||
export function OneConfiguration() {
|
export function OneConfiguration() {
|
||||||
return (
|
return (
|
||||||
|
<MainContainer>
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<ChunkTokenNumberItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<DelimiterItem />
|
||||||
布局识别配置 - 待实现
|
<LayoutRecognizeItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
PageRank配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动关键词配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动问题配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
GraphRAG配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
标签配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
|
<ConfigurationFormContainer>
|
||||||
|
<PageRankItem />
|
||||||
|
<AutoKeywordsItem />
|
||||||
|
<AutoQuestionsItem />
|
||||||
|
<HtmlForExcelItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
|
<ConfigurationFormContainer>
|
||||||
|
<UseRaptorItem />
|
||||||
|
<RaptorPromptItem />
|
||||||
|
<RaptorMaxTokenItem />
|
||||||
|
<RaptorThresholdItem />
|
||||||
|
<RaptorMaxClusterItem />
|
||||||
|
<RaptorRandomSeedItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
|
<ConfigurationFormContainer>
|
||||||
|
<UseGraphragItem />
|
||||||
|
<EntityTypesItem />
|
||||||
|
<GraphragMethodItem />
|
||||||
|
<EntityNormalizeItem />
|
||||||
|
<CommunityReportItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
|
<ConfigurationFormContainer>
|
||||||
|
<TagsItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
</MainContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,121 +1,61 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
|
||||||
Box,
|
|
||||||
Typography,
|
|
||||||
FormControl,
|
|
||||||
InputLabel,
|
|
||||||
Select,
|
|
||||||
MenuItem,
|
|
||||||
TextField,
|
|
||||||
Slider,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { useFormContext, Controller } from 'react-hook-form';
|
|
||||||
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
||||||
|
import {
|
||||||
|
ChunkMethodItem,
|
||||||
|
EmbeddingModelItem,
|
||||||
|
LayoutRecognizeItem,
|
||||||
|
PageRankItem,
|
||||||
|
AutoKeywordsItem,
|
||||||
|
AutoQuestionsItem,
|
||||||
|
UseRaptorItem,
|
||||||
|
RaptorPromptItem,
|
||||||
|
RaptorMaxTokenItem,
|
||||||
|
RaptorThresholdItem,
|
||||||
|
RaptorMaxClusterItem,
|
||||||
|
RaptorRandomSeedItem,
|
||||||
|
UseGraphragItem,
|
||||||
|
EntityTypesItem,
|
||||||
|
GraphragMethodItem,
|
||||||
|
EntityNormalizeItem,
|
||||||
|
CommunityReportItem,
|
||||||
|
TagsItem
|
||||||
|
} from './common-items';
|
||||||
|
|
||||||
export function PaperConfiguration() {
|
export function PaperConfiguration() {
|
||||||
const { control } = useFormContext();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<MainContainer>
|
<MainContainer>
|
||||||
{/* 布局识别 */}
|
<ConfigurationFormContainer>
|
||||||
<Box>
|
<ChunkMethodItem />
|
||||||
<Typography variant="h6" gutterBottom>
|
<LayoutRecognizeItem />
|
||||||
布局识别
|
<EmbeddingModelItem />
|
||||||
</Typography>
|
<PageRankItem />
|
||||||
<Controller
|
|
||||||
name="parser_config.layout_recognize"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<InputLabel>布局识别方式</InputLabel>
|
|
||||||
<Select
|
|
||||||
{...field}
|
|
||||||
label="布局识别方式"
|
|
||||||
>
|
|
||||||
<MenuItem value="DeepDOC">DeepDOC</MenuItem>
|
|
||||||
<MenuItem value="Plain Text">Plain Text</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 自动关键词 */}
|
|
||||||
<Box>
|
|
||||||
<Typography variant="h6" gutterBottom>
|
|
||||||
自动关键词数量
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.auto_keywords"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Box sx={{ px: 2 }}>
|
|
||||||
<Slider
|
|
||||||
{...field}
|
|
||||||
min={0}
|
|
||||||
max={10}
|
|
||||||
step={1}
|
|
||||||
marks
|
|
||||||
valueLabelDisplay="auto"
|
|
||||||
onChange={(_, value) => field.onChange(value)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 自动问题 */}
|
|
||||||
<Box>
|
|
||||||
<Typography variant="h6" gutterBottom>
|
|
||||||
自动问题数量
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.auto_questions"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<Box sx={{ px: 2 }}>
|
|
||||||
<Slider
|
|
||||||
{...field}
|
|
||||||
min={0}
|
|
||||||
max={10}
|
|
||||||
step={1}
|
|
||||||
marks
|
|
||||||
valueLabelDisplay="auto"
|
|
||||||
onChange={(_, value) => field.onChange(value)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
{/* 标签数量 */}
|
|
||||||
<Box>
|
|
||||||
<Typography variant="h6" gutterBottom>
|
|
||||||
Top N 标签数量
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.topn_tags"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<TextField
|
|
||||||
{...field}
|
|
||||||
type="number"
|
|
||||||
fullWidth
|
|
||||||
label="标签数量"
|
|
||||||
inputProps={{ min: 1, max: 10 }}
|
|
||||||
onChange={(e) => field.onChange(parseInt(e.target.value))}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
论文解析器专门优化用于学术论文的解析,能够更好地识别论文的结构和内容。
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</MainContainer>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
|
<ConfigurationFormContainer>
|
||||||
|
<AutoKeywordsItem />
|
||||||
|
<AutoQuestionsItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
|
<ConfigurationFormContainer>
|
||||||
|
<UseRaptorItem />
|
||||||
|
<RaptorPromptItem />
|
||||||
|
<RaptorMaxTokenItem />
|
||||||
|
<RaptorThresholdItem />
|
||||||
|
<RaptorMaxClusterItem />
|
||||||
|
<RaptorRandomSeedItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
|
<ConfigurationFormContainer>
|
||||||
|
<UseGraphragItem />
|
||||||
|
<EntityTypesItem />
|
||||||
|
<GraphragMethodItem />
|
||||||
|
<EntityNormalizeItem />
|
||||||
|
<CommunityReportItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
|
<ConfigurationFormContainer>
|
||||||
|
<TagsItem />
|
||||||
|
</ConfigurationFormContainer>
|
||||||
|
</MainContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,37 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
export function PictureConfiguration() {
|
export function PictureConfiguration() {
|
||||||
return (
|
return (
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
<PageRankItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoQuestionsItem />
|
||||||
PageRank配置 - 待实现
|
<TagsItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动关键词配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动问题配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
标签配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,61 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
export function PresentationConfiguration() {
|
export function PresentationConfiguration() {
|
||||||
return (
|
return (
|
||||||
<MainContainer>
|
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
布局识别配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
<PageRankItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoQuestionsItem />
|
||||||
PageRank配置 - 待实现
|
<TagsItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动关键词配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
自动问题配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
Raptor配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
GraphRAG配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<ConfigurationFormContainer>
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
标签配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
|
||||||
</MainContainer>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
Box,
|
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, TagsItem } from './common-items';
|
||||||
Typography,
|
|
||||||
TextField,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { useFormContext, Controller } from 'react-hook-form';
|
|
||||||
import { ConfigurationFormContainer, MainContainer } from './configuration-form-container';
|
|
||||||
|
|
||||||
export function QAConfiguration() {
|
export function QAConfiguration() {
|
||||||
const { control } = useFormContext();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<MainContainer>
|
<ChunkMethodItem />
|
||||||
{/* 标签数量 */}
|
<EmbeddingModelItem />
|
||||||
<Box>
|
<PageRankItem />
|
||||||
<Typography variant="h6" gutterBottom>
|
<TagsItem />
|
||||||
Top N 标签数量
|
|
||||||
</Typography>
|
|
||||||
<Controller
|
|
||||||
name="parser_config.topn_tags"
|
|
||||||
control={control}
|
|
||||||
render={({ field }) => (
|
|
||||||
<TextField
|
|
||||||
{...field}
|
|
||||||
type="number"
|
|
||||||
fullWidth
|
|
||||||
label="标签数量"
|
|
||||||
inputProps={{ min: 1, max: 10 }}
|
|
||||||
onChange={(e) => field.onChange(parseInt(e.target.value))}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
Q&A解析器专门用于处理问答格式的文档,会自动识别问题和答案的结构。
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</MainContainer>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,25 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
export function ResumeConfiguration() {
|
export function ResumeConfiguration() {
|
||||||
return (
|
return (
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
<PageRankItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoQuestionsItem />
|
||||||
PageRank配置 - 待实现
|
<TagsItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box sx={{ mb: 2 }}>
|
|
||||||
<Typography variant="body2" color="text.secondary">
|
|
||||||
标签配置 - 待实现
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem, PageRankItem, AutoKeywordsItem, AutoQuestionsItem, TagsItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
|
||||||
|
|
||||||
export function TableConfiguration() {
|
export function TableConfiguration() {
|
||||||
return (
|
return (
|
||||||
<ConfigurationFormContainer>
|
<ConfigurationFormContainer>
|
||||||
<ChunkMethodItem />
|
<ChunkMethodItem />
|
||||||
<EmbeddingModelItem />
|
<EmbeddingModelItem />
|
||||||
|
<PageRankItem />
|
||||||
<Box sx={{ mb: 2 }}>
|
<AutoKeywordsItem />
|
||||||
<Typography variant="body2" color="text.secondary">
|
<AutoQuestionsItem />
|
||||||
PageRank配置 - 待实现
|
<TagsItem />
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
</ConfigurationFormContainer>
|
</ConfigurationFormContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ConfigurationFormContainer } from './configuration-form-container';
|
import { ConfigurationFormContainer } from './configuration-form-container';
|
||||||
import { ChunkMethodItem, EmbeddingModelItem } from './common-item';
|
import { ChunkMethodItem, EmbeddingModelItem } from './common-items';
|
||||||
import { Box, Typography } from '@mui/material';
|
import { Box, Typography } from '@mui/material';
|
||||||
|
|
||||||
export function TagConfiguration() {
|
export function TagConfiguration() {
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ function KnowledgeBaseSetting() {
|
|||||||
permission: knowledge.permission || 'me',
|
permission: knowledge.permission || 'me',
|
||||||
avatar: knowledge.avatar,
|
avatar: knowledge.avatar,
|
||||||
parser_id: knowledge.parser_id || DOCUMENT_PARSER_TYPES.Naive,
|
parser_id: knowledge.parser_id || DOCUMENT_PARSER_TYPES.Naive,
|
||||||
|
embd_id: knowledge.embd_id || '',
|
||||||
parser_config: {
|
parser_config: {
|
||||||
chunk_token_num: knowledge.parser_config?.chunk_token_num || 512,
|
chunk_token_num: knowledge.parser_config?.chunk_token_num || 512,
|
||||||
delimiter: knowledge.parser_config?.delimiter || '\n',
|
delimiter: knowledge.parser_config?.delimiter || '\n',
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import Dashboard from '../pages/Dashboard';
|
|||||||
import ModelsResources from '../pages/ModelsResources';
|
import ModelsResources from '../pages/ModelsResources';
|
||||||
import { KnowledgeBaseList, KnowledgeBaseCreate, KnowledgeBaseDetail, KnowledgeBaseSetting, KnowledgeBaseTesting } from '../pages/knowledge';
|
import { KnowledgeBaseList, KnowledgeBaseCreate, KnowledgeBaseDetail, KnowledgeBaseSetting, KnowledgeBaseTesting } from '../pages/knowledge';
|
||||||
import MCP from '../pages/MCP';
|
import MCP from '../pages/MCP';
|
||||||
|
import FormFieldTest from '../pages/FormFieldTest';
|
||||||
|
|
||||||
const AppRoutes = () => {
|
const AppRoutes = () => {
|
||||||
return (
|
return (
|
||||||
@@ -31,6 +32,7 @@ const AppRoutes = () => {
|
|||||||
<Route path="dashboard" element={<Dashboard />} />
|
<Route path="dashboard" element={<Dashboard />} />
|
||||||
<Route path="models-resources" element={<ModelsResources />} />
|
<Route path="models-resources" element={<ModelsResources />} />
|
||||||
<Route path="mcp" element={<MCP />} />
|
<Route path="mcp" element={<MCP />} />
|
||||||
|
<Route path="form-field-test" element={<FormFieldTest />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
{/* 处理未匹配的路由 */}
|
{/* 处理未匹配的路由 */}
|
||||||
|
|||||||
Reference in New Issue
Block a user