blob: 00c7793a5eb7b790ece92cec437e3cd521a54006 [file] [log] [blame]
22301014bc4616f2025-06-03 16:59:44 +08001import { MailOutlined, LockOutlined } from '@ant-design/icons';
2230101462240ab2025-06-07 09:28:16 +08002import { Button, Form, Input, message, Row, Col, Modal } from 'antd';
3import { NavLink, useNavigate } from 'react-router';
22301014bc4616f2025-06-03 16:59:44 +08004import { useState, useEffect } from 'react';
2230101462240ab2025-06-07 09:28:16 +08005import { useForm } from 'antd/es/form/Form';
22301014b1477f72025-06-07 22:54:40 +08006import authApi from '../../api/Auth/AuthApi';
2230101462240ab2025-06-07 09:28:16 +08007
8// 定义表单值的类型
9interface FormValues {
10 email: string;
11 code: string;
12 password: string;
13 confirmPassword: string;
14}
15
22301014bc4616f2025-06-03 16:59:44 +080016
17function Forget() {
18 const [countdown, setCountdown] = useState(0);
2230101462240ab2025-06-07 09:28:16 +080019 const [emailSent, setEmailSent] = useState(false); // 是否已发送验证码
20 const [form] = useForm<FormValues>();
21 const emailValue = Form.useWatch('email', form);
22 const [messageApi, contextHolder] = message.useMessage();
23 const nav = useNavigate(); // 页面跳转
22301014bc4616f2025-06-03 16:59:44 +080024
2230101462240ab2025-06-07 09:28:16 +080025 // 校验邮箱格式
26 function isValidEmail(email: string): boolean {
27 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
28 console.log(emailRegex.test(email))
29 console.log(email)
30 return emailRegex.test(email);
31 }
22301014bc4616f2025-06-03 16:59:44 +080032
2230101462240ab2025-06-07 09:28:16 +080033 // 发送验证码
34 const sendResetCode = async () => {
35 if (!isValidEmail(emailValue)) {
36 form.validateFields(['email']);
37 return;
38 }
39
40 await authApi.sendResetCode(emailValue).then(() => {
41 setEmailSent(true);
42 setCountdown(60);
43 }).catch((error) => {
44 messageApi.error(error?.message || '验证码发送失败');
45 });
22301014bc4616f2025-06-03 16:59:44 +080046 };
47
2230101462240ab2025-06-07 09:28:16 +080048 const [modal, modalContext] = Modal.useModal();
49
50 const countDownNav = (onOk: () => void) => {
51 let secondsToGo = 5;
52 const instance = modal.success({
53 title: '重置成功',
54 content: `系统将在 ${secondsToGo} 后跳转到登陆页面.`,
55 okText: "立即跳转",
56 onOk
57 });
58
59 const timer = setInterval(() => {
60 secondsToGo -= 1;
61 instance.update({
62 content: `将在 ${secondsToGo} 后回到登陆页面.`,
63 });
64 }, 1000);
65
66 setTimeout(() => {
67 clearInterval(timer);
68 instance.destroy();
69 }, secondsToGo * 1000);
70 };
71 // 倒计时发送
22301014bc4616f2025-06-03 16:59:44 +080072 useEffect(() => {
73 let countdownTimer = null;
74
75 if (countdown > 0) {
76 countdownTimer = setTimeout(() => {
77 setCountdown(prev => prev - 1);
78 }, 1000);
79 }
80
81 return () => {
82 if (countdownTimer) {
83 clearTimeout(countdownTimer);
84 }
85 };
86 }, [countdown]);
87
2230101462240ab2025-06-07 09:28:16 +080088 // 重新发送验证码
22301014bc4616f2025-06-03 16:59:44 +080089 const resendCode = () => {
90 if (countdown > 0) return;
91 setCountdown(60);
2230101462240ab2025-06-07 09:28:16 +080092 sendResetCode(); // 重新发送验证码
93 };
94
95 // 表单提交处理
96 const onFinish = (values: FormValues) => {
97 if (!emailSent) {
98 sendResetCode();
99 } else {
100 console.log(values);
101 authApi.resetPassword({
102 email: values.email,
103 code: values.code,
104 newPassword: values.password,
105 }).then((response) => {
106 if (response.data.code == 0) {
107 countDownNav(() => nav('/login'))
108 } else {
109 messageApi.error(response.data.message);
110 }
111 })
112 }
22301014bc4616f2025-06-03 16:59:44 +0800113 };
114
115 return (
2230101462240ab2025-06-07 09:28:16 +0800116 <>
117 <Form
118 form={form}
119 name="forget"
120 initialValues={{ remember: false }}
121 onFinish={onFinish}
22301014bc4616f2025-06-03 16:59:44 +0800122 >
2230101462240ab2025-06-07 09:28:16 +0800123 {contextHolder}
124 <h2>重置密码</h2>
125 <p>请输入您注册时使用的邮箱地址</p>
22301014bc4616f2025-06-03 16:59:44 +0800126
2230101462240ab2025-06-07 09:28:16 +0800127 <Form.Item
128 name="email"
129 rules={[
130 { required: true, message: '请输入您的邮箱!' },
131 { type: 'email', message: '请输入正确的邮箱格式' }
132 ]}
133 >
134 <Input prefix={<MailOutlined />} placeholder="注册邮箱" />
135 </Form.Item>
22301014bc4616f2025-06-03 16:59:44 +0800136
2230101462240ab2025-06-07 09:28:16 +0800137 {emailSent && (
138 <>
139 <Form.Item
140 name="code"
141 rules={[{ required: true, message: '请输入验证码!' }]}
142 >
143 <Row gutter={8}>
144 <Col span={16}>
145 <Input placeholder="验证码" />
146 </Col>
147 <Col span={8}>
148 <Button
149 disabled={countdown > 0}
150 onClick={resendCode}
151 style={{ width: '100%' }}
152 >
153 {countdown > 0 ? `${countdown}s后重试` : '重新发送'}
154 </Button>
155 </Col>
156 </Row>
157 </Form.Item>
22301014bc4616f2025-06-03 16:59:44 +0800158
2230101462240ab2025-06-07 09:28:16 +0800159 <Form.Item
160 name="password"
161 rules={[
162 { required: true, message: '请设置新密码!' },
163 { min: 6, message: '密码长度至少为6位' }
164 ]}
165 >
166 <Input.Password prefix={<LockOutlined />} placeholder="新密码" />
167 </Form.Item>
22301014bc4616f2025-06-03 16:59:44 +0800168
2230101462240ab2025-06-07 09:28:16 +0800169 <Form.Item
170 name="confirmPassword"
171 dependencies={['password']}
172 rules={[
173 { required: true, message: '请确认新密码!' },
174 ({ getFieldValue }) => ({
175 validator(_, value) {
176 if (!value || getFieldValue('password') === value) {
177 return Promise.resolve();
178 }
179 return Promise.reject(new Error('两次输入的密码不一致!'));
180 },
181 }),
182 ]}
183 >
184 <Input.Password prefix={<LockOutlined />} placeholder="确认新密码" />
185 </Form.Item>
186 </>
187 )}
188
189 <Form.Item>
190 <Button block type="primary" htmlType="submit">
191 {emailSent ? '确认重置' : '获取验证码'}
192 </Button>
193 <NavLink to='/login'>返回登录</NavLink>
194 </Form.Item>
195 </Form>
196 {modalContext}
197 </>
22301014bc4616f2025-06-03 16:59:44 +0800198 );
199}
200
2230101462240ab2025-06-07 09:28:16 +0800201export default Forget;