From 637cdf917599456ea2ee19be821300797c761fa9 Mon Sep 17 00:00:00 2001 From: john Date: Fri, 14 Jun 2024 18:41:22 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化行为验证 --- src/api/request.ts | 21 +-- src/components/EmailForm.tsx | 110 ++-------------- src/components/PhoneForm.tsx | 109 +++------------- src/components/SendVerificationCode.tsx | 167 ++++++++++++++++++++++++ src/components/SilderVertify.tsx | 36 +---- 5 files changed, 208 insertions(+), 235 deletions(-) create mode 100644 src/components/SendVerificationCode.tsx diff --git a/src/api/request.ts b/src/api/request.ts index 44b358c..815cb41 100644 --- a/src/api/request.ts +++ b/src/api/request.ts @@ -1,3 +1,4 @@ +import { Toast } from "antd-mobile"; import axios, { AxiosRequestConfig, AxiosRequestHeaders } from "axios"; //基础URL,axios将会自动拼接在url前 @@ -85,29 +86,17 @@ const requestHandler = ( return new Promise>>((resolve, reject) => { response .then((res) => { + if (res.data.code != 0 && res.data.code != 200) { + Toast.show({ content: res.data.msg }); + } //业务代码 可根据需求自行处理 - // const data = res.data; - // if (data.code !== 200 && data.code !== 0) { - // //特定状态码 处理特定的需求 - // if (data.code == 401) { - // console.log("登录异常,执行登出..."); - // } - - // const e = JSON.stringify(data); - // console.log(`请求错误:${e}`); - // //数据请求错误 使用reject将错误返回 - // reject(data); - // } else { - // //数据请求正确 使用resolve将结果返回 - // resolve(res as axiosTypes>); - // } - resolve(res as axiosTypes>); }) .catch((error) => { const e = JSON.stringify(error); console.log(`网络错误:${e}`); + Toast.show({ content: "NetWork Error" }); reject(error); }); }); diff --git a/src/components/EmailForm.tsx b/src/components/EmailForm.tsx index cdfe9a3..24e5dc9 100644 --- a/src/components/EmailForm.tsx +++ b/src/components/EmailForm.tsx @@ -1,115 +1,32 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { useState, useEffect, useRef } from "react"; +import { useState, useRef } from "react"; import { useTranslation } from "react-i18next"; -import { Form, Input, Button, Modal } from "antd-mobile"; +import { Form, Input, Button } from "antd-mobile"; import "../pages/SignIn.scss"; -import { useCountdown } from "../hooks/useCountdown"; -import { sendCode, signUp } from "../api"; +import { signUp } from "../api"; import { signUpTypes, ErrorType } from "../type/SignIn"; import { Toast } from "antd-mobile"; import { useNavigate } from "react-router-dom"; import { Md5 } from "ts-md5"; import { FormInstance } from "antd-mobile/es/components/form"; import useUserStore from "../store/user"; -import SilderVertify, { SilderVertify_handleType } from "./SilderVertify"; +import SendVerificationCode from "./SendVerificationCode"; function EmailForm() { const formRef = useRef(null); const navigate = useNavigate(); const { t } = useTranslation(); - const { start, time } = useCountdown(); const [email, setEmail] = useState(""); const [authCode, setAuthCode] = useState(""); const [shareCode, setShareCode] = useState(""); const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); - const [remainingTime, setRemainingTime] = useState(0); const { Lang } = useUserStore(); - const SilderVertifyRef = useRef(null); const config = { headers: { "Accept-Language": Lang, }, }; - const sendVerificationCode = async () => { - try { - if (email === "") { - return; - } - if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { - Toast.show({ content: t("Invalid email") }); - return; - } - Modal.show({ - content: ( - <> - { - const timestamp = `${new Date().getTime()}`; - const res = await sendCode( - { - account: email, - areaCode: "", - status: 2, - signature: Md5.hashStr( - `Neer${email},${2},${timestamp}GetCode` - ), - timestamp, - posX: pox, - }, - config - ); - console.log("res", res); - if (res.status === 200 && res.data.data?.sms) { - Toast.show({ - content: t("send successfully"), - afterClose: () => { - start(60 * 1000); - }, - }); - Modal.clear(); - } else { - Toast.show({ - content: res.data.msg, - afterClose: () => { - // start(60 * 1000); - }, - }); - if (res.data.code == 1021 || res.data.code == 1015) { - SilderVertifyRef.current?._init(); - return; - } - Modal.clear(); - } - }} - /> - - ), - closeOnMaskClick: true, - }); - } catch (error: unknown) { - // 检查 error 是否是 ErrorType 类型 - if (typeof error === "object" && error !== null && "msg" in error) { - const typedError = error as ErrorType; // 使用类型断言 - Toast.show({ - content: typedError.msg, - afterClose: () => { - // start(60 * 1000); - }, - }); - } else { - // 处理不是 ErrorType 类型的错误 - console.log("An unexpected error occurred"); - } - console.warn(error); - } - }; - - useEffect(() => { - setRemainingTime(time / 1000); - }, [time]); const handleSignUp = async () => { if (email === "" || authCode === "") { @@ -260,15 +177,16 @@ function EmailForm() { onChange={(code) => setAuthCode(code)} /> - {remainingTime === 0 ? ( -

