加入了登录注册页面(ptstation-register文件夹),需启动react前端和创建虚拟环境并安装requirements.txt并运行run_server.py

Change-Id: I6abba3854c517286245d118a591e00761ac98685
diff --git a/react-ui/src/locales/zh-CN/pages.ts b/react-ui/src/locales/zh-CN/pages.ts
index fc7abfb..5d13109 100644
--- a/react-ui/src/locales/zh-CN/pages.ts
+++ b/react-ui/src/locales/zh-CN/pages.ts
@@ -1,7 +1,7 @@
 export default {
-  'pages.layouts.userLayout.title': 'Ant Design 是西湖区最具影响力的 Web 设计规范',
+  'pages.layouts.userLayout.title': 'Welcome!',
   'pages.login.accountLogin.tab': '账户密码登录',
-  'pages.login.accountLogin.errorMessage': '错误的用户名和密码(admin/admin123)',
+  'pages.login.accountLogin.errorMessage': '错误的用户名和密码',
   'pages.login.failure': '登录失败,请重试!',
   'pages.login.success': '登录成功!',
   'pages.login.username.placeholder': '用户名: admin',
diff --git a/react-ui/src/pages/User/Login/index.tsx b/react-ui/src/pages/User/Login/index.tsx
index a18f785..87759c3 100644
--- a/react-ui/src/pages/User/Login/index.tsx
+++ b/react-ui/src/pages/User/Login/index.tsx
@@ -1,6 +1,8 @@
 import Footer from '@/components/Footer';
 import { getCaptchaImg, login } from '@/services/system/auth';
 import { getFakeCaptcha } from '@/services/ant-design-pro/login';
+import { Modal, Form, Input, Button } from 'antd';
+
 import {
   AlipayCircleOutlined,
   LockOutlined,
@@ -90,6 +92,8 @@
   const { initialState, setInitialState } = useModel('@@initialState');
   const [captchaCode, setCaptchaCode] = useState<string>('');
   const [uuid, setUuid] = useState<string>('');
+const [forgotModalVisible, setForgotModalVisible] = useState(false);
+const [form] = Form.useForm();
 
   const containerClassName = useEmotionCss(() => {
     return {
@@ -190,50 +194,37 @@
             maxWidth: '75vw',
           }}
           logo={<img alt="logo" src="/logo.svg" />}
-          title="Ant Design"
+          title="PT Station"
           subTitle={intl.formatMessage({ id: 'pages.layouts.userLayout.title' })}
           initialValues={{
             autoLogin: true,
           }}
           actions={[
-            <FormattedMessage
-              key="loginWith"
-              id="pages.login.loginWith"
-              defaultMessage="其他登录方式"
-            />,
-            <ActionIcons key="icons" />,
+
           ]}
           onFinish={async (values) => {
             await handleSubmit(values as API.LoginParams);
           }}
-        >
-          <Tabs
-            activeKey={type}
-            onChange={setType}
-            centered
-            items={[
-              {
-                key: 'account',
-                label: intl.formatMessage({
-                  id: 'pages.login.accountLogin.tab',
-                  defaultMessage: '账户密码登录',
-                }),
-              },
-              {
-                key: 'mobile',
-                label: intl.formatMessage({
-                  id: 'pages.login.phoneLogin.tab',
-                  defaultMessage: '手机号登录',
-                }),
-              },
-            ]}
-          />
+        ><Tabs
+  activeKey={type}
+  onChange={setType}
+  centered
+  items={[
+    {
+      key: 'account',
+      label: intl.formatMessage({
+        id: 'pages.login.accountLogin.tab',
+        defaultMessage: '账户密码登录',
+      }),
+    },
+  ]}
+/>
 
           {code !== 200 && loginType === 'account' && (
             <LoginMessage
               content={intl.formatMessage({
                 id: 'pages.login.accountLogin.errorMessage',
-                defaultMessage: '账户或密码错误(admin/admin123)',
+                defaultMessage: '账户或密码错误',
               })}
             />
           )}
@@ -302,7 +293,7 @@
                         message: (
                           <FormattedMessage
                             id="pages.searchTable.updateForm.ruleName.nameRules"
-                            defaultMessage="请输入验证啊"
+                            defaultMessage="请输入验证"
                           />
                         ),
                       },
@@ -418,18 +409,134 @@
             <ProFormCheckbox noStyle name="autoLogin">
               <FormattedMessage id="pages.login.rememberMe" defaultMessage="自动登录" />
             </ProFormCheckbox>
-            <a
-              style={{
-                float: 'right',
-              }}
-            >
-              <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码" />
-            </a>
+        <a
+          style={{ float: 'right' }}
+          onClick={() => setForgotModalVisible(true)}
+        >
+          <FormattedMessage id="pages.login.forgotPassword" defaultMessage="忘记密码?" />
+        </a>
+
           </div>
         </LoginForm>
+<div style={{ textAlign: 'center', marginTop: 16 }}>
+  <span style={{ marginRight: 8 }}>
+    <FormattedMessage id="pages.login.noAccount" defaultMessage="没有账号?" />
+  </span>
+  <a href="http://localhost:5173/" target="_self">
+    <FormattedMessage id="pages.login.registerNow" defaultMessage="立即注册" />
+  </a>
+</div>
+
+
       </div>
+
+
+      <Modal
+  title="重置密码"
+  open={forgotModalVisible}
+  onCancel={() => setForgotModalVisible(false)}
+  footer={null}
+>
+<Form
+  form={form}
+  onFinish={async (values) => {
+    const { email, code, newPassword, confirmPassword } = values;
+
+    if (newPassword !== confirmPassword) {
+      message.error('两次密码输入不一致');
+      return;
+    }
+
+    const res = await fetch('http://127.0.0.1:6001/reset-password', {
+      method: 'POST',
+      headers: { 'Content-Type': 'application/json' },
+
+      body: JSON.stringify({ email, code, newPassword }),
+    });
+    const data = await res.json();
+
+    if (data.success) {
+      message.success('密码重置成功');
+      setForgotModalVisible(false);
+      form.resetFields();
+    } else {
+      message.error(data.message || '重置失败');
+    }
+  }}
+>
+  <Form.Item name="email" rules={[{ required: true, message: '请输入邮箱' }, { type: 'email' }]}>
+    <Input placeholder="邮箱" />
+  </Form.Item>
+
+  <Form.Item name="code" rules={[{ required: true, message: '请输入验证码' }]}>
+    <Input
+      placeholder="验证码"
+      addonAfter={
+        <a
+          onClick={async () => {
+            const email = form.getFieldValue('email');
+            if (!email) return message.warning('请先输入邮箱');
+            const res = await fetch('http://127.0.0.1:6001/send-code', {
+              method: 'POST',
+              headers: { 'Content-Type': 'application/json' },
+              body: JSON.stringify({ email }),
+            });
+            const result = await res.json();
+            if (result.success) {
+              message.success('验证码发送成功');
+            } else {
+              message.error(result.message || '验证码发送失败');
+            }
+          }}
+        >
+          获取验证码
+        </a>
+      }
+    />
+  </Form.Item>
+
+  <Form.Item
+    name="newPassword"
+    rules={[{ required: true, message: '请输入新密码' }]}
+    hasFeedback
+  >
+    <Input.Password placeholder="新密码" />
+  </Form.Item>
+
+  <Form.Item
+    name="confirmPassword"
+    dependencies={['newPassword']}
+    hasFeedback
+    rules={[
+      { required: true, message: '请确认新密码' },
+      ({ getFieldValue }) => ({
+        validator(_, value) {
+          if (!value || getFieldValue('newPassword') === value) {
+            return Promise.resolve();
+          }
+          return Promise.reject(new Error('两次密码输入不一致'));
+        },
+      }),
+    ]}
+  >
+    <Input.Password placeholder="确认密码" />
+  </Form.Item>
+
+  <Form.Item>
+    <Button type="primary" htmlType="submit" block>
+      重置密码
+    </Button>
+  </Form.Item>
+</Form>
+
+</Modal>
+
       <Footer />
     </div>
+
+
+
+
   );
 };