完善验证页面和后端接口的链接
> 1. 配置了开发环境的端口转发 -> localhost:8080\
> 2. 完成了注册,登录,忘记密码页的功能
> 3. 为项目配置了vitest测试框架
> 4. 对这三个页面进行了测试

> 重写了/test/setup.ts

Change-Id: I46c600ce06d698dae6953b2e1e3ff4a98b0f3de4
diff --git a/src/feature/auth/Forget.tsx b/src/feature/auth/Forget.tsx
index 25bf6dc..a98ffcf 100644
--- a/src/feature/auth/Forget.tsx
+++ b/src/feature/auth/Forget.tsx
@@ -1,16 +1,74 @@
 import { MailOutlined, LockOutlined } from '@ant-design/icons';
-import { Button, Form, Input, message, Row, Col } from 'antd';
-import { NavLink } from 'react-router';
+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/authApi';
+
+// 定义表单值的类型
+interface FormValues {
+    email: string;
+    code: string;
+    password: string;
+    confirmPassword: string;
+}
+
 
 function Forget() {
     const [countdown, setCountdown] = useState(0);
-    const [emailSent,] = useState(false);
+    const [emailSent, setEmailSent] = useState(false); // 是否已发送验证码
+    const [form] = useForm<FormValues>();
+    const emailValue = Form.useWatch('email', form);
+    const [messageApi, contextHolder] = message.useMessage();
+    const nav = useNavigate(); // 页面跳转
 
-    const onFinish = async () => {
+    // 校验邮箱格式
+    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;
 
@@ -27,92 +85,117 @@
         };
     }, [countdown]);
 
+    // 重新发送验证码
     const resendCode = () => {
         if (countdown > 0) return;
         setCountdown(60);
-        message.info('验证码已重新发送');
+        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
-            name="forget"
-            initialValues={{ remember: true }}
-            style={{ maxWidth: 360 }}
-            onFinish={onFinish}
-        >
-            <h2>重置密码</h2>
-            <p>请输入您注册时使用的邮箱地址</p>
-
-            <Form.Item
-                name="email"
-                rules={[
-                    { required: true, message: '请输入您的邮箱!' },
-                    { type: 'email', message: '请输入正确的邮箱格式' }
-                ]}
+        <>
+            <Form
+                form={form}
+                name="forget"
+                initialValues={{ remember: false }}
+                onFinish={onFinish}
             >
-                <Input prefix={<MailOutlined />} placeholder="注册邮箱" />
-            </Form.Item>
+                {contextHolder}
+                <h2>重置密码</h2>
+                <p>请输入您注册时使用的邮箱地址</p>
 
-            {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="email"
+                    rules={[
+                        { required: true, message: '请输入您的邮箱!' },
+                        { type: 'email', message: '请输入正确的邮箱格式' }
+                    ]}
+                >
+                    <Input prefix={<MailOutlined />} placeholder="注册邮箱" />
+                </Form.Item>
 
-                    <Form.Item
-                        name="password"
-                        rules={[
-                            { required: true, message: '请设置新密码!' },
-                            { min: 6, message: '密码长度至少为6位' }
-                        ]}
-                    >
-                        <Input.Password prefix={<LockOutlined />} 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="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
+                            name="password"
+                            rules={[
+                                { required: true, message: '请设置新密码!' },
+                                { min: 6, message: '密码长度至少为6位' }
+                            ]}
+                        >
+                            <Input.Password prefix={<LockOutlined />} placeholder="新密码" />
+                        </Form.Item>
 
-            <Form.Item>
-                <Button block type="primary" htmlType="submit">
-                    {emailSent ? '确认重置' : '获取验证码'}
-                </Button>
-                或 <NavLink to='/login'>返回登录</NavLink>
-            </Form.Item>
-        </Form>
+                        <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;    
\ No newline at end of file
+export default Forget;