- {t("Send verification code")} -

- ) : ( -

- {remainingTime} {t("seconds")} -

- )} + { + if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { + Toast.show({ content: t("Invalid email") }); + return false; + } + return true; + }} + /> (null); const { t } = useTranslation(); - const { start, time } = useCountdown(); const navigate = useNavigate(); const { SelectCountry, @@ -54,10 +52,9 @@ function PhoneForm() { const [authCode, setAuthCode] = useState(""); const [shareCode, setShareCode] = useState(""); - const [remainingTime, setRemainingTime] = useState(0); + const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); - const SilderVertifyRef = useRef(null); const gotoSelectCountry = () => { UpdatePreviousPathName("/"); @@ -71,80 +68,6 @@ function PhoneForm() { "Accept-Language": Lang, }, }; - const sendVerificationCode = async () => { - try { - if (CurrentPhoneNumber === "") { - return; - } - - Modal.show({ - content: ( - <> - { - const timestamp = `${new Date().getTime()}`; - const res = await sendCode( - { - account: CurrentPhoneNumber, - areaCode: SelectCountry?.code || defaultAreaCode, - status: 2, - signature: Md5.hashStr( - `Neer${CurrentPhoneNumber},${2},${timestamp}GetCode` - ), - timestamp, - posX: pox, - }, - config - ); - if (res.status === 200 && res.data.data?.sms) { - Toast.show({ - content: t("send successfully"), - afterClose: () => { - start(60 * 1000); - }, - }); - Modal.clear(); - } else { - Toast.show({ - content: res.data.msg, - afterClose: () => { - // start(60 * 1000); - }, - }); - if (res.data.code == 1021 || res.data.code == 1015) { - SilderVertifyRef.current?._init(); - return; - } - Modal.clear(); - } - }} - /> - - ), - closeOnMaskClick: true, - }); - } catch (error: unknown) { - // 检查 error 是否是 ErrorType 类型 - if (typeof error === "object" && error !== null && "msg" in error) { - const typedError = error as ErrorType; // 使用类型断言 - Toast.show({ - content: typedError.msg, - afterClose: () => { - // start(60 * 1000); - }, - }); - } else { - // 处理不是 ErrorType 类型的错误 - console.log("An unexpected error occurred"); - } - console.warn(error); - } - }; - useEffect(() => { - setRemainingTime(time / 1000); - }, [time]); const handleSignUp = async () => { if (CurrentPhoneNumber === "" || authCode === "") { @@ -305,15 +228,17 @@ function PhoneForm() { onChange={(code) => setAuthCode(code)} /> - {remainingTime === 0 ? ( -

- {t("Send verification code")} -

- ) : ( -

- {remainingTime} {t("seconds")} -

- )} + { + if (CurrentPhoneNumber == "") { + Toast.show({ content: t("Invalid phone number") }); + return false; + } + return true; + }} + /> boolean; +}) { + const [remainingTime, setRemainingTime] = useState(0); + const { start, time } = useCountdown(); + const { t } = useTranslation(); + const { Lang } = useUserStore(); + const [bigImage, setBigImage] = useState(""); + const [smallImage, setSmallImage] = useState(""); + const [smallImageY, setSmallImageY] = useState(0); + const SilderVertifyRef = useRef(null); + const [visible, setVisible] = useState(false); + const [sendingverfityCodeLoading, setSendingverfityCodeLoading] = + useState(false); + const config = { + headers: { + "Accept-Language": Lang, + }, + }; + async function getVerfityCode() { + return new Promise(async (reslove, _reject) => { + const timestamp = `${new Date().getTime()}`; + if (sendingverfityCodeLoading) return; + setSendingverfityCodeLoading(true); + try { + const res = await sendCode( + { + account: account, + areaCode, + status: 2, + signature: Md5.hashStr(`Neer${account},${2},${timestamp}GetCode`), + timestamp, + }, + config + ); + if (res.status == 200 && res.data.code == 0) { + setBigImage(res.data.data?.captcha?.bigImageBase64 || ""); + setSmallImage(res.data.data?.captcha?.smallImageBase64 || ""); + setSmallImageY(res.data.data?.captcha?.posY || 0); + reslove(); + } + } catch (error) {} + setSendingverfityCodeLoading(false); + }); + } + const sendVerificationCode = async () => { + try { + if (beforeSendVerificationCode && !beforeSendVerificationCode?.()) { + return; + } + await getVerfityCode(); + setVisible(true); + } catch (error: unknown) { + // 检查 error 是否是 ErrorType 类型 + if (typeof error === "object" && error !== null && "msg" in error) { + const typedError = error as ErrorType; // 使用类型断言 + Toast.show({ + content: typedError.msg, + afterClose: () => { + // start(60 * 1000); + }, + }); + } else { + // 处理不是 ErrorType 类型的错误 + console.log("An unexpected error occurred"); + } + console.warn(error); + } + }; + useEffect(() => { + setRemainingTime(time / 1000); + }, [time]); + return ( + <> + {remainingTime === 0 ? ( +

+ {t("Send verification code")} +

+ ) : ( +

+ {remainingTime} {t("seconds")} +

+ )} + + + { + const timestamp = `${new Date().getTime()}`; + const res = await sendCode( + { + account: account, + areaCode, + status: 2, + signature: Md5.hashStr( + `Neer${account},${2},${timestamp}GetCode` + ), + timestamp, + posX: pox, + }, + config + ); + if (res.status === 200 && res.data.data?.sms) { + Toast.show({ + content: t("send successfully"), + afterClose: () => { + start(60 * 1000); + }, + }); + setVisible(false); + } else { + Toast.show({ + content: res.data.msg, + }); + if (res.data.code == 1021 || res.data.code == 1015) { + await getVerfityCode(); + SilderVertifyRef.current?._init(); + return; + } + setVisible(false); + } + }} + /> + + } + closeOnMaskClick={true} + onClose={() => { + setVisible(false); + }} + /> + + + + } + closeOnMaskClick={false} + onClose={() => { + setSendingverfityCodeLoading(false); + }} + /> + + ); +} diff --git a/src/components/SilderVertify.tsx b/src/components/SilderVertify.tsx index e443200..5bf563a 100644 --- a/src/components/SilderVertify.tsx +++ b/src/components/SilderVertify.tsx @@ -1,14 +1,11 @@ import { useDrag } from "@use-gesture/react"; import { forwardRef, useState, useImperativeHandle, useEffect } from "react"; -import { Md5 } from "ts-md5"; -import { sendCode } from "../api"; -import useUserStore from "../store/user"; import { useTranslation } from "react-i18next"; /* * @LastEditors: John * @Date: 2024-06-06 16:41:24 - * @LastEditTime: 2024-06-06 21:07:00 + * @LastEditTime: 2024-06-14 16:35:28 * @Author: John */ export type SilderVertify_handleType = { @@ -17,10 +14,12 @@ export type SilderVertify_handleType = { const SilderVertify = forwardRef< SilderVertify_handleType, { - account: string; + bigImage: string; + smallImage: string; + smallImageY: number; onFinish: (pox: number) => Promise; } ->(function ({ onFinish, account }, ref) { +>(function ({ bigImage, smallImage, smallImageY, onFinish }, ref) { const [offsetX, setOffsetX] = useState(0); // Set the drag hook and define component movement based on gesture data. const bind = useDrag(async ({ event, down, movement: [mx, _] }) => { @@ -36,10 +35,6 @@ const SilderVertify = forwardRef< } }); - const [bigImage, setBigImage] = useState(""); - const [smallImage, setSmallImage] = useState(""); - const [smallImageY, setSmallImageY] = useState(0); - const { SelectCountry, Lang } = useUserStore(); const { t } = useTranslation(); useImperativeHandle(ref, () => { return { @@ -49,29 +44,8 @@ const SilderVertify = forwardRef< }; }); - const config = { - headers: { - "Accept-Language": Lang, - }, - }; async function init() { setOffsetX(0); - const timestamp = `${new Date().getTime()}`; - const res = await sendCode( - { - account: account, - areaCode: SelectCountry?.code || "+1", - status: 2, - signature: Md5.hashStr(`Neer${account},${2},${timestamp}GetCode`), - timestamp, - }, - config - ); - if (res.status == 200 && res.data.code == 0) { - setBigImage(res.data.data?.captcha?.bigImageBase64 || ""); - setSmallImage(res.data.data?.captcha?.smallImageBase64 || ""); - setSmallImageY(res.data.data?.captcha?.posY || 0); - } } useEffect(() => { init();