feat(models): add models page and refactor profile form
This commit is contained in:
@@ -69,6 +69,7 @@ function CreateKnowledgeDialog({ open, onClose, onSuccess }: CreateKnowledgeDial
|
||||
// 解析相关字段:后端已支持 parser_id / pipeline_id
|
||||
parser_id: data.parser_id,
|
||||
pipeline_id: data.pipeline_id,
|
||||
parse_type: Number.parseInt(parseType) ?? 1,
|
||||
};
|
||||
|
||||
await createKnowledge(requestData);
|
||||
|
||||
@@ -25,10 +25,10 @@ import {
|
||||
} from '@mui/icons-material';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLlmModelSetting } from '@/hooks/setting-hooks';
|
||||
import { useModelDialogs } from './hooks/useModelDialogs';
|
||||
import { useModelDialogs } from '../setting/hooks/useModelDialogs';
|
||||
import type { IFactory, IMyLlmModel, ILlmItem } from '@/interfaces/database/llm';
|
||||
import LLMFactoryCard, { MODEL_TYPE_COLORS } from './components/LLMFactoryCard';
|
||||
import { ModelDialogs } from './components/ModelDialogs';
|
||||
import LLMFactoryCard, { MODEL_TYPE_COLORS } from '../setting/components/LLMFactoryCard';
|
||||
import { ModelDialogs } from '../setting/components/ModelDialogs';
|
||||
import { useDialog } from '@/hooks/useDialog';
|
||||
import logger from '@/utils/logger';
|
||||
import { LLM_FACTORY_LIST, LocalLlmFactories, type LLMFactory } from '@/constants/llm';
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useRef } from 'react';
|
||||
import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react';
|
||||
import {
|
||||
Box,
|
||||
TextField,
|
||||
@@ -36,20 +36,29 @@ const languageOptions = [
|
||||
// 时区选项
|
||||
const timezoneOptions = TimezoneList.map(x => ({ value: x, label: x }));
|
||||
|
||||
interface ProfileFormProps {
|
||||
export interface ProfileFormProps {
|
||||
userInfo: IUserInfo | null;
|
||||
onSubmit: (data: Partial<IUserInfo>) => Promise<void>;
|
||||
showSaveButton?: boolean;
|
||||
onSave?: () => void | Promise<void>;
|
||||
}
|
||||
|
||||
export type ProfileFormHandle = {
|
||||
submit: () => Promise<void>;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 个人信息表单
|
||||
*/
|
||||
function ProfileForm({ userInfo, onSubmit }: ProfileFormProps) {
|
||||
const ProfileFormInner = (
|
||||
{ userInfo, onSubmit, showSaveButton = true, onSave }: ProfileFormProps,
|
||||
ref: React.ForwardedRef<ProfileFormHandle>
|
||||
) => {
|
||||
const { t } = useTranslation();
|
||||
const showMessage = useMessage();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
|
||||
const [formData, setFormData] = useState<Partial<IUserInfo>>({
|
||||
nickname: userInfo?.nickname || '',
|
||||
avatar: userInfo?.avatar || null,
|
||||
@@ -96,7 +105,7 @@ function ProfileForm({ userInfo, onSubmit }: ProfileFormProps) {
|
||||
showMessage.error(t('setting.pleaseSelectImageFile'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 检查文件大小 (限制为2MB)
|
||||
if (file.size > 2 * 1024 * 1024) {
|
||||
showMessage.error(t('setting.imageSizeLimit'));
|
||||
@@ -145,20 +154,25 @@ function ProfileForm({ userInfo, onSubmit }: ProfileFormProps) {
|
||||
}
|
||||
};
|
||||
|
||||
// 向父级暴露提交方法
|
||||
useImperativeHandle(ref, () => ({
|
||||
submit: handleSave,
|
||||
}));
|
||||
|
||||
return (
|
||||
<Paper elevation={0} sx={{ p: 3, backgroundColor: 'transparent' }}>
|
||||
<Typography variant="h6" gutterBottom sx={{ mb: 3, fontWeight: 600 }}>
|
||||
{t('setting.personalProfile')}
|
||||
</Typography>
|
||||
|
||||
|
||||
<Grid container spacing={3}>
|
||||
{/* 头像部分 */}
|
||||
<Grid size={12}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
|
||||
<Avatar
|
||||
src={formData.avatar}
|
||||
sx={{
|
||||
width: 80,
|
||||
sx={{
|
||||
width: 80,
|
||||
height: 80,
|
||||
border: '2px solid',
|
||||
borderColor: 'divider'
|
||||
@@ -174,7 +188,7 @@ function ProfileForm({ userInfo, onSubmit }: ProfileFormProps) {
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={triggerFileSelect}
|
||||
sx={{
|
||||
sx={{
|
||||
border: '1px solid',
|
||||
borderColor: 'primary.main',
|
||||
'&:hover': {
|
||||
@@ -260,21 +274,33 @@ function ProfileForm({ userInfo, onSubmit }: ProfileFormProps) {
|
||||
</FormControl>
|
||||
</Grid>
|
||||
|
||||
{/* 保存按钮 */}
|
||||
<Grid size={12}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 2 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleSave}
|
||||
sx={{ minWidth: 120 }}
|
||||
>
|
||||
{t('setting.save')}
|
||||
</Button>
|
||||
</Box>
|
||||
</Grid>
|
||||
{/* 保存按钮(可选) */}
|
||||
{showSaveButton && (
|
||||
<Grid size={12}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 2 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={async () => {
|
||||
if (onSave) {
|
||||
await onSave();
|
||||
} else {
|
||||
await handleSave();
|
||||
}
|
||||
}}
|
||||
sx={{ minWidth: 120 }}
|
||||
>
|
||||
{t('setting.save')}
|
||||
</Button>
|
||||
</Box>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const ProfileForm = forwardRef<ProfileFormHandle, ProfileFormProps>(ProfileFormInner);
|
||||
|
||||
ProfileForm.displayName = 'ProfileForm';
|
||||
|
||||
export default ProfileForm;
|
||||
@@ -1,4 +1,3 @@
|
||||
export { default as ModelsSetting } from './models';
|
||||
export { default as SystemSetting } from './system';
|
||||
export { default as TeamsSetting } from './teams';
|
||||
export { default as ProfileSetting } from './profile';
|
||||
|
||||
Reference in New Issue
Block a user