feat(models): add models page and refactor profile form

This commit is contained in:
2025-11-14 16:48:42 +08:00
parent 97402674cd
commit ef8076d87f
10 changed files with 267 additions and 94 deletions

View File

@@ -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);

View File

@@ -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';

View File

@@ -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;

View File

@@ -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';