【图文并茂】ant design pro 如何优雅奇妙地添加修改密码的功能

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上图所示,我们要加这样的一个功能,如何做呢?

首先要写好前端页面,再对接好后端,然后我们要判断当前密码是否正确,如果正确才能新密码修改好。

前端页面

src/pages/account/change-password/index.tsx

import { ProFormText, ProForm } from '@ant-design/pro-components';
import React, { useState } from 'react';
import { Alert, Button, Form, message } from 'antd';
import { updateItem } from '@/services/ant-design-pro/api';
import { useIntl } from '@umijs/max';

const ChangePassword: React.FC = () => {
  const [form] = Form.useForm();
  const [content, setContent] = useState<string | undefined>(undefined);
  const intl = useIntl();

  return (
    <div style={{ padding: 20 }}>
      <ProForm
        style={{ backgroundColor: 'white', padding: 20 }}
        form={form}
        onFinish={async (values) => {
          console.log('values', values);
          try {
            await updateItem('/auth/profile', values);
            message.success(intl.formatMessage({ id: 'password.changed.successfully' }));
            form.resetFields();
            setContent(undefined);
          } catch (err: any) {
            console.dir(err);
            setContent(err.response.data.message || err.message);
          }
        }}
        submitter={{
          render: (props) => {
            console.log(props);
            return [
              <Button type="primary" key="submit" onClick={() => props.form?.submit?.()}>
                {intl.formatMessage({ id: 'submit' })}
              </Button>,
            ];
          },
        }}
      >
        {content && (
          <Alert
            style={{
              marginBottom: 24,
              width: 330,
            }}
            message={content}
            type="error"
            showIcon
          />
        )}
        <ProFormText.Password
          name="currentPassword"
          label={intl.formatMessage({ id: 'current.password' })}
          width="md"
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'please.enter' }),
            },
          ]}
        />
        <ProFormText.Password
          name="password"
          label={intl.formatMessage({ id: 'new.password' })}
          width="md"
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'enter_password' }),
            },
          ]}
        />
        <ProFormText.Password
          name="confirmPassword"
          label={intl.formatMessage({ id: 'confirm.password' })}
          width="md"
          rules={[
            {
              required: true,
              message: intl.formatMessage({ id: 'please.enter' }),
            },
            ({ getFieldValue }) => ({
              validator(_, value) {
                if (!value || getFieldValue('password') === value) {
                  return Promise.resolve();
                }
                return Promise.reject(
                  new Error(intl.formatMessage({ id: 'passwords.must.match' })),
                );
              },
            }),
          ]}
        />
      </ProForm>
    </div>
  );
};

export default ChangePassword;

这个比较简单,

const [content, setContent] = useState<string | undefined>(undefined);

这里是设置错误信息用的。

onFinish={async (values) => {
          console.log('values', values);
          try {
            await updateItem('/auth/profile', values);
            message.success(intl.formatMessage({ id: 'password.changed.successfully' }));
            form.resetFields();
            setContent(undefined);
          } catch (err: any) {
            console.dir(err);
            setContent(err.response.data.message || err.message);
          }
        }}

这里是处理提交逻辑的。

await updateItem('/auth/profile', values);

这边发了一个请求

后端

在这里插入图片描述

const updateUserProfile = handleAsync(async (req: RequestCustom, res: Response) => {
  const { password, name, email, currentPassword, confirmPassword } = req.body;
  const userId = req.user?._id;

  if (!userId) {
    res.status(401);
    throw new Error('User not authenticated');
  }

  if (confirmPassword && confirmPassword !== password) {
    res.status(400);
    throw new Error('Passwords do not match');
  }

  const user = await User.findById(userId);

  if (!user) {
    res.status(404);
    throw new Error('User not found');
  }

  // 验证当前密码
  if (currentPassword && !(await bcrypt.compare(currentPassword, user.password))) {
    res.status(400);
    throw new Error('Current password is incorrect');
  }

  // 如果提供了新密码,则加密它
  let hashPassword = user.password;
  if (password) {
    const salt = await bcrypt.genSalt(10);
    hashPassword = await bcrypt.hash(password, salt);
  }

  const updatedUser = await User.findByIdAndUpdate(userId, {
    name: name || user.name,
    email: email || user.email,
    password: hashPassword,
  }, { new: true });

  res.json({
    success: true,
    name: updatedUser?.name,
    email: updatedUser?.email,
    token: generateToken(updatedUser!.id), // 注意: 请确保 generateToken 可以接受用户的 id 类型
  });
});

都有注释,应该能看明白。

完结。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值