feat(knowledge): refactor knowledge creation form and improve form handling

This commit is contained in:
2025-10-16 18:52:20 +08:00
parent f4e2f4f10c
commit 50628816e3
5 changed files with 312 additions and 150 deletions

View File

@@ -1,5 +1,5 @@
import React, { useRef } from 'react';
import { useFormContext, Controller } from 'react-hook-form';
import { useFormContext, Controller, type UseFormReturn } from 'react-hook-form';
import {
Box,
Typography,
@@ -18,30 +18,69 @@ import {
Delete as DeleteIcon,
} from '@mui/icons-material';
function GeneralForm() {
const { control, watch, setValue } = useFormContext();
interface GeneralFormProps {
form?: UseFormReturn;
onSubmit?: (data: any) => void;
isSubmitting?: boolean;
onCancel?: () => void;
submitButtonText?: string;
cancelButtonText?: string;
}
function GeneralForm({
form: propForm,
onSubmit,
isSubmitting,
onCancel,
submitButtonText = '保存',
cancelButtonText = '取消',
}: GeneralFormProps = {}) {
// 优先使用props传递的form否则使用FormProvider的context
let contextForm: UseFormReturn | null = null;
try {
contextForm = useFormContext();
} catch (error) {
contextForm = null;
}
const form = propForm || contextForm;
if (!form) {
console.error('GeneralForm: No form context found. Component must be used within a FormProvider or receive a form prop.');
return (
<Box sx={{ p: 2, textAlign: 'center' }}>
<Typography color="error">
FormProvider中使用或传递form参数
</Typography>
</Box>
);
}
const { control, watch, setValue, handleSubmit } = form;
const fileInputRef = useRef<HTMLInputElement>(null);
const handleAvatarUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
if (file && form) {
const reader = new FileReader();
reader.onload = (e) => {
setValue('avatar', e.target?.result as string);
form.setValue('avatar', e.target?.result as string);
};
reader.readAsDataURL(file);
}
};
const handleAvatarDelete = () => {
setValue('avatar', undefined);
if (form) {
form.setValue('avatar', undefined);
}
};
const handleAvatarClick = () => {
fileInputRef.current?.click();
};
const avatar = watch('avatar');
const avatar = watch('avatar', '');
return (
<Box sx={{ p: 3 }}>
@@ -146,6 +185,28 @@ function GeneralForm() {
</Grid>
</Grid>
</Grid>
{/* 表单操作按钮 - 仅在有onSubmit回调时显示 */}
{onSubmit && (
<Box sx={{ mt: 4, display: 'flex', justifyContent: 'flex-end', gap: 2 }}>
{onCancel && (
<Button
variant="outlined"
onClick={onCancel}
disabled={isSubmitting}
>
{cancelButtonText}
</Button>
)}
<Button
variant="contained"
onClick={form ? form.handleSubmit(onSubmit) : undefined}
disabled={isSubmitting || !form}
>
{isSubmitting ? '提交中...' : submitButtonText}
</Button>
</Box>
)}
</Box>
);
}