Browse Source

登录 修改 注册 接口完成

main
lk 2 months ago
parent
commit
6d33e0f198
  1. 5
      src/pages/use/login/index.tsx
  2. 73
      src/pages/use/password/retrieve.tsx
  3. 225
      src/pages/use/register/index.tsx
  4. 7
      src/request.ts
  5. 5
      src/service/system.ts
  6. 42
      src/store/system/user.ts
  7. 2
      vite.config.ts

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

@ -12,6 +12,7 @@ import {
upLoginAtom, upLoginAtom,
} from "@/store/system/user.ts"; } from "@/store/system/user.ts";
import React, { memo, useEffect, useLayoutEffect, useState } from "react"; import React, { memo, useEffect, useLayoutEffect, useState } from "react";
import systemServ from "@/service/system.ts";
const { Title, Text, Link } = Typography; const { Title, Text, Link } = Typography;
const { TabPane } = Tabs; const { TabPane } = Tabs;
@ -21,7 +22,7 @@ const Login = memo(() => {
const [emailform] = Form.useForm(); const [emailform] = Form.useForm();
const [telegramform] = Form.useForm(); const [telegramform] = Form.useForm();
const { mutate: upLoginFun } = useAtomValue(upLoginAtom); const { mutate: upLoginFun } = useAtomValue(upLoginAtom);
const { mutate: emailCodeMutate } = useAtomValue(emailCodeAtom);
const [emailCodeData, setEmailCodeData] = useState({});
const { mutate: emailLoginMutate } = useAtomValue(emailLoginAtom); const { mutate: emailLoginMutate } = useAtomValue(emailLoginAtom);
const { mutate: telegramCodeMutate } = useAtomValue(telegramCodeAtom); const { mutate: telegramCodeMutate } = useAtomValue(telegramCodeAtom);
const { mutate: telegramLoginMutate } = useAtomValue(telegramLoginAtom); const { mutate: telegramLoginMutate } = useAtomValue(telegramLoginAtom);
@ -35,7 +36,7 @@ const Login = memo(() => {
const email = emailform.getFieldValue("email"); const email = emailform.getFieldValue("email");
setCountdown(10); setCountdown(10);
setIsButtonDisabled(true); setIsButtonDisabled(true);
emailCodeMutate({ is_register: false, email });
setEmailCodeData(systemServ.emailCode({ is_register: false, email }));
}; };
const emailhandleSubmit = (values: any) => { const emailhandleSubmit = (values: any) => {
emailLoginMutate(values); emailLoginMutate(values);

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

@ -1,32 +1,73 @@
import { Layout, Input, Button, Typography, Row, Col, Form } from "antd";
import {Layout, Input, Button, Typography, Row, Col, Form, message, Modal} 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 { 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";
import { passwordRules } from "@/pages/use/useTools.tsx";
import { useAtom } from "jotai/index";
import systemServ from "@/service/system.ts";
import { setToken } from "@/store/system.ts";
const { Title, Text, Link } = Typography; const { Title, Text, Link } = Typography;
const PwdRetrieve = memo(() => { const PwdRetrieve = memo(() => {
const navigate = useNavigate(); const navigate = useNavigate();
const [retrieveForm] = Form.useForm(); const [retrieveForm] = Form.useForm();
const { mutate: emailCodeMutate } = useAtomValue(emailCodeAtom);
const [emailCodeData, setEmailCodeData] = useState({});
const [pwdRetrieveData, setPwdRetrieveData] = useState({});
const handleRetrieveSubmit = (values: any) => {
console.log(values);
// 调用找回密码API
const handleRetrieveSubmit = async (values: any) => {
const param = {
email: values.email,
password: values.password,
code: values.code,
};
const result = await systemServ.pwdRetrieve(param);
setPwdRetrieveData(result);
}; };
const handleGetCode = () => {
const handleGetCode = async () => {
const email = retrieveForm.getFieldValue("email"); const email = retrieveForm.getFieldValue("email");
setCountdown(10);
setIsButtonDisabled(true);
emailCodeMutate({ email });
const result = await systemServ.emailCode({ is_register: false, email });
setEmailCodeData(result);
}; };
const [countdown, setCountdown] = useState<number>(0); const [countdown, setCountdown] = useState<number>(0);
const [isButtonDisabled, setIsButtonDisabled] = useState<boolean>(false); const [isButtonDisabled, setIsButtonDisabled] = useState<boolean>(false);
const [gotoLoginModalVisible, SetGotoLoginModalVisible] = useState(false);
const showGotoLoginModal= () => {
SetGotoLoginModalVisible(true);
};
const gotoLoginModalHandleOk = () => {
SetGotoLoginModalVisible(false);
navigate({ to: "/login" });
};
// const gotoLoginModalHandleCancel = () => {
// SetGotoLoginModalVisible(false);
// };
//
useEffect(() => {
if ((emailCodeData as any)?.code === 0) {
setCountdown(10);
setIsButtonDisabled(true);
}
}, [emailCodeData]);
useEffect(() => {
if ((pwdRetrieveData as any)?.code === 0) {
message.success("密码找回成功");
showGotoLoginModal();
}
}, [pwdRetrieveData, navigate]);
useEffect(() => { useEffect(() => {
let timer: number; let timer: number;
if (countdown > 0) { if (countdown > 0) {
@ -124,6 +165,18 @@ const PwdRetrieve = memo(() => {
</Row> </Row>
</Col> </Col>
</Row> </Row>
<Modal
title="修改成功"
visible={gotoLoginModalVisible}
onOk={gotoLoginModalHandleOk}
footer={[
<Button key="ok" type="primary" onClick={gotoLoginModalHandleOk}>
</Button>,
]}
>
<p></p>
</Modal>
</Layout> </Layout>
); );
}); });

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

@ -1,39 +1,38 @@
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, UserOutlined} from "@ant-design/icons";
import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useAtom, useAtomValue } from "jotai";
import { useAtomValue } from "jotai";
import React, { memo, useEffect, useState } from "react"; import React, { memo, useEffect, useState } from "react";
import { emailCodeAtom, emailRegisterAtom } from "@/store/system/user.ts";
import { emailRegisterAtom } from "@/store/system/user.ts";
import { passwordRules } from "@/pages/use/useTools"; import { passwordRules } from "@/pages/use/useTools";
import systemServ from "@/service/system.ts";
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: emailRegisterMutate } = useAtomValue(emailRegisterAtom); 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 [countdown, setCountdown] = useState(10);
const [emailCodeData, setEmailCodeData] = useState({});
const [isButtonDisabled, setIsButtonDisabled] = useState<boolean>(false);
const getEmailCode = () => { const getEmailCode = () => {
const email = registerForm.getFieldValue("email"); const email = registerForm.getFieldValue("email");
setCountdown(10); setCountdown(10);
setIsButtonDisabled(true); setIsButtonDisabled(true);
const data = emailCodeMutate({ is_register: true, email });
console.log(data);
setEmailCodeData(systemServ.emailCode({ is_register: true, email }));
}; };
const emailRegisterSubmit = (values: any) => { const emailRegisterSubmit = (values: any) => {
emailRegisterMutate({ email: values.email, password: values.password, code: values.code }); emailRegisterMutate({ email: values.email, password: values.password, code: values.code });
}; };
const [countdown, setCountdown] = useState<number>(0);
const [isButtonDisabled, setIsButtonDisabled] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
if ((emailData as any)?.countdown === -1) {
if ((emailCodeData as any)?.countdown === -1) {
setCountdown(0); setCountdown(0);
setIsButtonDisabled(false); setIsButtonDisabled(false);
} }
}, [emailData]);
}, [emailCodeData]);
useEffect(() => { useEffect(() => {
let timer: number; let timer: number;
@ -53,111 +52,111 @@ const Register = memo(() => {
}, []); }, []);
return ( return (
<Layout
style={{
height: "100vh",
background: "url('https://placehold.co/1920x1080') no-repeat center center",
backgroundSize: "cover",
}}
>
<Row justify="center" align="middle" style={{ height: "100%" }}>
<Col>
<Row>
<Col span={12} style={{ padding: "20px" }}>
<Title level={3}></Title>
<Text></Text>
<br />
<Link href="#"> &gt;</Link>
</Col>
<Col
span={12}
style={{
padding: "20px",
background: "#fff",
borderRadius: "8px",
position: "relative",
width: "500px",
height: "500px",
}}
>
<Form form={registerForm} onFinish={emailRegisterSubmit} style={{ marginTop: "50px" }}>
<Form.Item name="email" rules={[{ required: true, message: "请输入邮箱" }]}>
<Input
size="large"
placeholder="请输入邮箱"
prefix={<MailOutlined />}
addonAfter={
<Button onClick={getEmailCode} disabled={isButtonDisabled}>
{isButtonDisabled ? `${countdown}秒后重试` : "获得验证码"}
</Button>
}
/>
</Form.Item>
<Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}>
<Input size="large" placeholder="请输入验证码" prefix={<SecurityScanOutlined />} autoComplete="off" />
</Form.Item>
<Form.Item name="password" rules={passwordRules}>
<Input.Password size="large" placeholder="请输入密码" prefix={<LockOutlined />} autoComplete="off" />
</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 size="large" placeholder="请确认密码" prefix={<LockOutlined />} autoComplete="off" />
</Form.Item>
<Button type="primary" htmlType="submit" style={{ width: "100%" }}>
</Button>
</Form>
<div
style={{
position: "absolute",
top: 0,
right: 0,
width: 0,
height: 0,
borderLeft: "80px solid transparent",
borderTop: "80px solid #ff9800",
textAlign: "center",
}}
>
<span
<Layout
style={{ style={{
cursor: "pointer", // 设置手型光标
position: "absolute",
top: "-70px",
right: "0px",
color: "#fff",
fontSize: "16px",
transform: "rotate(0deg)",
textAlign: "center",
width: "60px",
display: "block",
height: "100vh",
background: "url('https://placehold.co/1920x1080') no-repeat center center",
backgroundSize: "cover",
}} }}
onClick={() => navigate({ to: "/login" })}
>
<Row justify="center" align="middle" style={{ height: "100%" }}>
<Col>
<Row>
<Col span={12} style={{ padding: "20px" }}>
<Title level={3}></Title>
<Text></Text>
<br />
<Link href="#"> &gt;</Link>
</Col>
<Col
span={12}
style={{
padding: "20px",
background: "#fff",
borderRadius: "8px",
position: "relative",
width: "500px",
height: "500px",
}}
>
<Form form={registerForm} onFinish={emailRegisterSubmit} style={{ marginTop: "50px" }}>
<Form.Item name="email" rules={[{ required: true, message: "请输入邮箱" }]}>
<Input
size="large"
placeholder="请输入邮箱"
prefix={<MailOutlined />}
addonAfter={
<Button onClick={getEmailCode} disabled={isButtonDisabled}>
{isButtonDisabled ? `${countdown}秒后重试` : "获得验证码"}
</Button>
}
/>
</Form.Item>
<Form.Item name="code" rules={[{ required: true, message: "请输入验证码" }]}>
<Input size="large" placeholder="请输入验证码" prefix={<SecurityScanOutlined />} autoComplete="off" />
</Form.Item>
<Form.Item name="password" rules={passwordRules}>
<Input.Password size="large" placeholder="请输入密码" prefix={<LockOutlined />} autoComplete="off" />
</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 size="large" placeholder="请确认密码" prefix={<LockOutlined />} autoComplete="off" />
</Form.Item>
<Button type="primary" htmlType="submit" style={{ width: "100%" }}>
</Button>
</Form>
<div
style={{
position: "absolute",
top: 0,
right: 0,
width: 0,
height: 0,
borderLeft: "80px solid transparent",
borderTop: "80px solid #ff9800",
textAlign: "center",
}}
>
<span
style={{
cursor: "pointer",
position: "absolute",
top: "-70px",
right: "0px",
color: "#fff",
fontSize: "16px",
transform: "rotate(0deg)",
textAlign: "center",
width: "60px",
display: "block",
}}
onClick={() => navigate({ to: "/login" })}
> >
</span> </span>
</div>
<Row justify="space-between" style={{ marginTop: "10px" }}>
<Link onClick={() => navigate({ to: "/login" })}></Link>
</Row>
</Col>
</Row>
</Col>
</Row>
</Layout>
</div>
<Row justify="space-between" style={{ marginTop: "10px" }}>
<Link onClick={() => navigate({ to: "/login" })}></Link>
</Row>
</Col>
</Row>
</Col>
</Row>
</Layout>
); );
}); });

7
src/request.ts

@ -54,7 +54,12 @@ axiosInstance.interceptors.response.use(
case 0: case 0:
case 200: case 200:
//login //login
if (response.config.url?.includes("/sys/login")) {
if (
response.config.url?.includes("/sys/login") ||
response.config.url?.includes("/sys/email/reg") ||
response.config.url?.includes("/sys/email/login") ||
response.config.url?.includes("/sys/login/telegram")
) {
setToken(result.data.token); setToken(result.data.token);
const search = new URLSearchParams(window.location.search); const search = new URLSearchParams(window.location.search);
// eslint-disable-next-line no-case-declarations // eslint-disable-next-line no-case-declarations

5
src/service/system.ts

@ -21,7 +21,7 @@ const systemServ = {
}, },
emailLogin: (data: any) => { emailLogin: (data: any) => {
return request.post<System.LoginResponse>("/sys/login/email", data);
return request.post<System.LoginResponse>("/sys/email/login", data);
}, },
emailRegister: (data: any) => { emailRegister: (data: any) => {
return request.post<System.LoginResponse>("/sys/email/reg", data); return request.post<System.LoginResponse>("/sys/email/reg", data);
@ -35,6 +35,9 @@ const systemServ = {
telegramLogin: (data: any) => { telegramLogin: (data: any) => {
return request.post<System.LoginResponse>("/sys/login/telegram", data); return request.post<System.LoginResponse>("/sys/login/telegram", data);
}, },
pwdRetrieve: (data: any) => {
return request.post<System.LoginResponse>("/sys/email/pws", data);
},

42
src/store/system/user.ts

@ -40,26 +40,31 @@ export const upLoginAtom = atomWithMutation<any, UPLoginRequest>((get) => ({
}, },
onSuccess: (res) => { onSuccess: (res) => {
message.success(t("login.success")); message.success(t("login.success"));
get(userMenuDataAtom).refetch().then();
// setToken(res.data.token);
// get(userMenuDataAtom).refetch().then();
return res.data; return res.data;
}, },
retry: false, retry: false,
})); }));
export const emailCodeAtom = atomWithMutation<any, any>((get) => ({
mutationKey: ["emailCode"],
mutationFn: async (params) => {
return await systemServ.emailCode(params);
},
onSuccess: (res) => {
if(res.data.countdown===-1){
message.error(res.message);
}
return res.data;
},
retry: false,
}));
export const emailCodeAtom = (params) =>atomWithQuery(() => {
return {
queryKey: ["emailCode",params],
queryFn: async () => {
return await systemServ.emailCode(params);
},
select: (data) => {
return data.data;
},
};
});
export const emailLoginAtom = atomWithMutation<any, any>((get) => ({ export const emailLoginAtom = atomWithMutation<any, any>((get) => ({
mutationKey: ["emailLogin"], mutationKey: ["emailLogin"],
mutationFn: async (params) => { mutationFn: async (params) => {
@ -67,18 +72,23 @@ export const emailLoginAtom = atomWithMutation<any, any>((get) => ({
}, },
onSuccess: (res) => { onSuccess: (res) => {
message.success(t("login.success")); message.success(t("login.success"));
// console.log('login success', res)
return res.data; return res.data;
}, },
retry: false, retry: false,
})); }));
export const emailRegisterAtom = atomWithMutation<any, any>((get) => ({ export const emailRegisterAtom = atomWithMutation<any, any>((get) => ({
mutationKey: ["emailRegister"], mutationKey: ["emailRegister"],
mutationFn: async (params) => { mutationFn: async (params) => {
return await systemServ.emailRegister(params); return await systemServ.emailRegister(params);
}, },
onSuccess: (res) => { onSuccess: (res) => {
// console.log('login success', res)
// setToken(res.data.token);
// window.location.href = "/";
return res.data; return res.data;
}, },
retry: false, retry: false,

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