/** * User Profile Page * 个人信息页面 */ import { useState, useEffect } from 'react'; import { Form, Input, Button, Card, Avatar, Space, Descriptions, Row, Col, Upload, message } from 'antd'; import { UserOutlined, MailOutlined, IdcardOutlined, UploadOutlined } from '@ant-design/icons'; import { request, API_BASE_URL } from '../../utils/request'; import { auth } from '../../utils/auth'; import { useToast } from '../../contexts/ToastContext'; export function UserProfile() { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const [uploading, setUploading] = useState(false); const [userProfile, setUserProfile] = useState(null); const toast = useToast(); const user = auth.getUser(); useEffect(() => { loadUserProfile(); }, []); const loadUserProfile = async () => { setLoading(true); try { const { data } = await request.get('/users/me'); setUserProfile(data); form.setFieldsValue({ email: data.email || '', full_name: data.full_name || '', }); } catch (error) { toast.error('获取用户信息失败'); } finally { setLoading(false); } }; const handleSubmit = async (values: any) => { setLoading(true); try { await request.put('/users/me/profile', { full_name: values.full_name, email: values.email || null, }); toast.success('个人信息更新成功'); // Update local user info const updatedUser = { ...user, full_name: values.full_name, email: values.email }; auth.setUser(updatedUser); // Reload profile await loadUserProfile(); } catch (error: any) { toast.error(error.response?.data?.detail || '更新失败'); } finally { setLoading(false); } }; const handleAvatarUpload = async (options: any) => { const { file } = options; const formData = new FormData(); formData.append('file', file); setUploading(true); try { const { data } = await request.post('/users/me/avatar', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }); toast.success('头像上传成功'); // Update local user info with new avatar URL auth.setUser({ ...user, avatar_url: data.avatar_url }); // Reload profile to get new avatar URL from backend await loadUserProfile(); } catch (error: any) { toast.error(error.response?.data?.detail || '头像上传失败'); } finally { setUploading(false); } }; // Construct full avatar URL const getAvatarUrl = () => { if (!userProfile?.avatar_url) return null; // Use relative path to allow proxying (Vite/Nginx) // The backend returns a relative path like "user/1/avatar/avatar.png" return `/upload/${userProfile.avatar_url}?t=${new Date().getTime()}`; }; return ( {/* User Avatar and Basic Info Card */}
} />

{userProfile?.full_name || userProfile?.username || '用户'}

@{userProfile?.username}

{userProfile && ( {userProfile.role === 'admin' ? '管理员' : '普通用户'} {new Date(userProfile.created_at).toLocaleString('zh-CN')} )}
{/* Edit Profile Form */}
} placeholder="请输入您的姓名" size="large" /> } placeholder="请输入邮箱地址(可选)" size="large" />
); }