| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- import { postForm } from '@/request';
- import * as api from '@/services/login';
- import { message } from '@/utils/antdAppInstance';
- import { userKey } from '@/utils/authUtils';
- import { secureLocalStorage as ls } from '@/utils/localUtils';
- import {
- CloseOutlined,
- EditOutlined,
- LoadingOutlined,
- PlusOutlined,
- SaveOutlined,
- } from '@ant-design/icons';
- import { ProFormText } from '@ant-design/pro-components';
- import { useModel } from '@umijs/max';
- import { Avatar, Button, Card, Col, Form, Row, Space, Upload } from 'antd';
- import React, { useEffect, useState } from 'react';
- const UserInfo: React.FC = () => {
- const { initialState, setInitialState } = useModel('@@initialState');
- const [form] = Form.useForm();
- const [isEditing, setIsEditing] = useState(false);
- const [loading, setLoading] = useState(false);
- const [uploading, setUploading] = useState(false);
- const [userInfo, setUserInfo] = useState<API.UserInfo | null>(null);
- useEffect(() => {
- if (initialState?.currentUser) {
- setUserInfo(initialState.currentUser);
- form.setFieldsValue({
- username: initialState.currentUser.username,
- nickname: initialState.currentUser.nickname,
- avatar: initialState.currentUser.avatar,
- email: initialState.currentUser.email,
- phone: initialState.currentUser.phone,
- });
- }
- }, [initialState?.currentUser, form]);
- const handleEdit = () => {
- setIsEditing(true);
- };
- const handleCancel = () => {
- setIsEditing(false);
- if (userInfo) {
- form.setFieldsValue({
- username: userInfo.username,
- nickname: userInfo.nickname,
- avatar: userInfo.avatar,
- email: userInfo.email,
- phone: userInfo.phone,
- });
- }
- };
- const handleSave = async () => {
- try {
- const values = await form.validateFields();
- setLoading(true);
- const result = await api.fetchUserUpdateInfo({
- username: values.username,
- nickname: values.nickname,
- avatar: values.avatar,
- email: values.email,
- phone: values.phone,
- });
- if (result.success) {
- message.success('修改成功');
- setIsEditing(false);
- setInitialState((prev) => ({
- ...prev,
- currentUser: {
- ...prev?.currentUser,
- ...values,
- },
- }));
- const localUserInfo = ls.getLocal<API.UserInfo>(userKey);
- const newUserInfo = {
- ...localUserInfo,
- ...values,
- };
- ls.setLocal<API.UserInfo>(userKey, newUserInfo);
- setUserInfo(newUserInfo);
- } else {
- message.error(result.errorMessage || '修改失败');
- }
- } catch (error) {
- message.error('修改失败');
- } finally {
- setLoading(false);
- }
- };
- const handleAvatarUpload = async (options: any) => {
- const { file } = options;
- const isImage = file.type.startsWith('image/');
- if (!isImage) {
- message.error('只能上传图片文件!');
- return;
- }
- if (file.size / 1024 / 1024 > 1) {
- message.error('头像大小不能超过1MB');
- return;
- }
- setUploading(true);
- try {
- const formData = new FormData();
- formData.append('file', file);
- formData.append('fileType', 'avatar');
- const res = await postForm<API.Result<{ url: string; path: string }>>(
- '/minio/upload',
- formData,
- );
- if (res.success && res.data) {
- form.setFieldValue('avatar', res.data.path);
- setUserInfo((prev) => (prev ? { ...prev, avatar: res.data!.url } : prev));
- message.success('上传成功');
- } else {
- message.error(res.errorMessage || '上传失败');
- }
- } catch {
- message.error('上传失败');
- } finally {
- setUploading(false);
- }
- };
- if (!userInfo) {
- return <div>加载中...</div>;
- }
- return (
- <div style={{ padding: '24px' }}>
- <Card title="用户信息" style={{ maxWidth: 800, margin: '0 auto' }}>
- <Form form={form} layout="vertical">
- <Row gutter={24}>
- <Col span={12}>
- <ProFormText
- name="username"
- label="用户名"
- readonly={!isEditing}
- rules={[{ required: true, message: '请输入用户名' }]}
- formItemProps={{ layout: 'horizontal' }}
- fieldProps={{ disabled: true }}
- />
- <ProFormText
- name="nickname"
- label="昵称"
- readonly={!isEditing}
- rules={[{ required: true, message: '请输入昵称' }]}
- formItemProps={{ layout: 'horizontal' }}
- placeholder="请输入昵称"
- />
- <ProFormText
- name="email"
- label="邮箱"
- readonly={!isEditing}
- rules={[{ type: 'email', message: '请输入正确的邮箱格式' }]}
- formItemProps={{ layout: 'horizontal' }}
- placeholder="请输入邮箱"
- />
- <ProFormText
- name="phone"
- label="电话"
- readonly={!isEditing}
- formItemProps={{ layout: 'horizontal' }}
- placeholder="请输入电话"
- />
- </Col>
- <Col span={12}>
- <Form.Item name="avatar" hidden />
- <div style={{ textAlign: 'center' }}>
- <div style={{ marginBottom: 16 }}>
- <Avatar
- size={120}
- src={userInfo.avatar}
- style={{ border: '2px solid #f0f0f0' }}
- />
- </div>
- {isEditing && (
- <Upload
- showUploadList={false}
- customRequest={handleAvatarUpload}
- accept="image/*"
- >
- <Button icon={uploading ? <LoadingOutlined /> : <PlusOutlined />}>
- 上传头像
- </Button>
- </Upload>
- )}
- </div>
- </Col>
- </Row>
- </Form>
- <div style={{ textAlign: 'center', marginTop: 24 }}>
- {!isEditing ? (
- <Button type="primary" icon={<EditOutlined />} onClick={handleEdit}>
- 修改信息
- </Button>
- ) : (
- <Space>
- <Button type="primary" icon={<SaveOutlined />} onClick={handleSave} loading={loading}>
- 确定修改
- </Button>
- <Button icon={<CloseOutlined />} onClick={handleCancel}>
- 取消
- </Button>
- </Space>
- )}
- </div>
- </Card>
- </div>
- );
- };
- export default UserInfo;
|