import { useState, useEffect } from 'react'
import { Card, Tabs, Form, Input, Button, Avatar, Upload, message } from 'antd'
import { UserOutlined, LockOutlined, UploadOutlined } from '@ant-design/icons'
import ImgCrop from 'antd-img-crop'
import { getCurrentUser, updateProfile, changePassword, uploadAvatar } from '@/api/auth'
import useUserStore from '@/stores/userStore'
import Toast from '@/components/Toast/Toast'
import './ProfilePage.css'
function ProfilePage() {
const [loading, setLoading] = useState(false)
const [userInfo, setUserInfo] = useState(null)
const [profileForm] = Form.useForm()
const [passwordForm] = Form.useForm()
const { user, setUser } = useUserStore()
useEffect(() => {
loadUserInfo()
}, [])
// 加载用户信息
const loadUserInfo = async () => {
try {
const res = await getCurrentUser()
setUserInfo(res.data)
profileForm.setFieldsValue({
username: res.data.username,
nickname: res.data.nickname,
email: res.data.email,
phone: res.data.phone,
})
} catch (error) {
console.error('Load user info error:', error)
message.error('加载用户信息失败')
}
}
// 更新资料
const handleUpdateProfile = async (values) => {
setLoading(true)
try {
const res = await updateProfile({
nickname: values.nickname,
email: values.email,
phone: values.phone,
})
setUserInfo(res.data)
setUser(res.data) // 更新全局用户信息
Toast.success('更新成功', '个人资料已更新')
} catch (error) {
console.error('Update profile error:', error)
message.error(error.response?.data?.detail || '更新失败')
} finally {
setLoading(false)
}
}
// 修改密码
const handleChangePassword = async (values) => {
setLoading(true)
try {
await changePassword({
old_password: values.old_password,
new_password: values.new_password,
})
Toast.success('修改成功', '密码已修改,请重新登录')
passwordForm.resetFields()
// 2秒后跳转到登录页
setTimeout(() => {
window.location.href = '/login'
}, 2000)
} catch (error) {
console.error('Change password error:', error)
message.error(error.response?.data?.detail || '修改密码失败')
} finally {
setLoading(false)
}
}
// 上传头像前的验证
const beforeAvatarUpload = (file) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
if (!isJpgOrPng) {
Toast.error('格式错误', '仅支持 JPG、PNG 格式的图片')
return false
}
const isLt1M = file.size / 1024 / 1024 < 1
if (!isLt1M) {
Toast.error('文件过大', '图片大小不能超过 1MB')
return false
}
return true
}
// 处理头像上传
const handleAvatarUpload = async (info) => {
const { file } = info
setLoading(true)
try {
const res = await uploadAvatar(file)
setUserInfo(res.data)
setUser(res.data) // 更新全局用户信息
Toast.success('上传成功', '头像已更新')
} catch (error) {
console.error('Upload avatar error:', error)
Toast.error('上传失败', error.response?.data?.detail || '头像上传失败')
} finally {
setLoading(false)
}
}
// 获取头像URL
const getAvatarUrl = () => {
if (!userInfo?.avatar) return null
// avatar 字段存储的是相对路径,如:2/avatar/xxx.jpg
// 需要转换为 API 端点: /api/v1/auth/avatar/{user_id}/{filename}
const parts = userInfo.avatar.split('/')
if (parts.length >= 3) {
const userId = parts[0]
const filename = parts[2]
return `/api/v1/auth/avatar/${userId}/${filename}`
}
return null
}
const tabItems = [
{
key: 'profile',
label: (
支持 JPG、PNG 格式,文件小于 1MB