如上图所示,我们要加这样的一个功能,如何做呢?
首先要写好前端页面,再对接好后端,然后我们要判断当前密码是否正确,如果正确才能新密码修改好。
前端页面
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 类型
});
});
都有注释,应该能看明白。
完结。
- 获取 ant design pro & nodejs & typescript 多角色权限动态菜单管理系统源码*
- 我正在做的程序员赚钱副业 - Shopify 真实案例技术赚钱营销课视频教程