Browse Source

登录 注册

main
lk 1 week ago
parent
commit
b769e740b1
  1. 25
      src/pages/use/login/index.tsx
  2. 30
      src/pages/use/password/retrieve.tsx
  3. 59
      src/pages/use/register/index.tsx
  4. 12
      src/pages/use/useTools.tsx
  5. 6
      src/service/system.ts
  6. 17
      src/store/system/user.ts
  7. 2
      vite.config.ts

25
src/pages/use/login/index.tsx

@ -35,7 +35,7 @@ const Login = memo(() => {
const email = emailform.getFieldValue("email"); const email = emailform.getFieldValue("email");
setCountdown(10); setCountdown(10);
setIsButtonDisabled(true); setIsButtonDisabled(true);
emailCodeMutate({ email });
emailCodeMutate({ is_register: false, email });
}; };
const emailhandleSubmit = (values: any) => { const emailhandleSubmit = (values: any) => {
emailLoginMutate(values); emailLoginMutate(values);
@ -114,14 +114,19 @@ const Login = memo(() => {
height: "400px", height: "400px",
}} }}
> >
<Tabs defaultActiveKey="1">
<Tabs defaultActiveKey="1" style={{ marginTop: "50px" }}>
<TabPane tab="邮箱密码登录" key="1"> <TabPane tab="邮箱密码登录" key="1">
<Form form={upform} onFinish={uphandleSubmit}> <Form form={upform} onFinish={uphandleSubmit}>
<Form.Item name="username" rules={[{ required: true, message: "请输入邮箱" }]}> <Form.Item name="username" rules={[{ required: true, message: "请输入邮箱" }]}>
<Input size="large" placeholder="请输入邮箱" prefix={<UserOutlined />} /> <Input size="large" placeholder="请输入邮箱" prefix={<UserOutlined />} />
</Form.Item> </Form.Item>
<Form.Item name="password" rules={[{ required: true, message: "请输入登录密码" }]}> <Form.Item name="password" rules={[{ required: true, message: "请输入登录密码" }]}>
<Input.Password size="large" placeholder="请输入登录密码" prefix={<LockOutlined />} />
<Input.Password
size="large"
placeholder="请输入登录密码"
prefix={<LockOutlined />}
autoComplete="off"
/>
</Form.Item> </Form.Item>
{/*<Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}>*/} {/*<Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}>*/}
{/* <Input.Password size="large" placeholder="验证码" prefix={<LockOutlined />} />*/} {/* <Input.Password size="large" placeholder="验证码" prefix={<LockOutlined />} />*/}
@ -146,7 +151,12 @@ const Login = memo(() => {
/> />
</Form.Item> </Form.Item>
<Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}> <Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}>
<Input.Password size="large" placeholder="请输入验证码" prefix={<LockOutlined />} />
<Input.Password
size="large"
placeholder="请输入验证码"
prefix={<LockOutlined />}
autoComplete="off"
/>
</Form.Item> </Form.Item>
<Button type="primary" htmlType="submit" style={{ width: "100%" }}> <Button type="primary" htmlType="submit" style={{ width: "100%" }}>
@ -168,7 +178,12 @@ const Login = memo(() => {
/> />
</Form.Item> </Form.Item>
<Form.Item name="code" rules={[{ required: true, message: "请输入飞机验证码" }]}> <Form.Item name="code" rules={[{ required: true, message: "请输入飞机验证码" }]}>
<Input.Password size="large" placeholder="请输入飞机验证码" prefix={<LockOutlined />} />
<Input.Password
size="large"
placeholder="请输入飞机验证码"
prefix={<LockOutlined />}
autoComplete="off"
/>
</Form.Item> </Form.Item>
<Button type="primary" htmlType="submit" style={{ width: "100%" }}> <Button type="primary" htmlType="submit" style={{ width: "100%" }}>

30
src/pages/use/password/retrieve.tsx

@ -4,6 +4,7 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import React, { memo, useEffect, useState } from "react"; import React, { memo, useEffect, useState } from "react";
import { emailCodeAtom } from "@/store/system/user.ts"; import { emailCodeAtom } from "@/store/system/user.ts";
import {passwordRules} from "@/pages/use/useTools.tsx";
const { Title, Text, Link } = Typography; const { Title, Text, Link } = Typography;
const PwdRetrieve = memo(() => { const PwdRetrieve = memo(() => {
@ -85,13 +86,32 @@ const PwdRetrieve = memo(() => {
/> />
</Form.Item> </Form.Item>
<Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}> <Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}>
<Input size="large" placeholder="请输入验证码" prefix={<SecurityScanOutlined />} />
<Input size="large" placeholder="请输入验证码" prefix={<SecurityScanOutlined />} autoComplete="off" />
</Form.Item> </Form.Item>
<Form.Item name="password" rules={[{ required: true, message: "请输入新密码" }]}>
<Input.Password size="large" placeholder="请输入新密码" prefix={<LockOutlined />} />
<Form.Item name="password" rules={passwordRules}>
<Input.Password
size="large"
placeholder="请输入新密码"
prefix={<LockOutlined />}
autoComplete="off"
/>
</Form.Item> </Form.Item>
<Form.Item name="confirmPassword" rules={[{ required: true, message: "请确认新密码" }]}>
<Input.Password size="large" placeholder="请确认新密码" prefix={<LockOutlined />} />
<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 size="large" placeholder="请确认密码" prefix={<LockOutlined />} autoComplete="off" />
</Form.Item> </Form.Item>
<Button type="primary" htmlType="submit" style={{ width: "100%" }}> <Button type="primary" htmlType="submit" style={{ width: "100%" }}>

59
src/pages/use/register/index.tsx

@ -1,32 +1,41 @@
import { Layout, Input, Button, Typography, Row, Col, Form } from "antd"; import { Layout, Input, Button, Typography, Row, Col, Form } from "antd";
import { LockOutlined, MailOutlined, SecurityScanOutlined } from "@ant-design/icons"; import { LockOutlined, MailOutlined, SecurityScanOutlined } from "@ant-design/icons";
import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useAtomValue } from "jotai";
import { useAtom, useAtomValue } from "jotai";
import React, { memo, useEffect, useState } from "react"; import React, { memo, useEffect, useState } from "react";
import { emailCodeAtom } from "@/store/system/user.ts";
import { emailCodeAtom, emailRegisterAtom } from "@/store/system/user.ts";
import { passwordRules } from "@/pages/use/useTools";
const { Title, Text, Link } = Typography; const { Title, Text, Link } = Typography;
const Register = memo(() => { const Register = memo(() => {
const navigate = useNavigate(); const navigate = useNavigate();
const [registerForm] = Form.useForm(); const [registerForm] = Form.useForm();
const { mutate: emailCodeMutate } = useAtomValue(emailCodeAtom);
const handleRegisterSubmit = (values: any) => {
console.log(values);
// 调用注册API
};
const handleGetCode = () => {
const { mutate: emailRegisterMutate } = useAtomValue(emailRegisterAtom);
const { mutateAsync: emailCodeMutate, data: emailData } = useAtomValue(emailCodeAtom);
//const [{ mutate: emailCodeMutate, data: emailData }] = useAtom(emailCodeAtom);
//const [, mutate: emailCodeMutate] = useAtom(emailCodeAtom);
const getEmailCode = () => {
const email = registerForm.getFieldValue("email"); const email = registerForm.getFieldValue("email");
setCountdown(10); setCountdown(10);
setIsButtonDisabled(true); setIsButtonDisabled(true);
emailCodeMutate({ email });
const data = emailCodeMutate({ is_register: true, email });
console.log(data);
};
const emailRegisterSubmit = (values: any) => {
emailRegisterMutate({ email: values.email, password: values.password, code: values.code });
}; };
const [countdown, setCountdown] = useState<number>(0); const [countdown, setCountdown] = useState<number>(0);
const [isButtonDisabled, setIsButtonDisabled] = useState<boolean>(false); const [isButtonDisabled, setIsButtonDisabled] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
if ((emailData as any)?.countdown === -1) {
setCountdown(0);
setIsButtonDisabled(false);
}
}, [emailData]);
useEffect(() => {
let timer: number; let timer: number;
if (countdown > 0) { if (countdown > 0) {
timer = setTimeout(() => setCountdown(countdown - 1), 1000); timer = setTimeout(() => setCountdown(countdown - 1), 1000);
@ -71,27 +80,41 @@ const Register = memo(() => {
height: "500px", height: "500px",
}} }}
> >
<Form form={registerForm} onFinish={handleRegisterSubmit} style={{ marginTop: "50px" }}>
<Form form={registerForm} onFinish={emailRegisterSubmit} style={{ marginTop: "50px" }}>
<Form.Item name="email" rules={[{ required: true, message: "请输入邮箱" }]}> <Form.Item name="email" rules={[{ required: true, message: "请输入邮箱" }]}>
<Input <Input
size="large" size="large"
placeholder="请输入邮箱" placeholder="请输入邮箱"
prefix={<MailOutlined />} prefix={<MailOutlined />}
addonAfter={ addonAfter={
<Button onClick={handleGetCode} disabled={isButtonDisabled}>
<Button onClick={getEmailCode} disabled={isButtonDisabled}>
{isButtonDisabled ? `${countdown}秒后重试` : "获得验证码"} {isButtonDisabled ? `${countdown}秒后重试` : "获得验证码"}
</Button> </Button>
} }
/> />
</Form.Item> </Form.Item>
<Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}> <Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}>
<Input size="large" placeholder="请输入验证码" prefix={<SecurityScanOutlined />} />
<Input size="large" placeholder="请输入验证码" prefix={<SecurityScanOutlined />} autoComplete="off" />
</Form.Item> </Form.Item>
<Form.Item name="password" rules={[{ required: true, message: "请输入密码" }]}>
<Input.Password size="large" placeholder="请输入密码" prefix={<LockOutlined />} />
<Form.Item name="password" rules={passwordRules}>
<Input.Password size="large" placeholder="请输入密码" prefix={<LockOutlined />} autoComplete="off" />
</Form.Item> </Form.Item>
<Form.Item name="confirmPassword" rules={[{ required: true, message: "请确认密码" }]}>
<Input.Password size="large" placeholder="请确认密码" prefix={<LockOutlined />} />
<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 size="large" placeholder="请确认密码" prefix={<LockOutlined />} autoComplete="off" />
</Form.Item> </Form.Item>
<Button type="primary" htmlType="submit" style={{ width: "100%" }}> <Button type="primary" htmlType="submit" style={{ width: "100%" }}>

12
src/pages/use/useTools.tsx

@ -0,0 +1,12 @@
export const passwordRules = [
{ required: true, message: "请输入密码" },
{
pattern: /^(?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*\d)|(?=.*[a-z])(?=.*[!@#$%^&*])|(?=.*[A-Z])(?=.*\d)|(?=.*[A-Z])(?=.*[!@#$%^&*])|(?=.*\d)(?=.*[!@#$%^&*])/,
message: "密码必须包含至少两种字符类型:英文大写、英文小写、数字、符号",
},
{
min: 6,
max: 20,
message: "密码长度必须在6到20位之间",
},
];

6
src/service/system.ts

@ -23,6 +23,10 @@ const systemServ = {
emailLogin: (data: any) => { emailLogin: (data: any) => {
return request.post<System.LoginResponse>("/sys/login/email", data); return request.post<System.LoginResponse>("/sys/login/email", data);
}, },
emailRegister: (data: any) => {
return request.post<System.LoginResponse>("/sys/email/reg", data);
},
telegramCode: (data: any) => { telegramCode: (data: any) => {
return request.post<System.LoginResponse>("/sys/telegram", data); return request.post<System.LoginResponse>("/sys/telegram", data);
@ -32,6 +36,8 @@ const systemServ = {
return request.post<System.LoginResponse>("/sys/login/telegram", data); return request.post<System.LoginResponse>("/sys/login/telegram", data);
}, },
logout: () => { logout: () => {
// //
}, },

17
src/store/system/user.ts

@ -53,9 +53,9 @@ export const emailCodeAtom = atomWithMutation<any, any>((get) => ({
return await systemServ.emailCode(params); return await systemServ.emailCode(params);
}, },
onSuccess: (res) => { onSuccess: (res) => {
//message.success(t("login.success"));
// console.log('login success', res)
//get(userMenuDataAtom).refetch().then();
if(res.data.countdown===-1){
message.error(res.message);
}
return res.data; return res.data;
}, },
retry: false, retry: false,
@ -72,6 +72,17 @@ export const emailLoginAtom = atomWithMutation<any, any>((get) => ({
}, },
retry: false, retry: false,
})); }));
export const emailRegisterAtom = atomWithMutation<any, any>((get) => ({
mutationKey: ["emailRegister"],
mutationFn: async (params) => {
return await systemServ.emailRegister(params);
},
onSuccess: (res) => {
// console.log('login success', res)
return res.data;
},
retry: false,
}));
export const telegramCodeAtom = atomWithMutation<any, any>((get) => ({ export const telegramCodeAtom = atomWithMutation<any, any>((get) => ({
mutationKey: ["telegramCode"], mutationKey: ["telegramCode"],

2
vite.config.ts

@ -14,7 +14,7 @@ const proxyMap = {
//'/api/v1/certold': 'http://192.168.31.41:8000', //'/api/v1/certold': 'http://192.168.31.41:8000',
"/api/v1/cert": "http://127.0.0.1:8000", "/api/v1/cert": "http://127.0.0.1:8000",
//'/api/v1/cert': 'http://192.168.31.41:8000', //'/api/v1/cert': 'http://192.168.31.41:8000',
//"/api/v1/sys": "http://192.168.31.41:8686/",
"/api/v1/sys": "http://192.168.31.41:8686/",
} as Record<any, string>; } as Record<any, string>;
const proxyConfig = Object.keys(proxyMap).reduce( const proxyConfig = Object.keys(proxyMap).reduce(

Loading…
Cancel
Save