blob: 00c7793a5eb7b790ece92cec437e3cd521a54006 [file] [log] [blame] [edit]
import { MailOutlined, LockOutlined } from '@ant-design/icons';
import { Button, Form, Input, message, Row, Col, Modal } from 'antd';
import { NavLink, useNavigate } from 'react-router';
import { useState, useEffect } from 'react';
import { useForm } from 'antd/es/form/Form';
import authApi from '../../api/Auth/AuthApi';
// 定义表单值的类型
interface FormValues {
email: string;
code: string;
password: string;
confirmPassword: string;
}
function Forget() {
const [countdown, setCountdown] = useState(0);
const [emailSent, setEmailSent] = useState(false); // 是否已发送验证码
const [form] = useForm<FormValues>();
const emailValue = Form.useWatch('email', form);
const [messageApi, contextHolder] = message.useMessage();
const nav = useNavigate(); // 页面跳转
// 校验邮箱格式
function isValidEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test(email))
console.log(email)
return emailRegex.test(email);
}
// 发送验证码
const sendResetCode = async () => {
if (!isValidEmail(emailValue)) {
form.validateFields(['email']);
return;
}
await authApi.sendResetCode(emailValue).then(() => {
setEmailSent(true);
setCountdown(60);
}).catch((error) => {
messageApi.error(error?.message || '验证码发送失败');
});
};
const [modal, modalContext] = Modal.useModal();
const countDownNav = (onOk: () => void) => {
let secondsToGo = 5;
const instance = modal.success({
title: '重置成功',
content: `系统将在 ${secondsToGo} 后跳转到登陆页面.`,
okText: "立即跳转",
onOk
});
const timer = setInterval(() => {
secondsToGo -= 1;
instance.update({
content: `将在 ${secondsToGo} 后回到登陆页面.`,
});
}, 1000);
setTimeout(() => {
clearInterval(timer);
instance.destroy();
}, secondsToGo * 1000);
};
// 倒计时发送
useEffect(() => {
let countdownTimer = null;
if (countdown > 0) {
countdownTimer = setTimeout(() => {
setCountdown(prev => prev - 1);
}, 1000);
}
return () => {
if (countdownTimer) {
clearTimeout(countdownTimer);
}
};
}, [countdown]);
// 重新发送验证码
const resendCode = () => {
if (countdown > 0) return;
setCountdown(60);
sendResetCode(); // 重新发送验证码
};
// 表单提交处理
const onFinish = (values: FormValues) => {
if (!emailSent) {
sendResetCode();
} else {
console.log(values);
authApi.resetPassword({
email: values.email,
code: values.code,
newPassword: values.password,
}).then((response) => {
if (response.data.code == 0) {
countDownNav(() => nav('/login'))
} else {
messageApi.error(response.data.message);
}
})
}
};
return (
<>
<Form
form={form}
name="forget"
initialValues={{ remember: false }}
onFinish={onFinish}
>
{contextHolder}
<h2>重置密码</h2>
<p>请输入您注册时使用的邮箱地址</p>
<Form.Item
name="email"
rules={[
{ required: true, message: '请输入您的邮箱!' },
{ type: 'email', message: '请输入正确的邮箱格式' }
]}
>
<Input prefix={<MailOutlined />} placeholder="注册邮箱" />
</Form.Item>
{emailSent && (
<>
<Form.Item
name="code"
rules={[{ required: true, message: '请输入验证码!' }]}
>
<Row gutter={8}>
<Col span={16}>
<Input placeholder="验证码" />
</Col>
<Col span={8}>
<Button
disabled={countdown > 0}
onClick={resendCode}
style={{ width: '100%' }}
>
{countdown > 0 ? `${countdown}s后重试` : '重新发送'}
</Button>
</Col>
</Row>
</Form.Item>
<Form.Item
name="password"
rules={[
{ required: true, message: '请设置新密码!' },
{ min: 6, message: '密码长度至少为6位' }
]}
>
<Input.Password prefix={<LockOutlined />} placeholder="新密码" />
</Form.Item>
<Form.Item
name="confirmPassword"
dependencies={['password']}
rules={[
{ required: true, message: '请确认新密码!' },
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('两次输入的密码不一致!'));
},
}),
]}
>
<Input.Password prefix={<LockOutlined />} placeholder="确认新密码" />
</Form.Item>
</>
)}
<Form.Item>
<Button block type="primary" htmlType="submit">
{emailSent ? '确认重置' : '获取验证码'}
</Button>
<NavLink to='/login'>返回登录</NavLink>
</Form.Item>
</Form>
{modalContext}
</>
);
}
export default Forget;