diff --git a/src/components/captcha/SlideCapt.tsx b/src/components/captcha/SlideCapt.tsx index 0c4002b..d77e149 100644 --- a/src/components/captcha/SlideCapt.tsx +++ b/src/components/captcha/SlideCapt.tsx @@ -1,163 +1,160 @@ -import React, { forwardRef, memo, useCallback, useEffect, useState, useImperativeHandle } from 'react' -import { Popover, message } from 'antd' -import GoCaptcha from 'go-captcha-react' -import { SlideCaptchaCheckData } from './types.ts' -import { SlideData, SlidePoint } from 'go-captcha-react/dist/components/Slide/meta/data' -import { SlideConfig } from 'go-captcha-react/dist/components/Slide/meta/config' -import { Props } from 'go-captcha-react/dist/components/Button' -import { useStyle } from './style.ts' +import React, { forwardRef, memo, useCallback, useEffect, useState, useImperativeHandle } from "react"; +import { Popover, message } from "antd"; +import GoCaptcha from "go-captcha-react"; +import { SlideCaptchaCheckData } from "./types.ts"; +import { SlideData, SlidePoint } from "go-captcha-react/dist/components/Slide/meta/data"; +import { SlideConfig } from "go-captcha-react/dist/components/Slide/meta/config"; +import { Props } from "go-captcha-react/dist/components/Button"; +import { useStyle } from "./style.ts"; export interface SlideCaptProps { api: { - getCaptcha: () => Promise, - checkCaptcha: (params: SlideCaptchaCheckData) => Promise, - }, - config?: SlideConfig - value?: string - onChange?: (value?: string) => void + getCaptcha: () => Promise; + checkCaptcha: (params: SlideCaptchaCheckData) => Promise; + }; + config?: SlideConfig; + value?: string; + onChange?: (value?: string) => void; } export type SlideCaptRef = { - reset: () => void -} - - -const SlideCapt = forwardRef(( - { - config, - api, - value, - onChange, - }: SlideCaptProps, ref) => { - - const { styles } = useStyle() - const [ open, setOpen ] = useState(false) - const [ state, setState ] = useState({}) - const [ data, setData ] = useState() - const [ innerKey, setKey ] = useState(value) - - const fetchCaptcha = useCallback(() => { - - return api.getCaptcha().then(res => { - if (res.code === 0) { - const data = res.data - setKey(data['captcha_key'] || '') - setData({ - image: data['image_base64'] || '', - thumb: data['tile_base64'] || '', - thumbX: data['tile_x'] || 0, - thumbY: data['tile_y'] || 0, - thumbWidth: data['tile_width'] || 0, - thumbHeight: data['tile_height'] || 0, - }) + reset: () => void; +}; + +const SlideCapt = forwardRef( + ({ config, api, value, onChange }: SlideCaptProps, ref) => { + const { styles } = useStyle(); + const [open, setOpen] = useState(false); + const [state, setState] = useState({}); + const [data, setData] = useState(); + const [innerKey, setKey] = useState(value); + + const fetchCaptcha = useCallback(() => { + return api.getCaptcha().then((res) => { + if (res.code === 0) { + const data = res.data; + setKey(data["captcha_key"] || ""); + setData({ + image: data["image_base64"] || "", + thumb: data["tile_base64"] || "", + thumbX: data["tile_x"] || 0, + thumbY: data["tile_y"] || 0, + thumbWidth: data["tile_width"] || 0, + thumbHeight: data["tile_height"] || 0, + }); + } + }); + }, [api.getCaptcha, setData]); + + const refresh = useCallback(() => { + fetchCaptcha(); + }, [fetchCaptcha]); + + const confirm = useCallback( + (point: SlidePoint, clear: (fn?: any) => void) => { + api + .checkCaptcha({ + point: [point.x, point.y].join(","), + key: innerKey!, + }) + .then((res) => { + // console.log(res) + if (res.code === 0 && res.data.is_ok) { + message.success(`验证成功`); + + //验证成功,onChange通知出去,外部需要key做为校验 + onChange?.(innerKey); + + setState((prevState) => ({ + ...prevState, + type: "success", + title: "校验成功", + })); + setOpen(false); + } else { + message.error("验证失败"); + setState((prevState) => ({ + ...prevState, + type: "error", + title: "点击进行校验", + })); + } + setTimeout(() => { + clear(); + fetchCaptcha(); + }, 1000); + }) + .catch(() => { + setTimeout(() => { + clear(); + fetchCaptcha(); + }, 1000); + }); + }, + [api.checkCaptcha, setData, state, setState, setOpen, innerKey, onChange, fetchCaptcha], + ); + + useImperativeHandle(ref, () => { + return { + reset() { + setState((prevState) => ({ + ...prevState, + type: "default", + title: "点击进行校验", + })); + setKey(undefined); + onChange?.(undefined); + refresh(); + }, + }; + }, [fetchCaptcha, setState, setKey]); + + useEffect(() => { + if (open) { + fetchCaptcha(); } + }, [open]); + + return ( +
+ { + setOpen(false); + }, + }} + /> + } + open={open} + onOpenChange={setOpen} + forceRender={true} + trigger="click" + > + { + setOpen(true); + }} + /> + +
+ ); + }, +); - }) - - - }, [ api.getCaptcha, setData ]) - - const refresh = useCallback(() => { - fetchCaptcha() - }, [ fetchCaptcha ]) - - const confirm = useCallback((point: SlidePoint, clear: (fn?: any) => void) => { - - api.checkCaptcha({ - point: [ point.x, point.y ].join(','), - key: innerKey! - }).then(res => { - // console.log(res) - if (res.code === 0 && res.data.is_ok) { - message.success(`验证成功`) - - //验证成功,onChange通知出去,外部需要key做为校验 - onChange?.(innerKey) - - setState(prevState => ({ - ...prevState, type: 'success', title: '校验成功', - })) - setOpen(false) - } else { - message.error('验证失败') - setState(prevState => ({ - ...prevState, type: 'error', title: '点击进行校验', - })) - } - setTimeout(() => { - clear() - fetchCaptcha() - }, 1000) - - }).catch(() => { - setTimeout(() => { - clear() - fetchCaptcha() - }, 1000) - }) - - }, [ api.checkCaptcha, setData, state, setState, setOpen, innerKey, onChange, fetchCaptcha ]) - - useImperativeHandle(ref, () => { - return { - reset() { - setState(prevState => ({ - ...prevState, type: 'default', title: '点击进行校验', - })) - setKey(undefined) - onChange?.(undefined) - refresh() - } - } - }, [ fetchCaptcha, setState, setKey ]) - - useEffect(() => { - - if (open) { - fetchCaptcha() - } - - }, [ open ]) - - return ( -
- { - setOpen(false) - } - }} - /> - } - open={open} - onOpenChange={setOpen} - forceRender={true} - trigger="click"> - { - setOpen(true) - } - }/> - -
- ) -}) - -export default memo(SlideCapt) \ No newline at end of file +export default memo(SlideCapt); diff --git a/src/pages/use/login/index.tsx b/src/pages/use/login/index.tsx index d9daedc..f48b2c2 100644 --- a/src/pages/use/login/index.tsx +++ b/src/pages/use/login/index.tsx @@ -1,261 +1,281 @@ -import { Layout, Tabs, Input, Button, Typography, Row, Col, Form } from 'antd' -import { QrcodeOutlined, UserOutlined, LockOutlined } from '@ant-design/icons' -import SelectLang from '@/components/select-lang' -import { createFileRoute, useNavigate } from '@tanstack/react-router' -import { useAtom, useAtomValue } from 'jotai' -import { useTranslation } from '@/i18n.ts' +import { Layout, Tabs, Input, Button, Typography, Row, Col, Form } from "antd"; +import { QrcodeOutlined, UserOutlined, LockOutlined } from "@ant-design/icons"; +import SelectLang from "@/components/select-lang"; +import { createFileRoute, useNavigate } from "@tanstack/react-router"; +import { useAtom, useAtomValue } from "jotai"; +import { useTranslation } from "@/i18n.ts"; import { emailCodeAtom, emailLoginAtom, telegramCodeAtom, telegramLoginAtom, upLoginAtom, -} from '@/store/system/user.ts' -import React, { memo, useEffect, useLayoutEffect, useRef, useState } from 'react' -import systemServ from '@/service/system.ts' -import SlideCapt, { SlideCaptRef } from '@/components/captcha/SlideCapt.tsx' +} from "@/store/system/user.ts"; +import React, { memo, useEffect, useLayoutEffect, useRef, useState } from "react"; +import systemServ from "@/service/system.ts"; +import SlideCapt, { SlideCaptRef } from "@/components/captcha/SlideCapt.tsx"; +import { t } from "i18next"; -const { Title, Text, Link } = Typography -const { TabPane } = Tabs +const { Title, Text, Link } = Typography; +const { TabPane } = Tabs; const Login = memo(() => { - const navigate = useNavigate() - const [ upform ] = Form.useForm() - const [ emailform ] = Form.useForm() - const [ telegramform ] = Form.useForm() - const { mutate: upLoginFun } = useAtomValue(upLoginAtom) - const [ emailCodeData, setEmailCodeData ] = useState({}) - const { mutate: emailLoginMutate } = useAtomValue(emailLoginAtom) - const { mutate: telegramLoginMutate } = useAtomValue(telegramLoginAtom) + const languageSet = { + 向量检索服务免费试用: t("login.vectorRetrievalServiceFreeTrial", "向量检索服务免费试用"), + 免费试用向量检索服务玩转大模型生成式检索: t( + "login.freeTrialVectorRetrievalService", + "免费试用向量检索服务,玩转大模型生成式检索", + ), + 查看详情: t("login.viewDetails", "查看详情 >"), + 请输入邮箱: t("login.pleaseEnterEmail", "请输入邮箱"), + 获得验证码: t("login.getVerificationCode", "获得验证码"), + 秒后重试: t("login.retryAfterSeconds", "秒后重试"), + 请输入验证码: t("login.pleaseEnterVerificationCode", "请输入验证码"), + 请输入登录密码: t("login.pleaseEnterPassword", "请输入登录密码"), + 点击进行校验: t("login.clickToVerify", "点击进行校验"), + 登录: t("login.login", "登录"), + 注册: t("login.register", "注册"), + 忘记密码: t("login.forgotPassword", "忘记密码"), + 邮箱密码登录: t("login.emailPasswordLogin", "邮箱密码登录"), + 邮箱验证登录: t("login.emailVerificationLogin", "邮箱验证登录"), + 飞机验证登录: t("login.telegramVerificationLogin", "飞机验证登录"), + }; - const slideCaptRef = useRef() + const navigate = useNavigate(); + const [upform] = Form.useForm(); + const [emailform] = Form.useForm(); + const [telegramform] = Form.useForm(); + const { mutate: upLoginFun } = useAtomValue(upLoginAtom); + const [emailCodeData, setEmailCodeData] = useState({}); + const { mutate: emailLoginMutate } = useAtomValue(emailLoginAtom); + const { mutate: telegramLoginMutate } = useAtomValue(telegramLoginAtom); + + const slideCaptRef = useRef(); const uphandleSubmit = (values: any) => { - console.log(values) - upLoginFun(values) - } + console.log(values); + upLoginFun(values); + }; const getEmailCode = async () => { - const email = emailform.getFieldValue('email') - const result = await systemServ.emailCode({ is_register: false, email }) - setEmailCodeData(result) - } + const email = emailform.getFieldValue("email"); + const result = await systemServ.emailCode({ is_register: false, email }); + setEmailCodeData(result); + }; const emailhandleSubmit = (values: any) => { - emailLoginMutate(values) - } + emailLoginMutate(values); + }; const getTelegramCode = async () => { - const telegram = telegramform.getFieldValue('telegram') - const result = await systemServ.telegramCode({ telegram }) - setEmailCodeData(result) - } + const telegram = telegramform.getFieldValue("telegram"); + const result = await systemServ.telegramCode({ telegram }); + setEmailCodeData(result); + }; const telegramhandleSubmit = (values: any) => { - telegramLoginMutate(values) - } + telegramLoginMutate(values); + }; - const [ countdown, setCountdown ] = useState(() => { - const savedCountdown = localStorage.getItem('countdown') - return savedCountdown !== null ? Number(savedCountdown) : 0 - }) + const [countdown, setCountdown] = useState(() => { + const savedCountdown = localStorage.getItem("countdown"); + return savedCountdown !== null ? Number(savedCountdown) : 0; + }); - const [ isButtonDisabled, setIsButtonDisabled ] = useState(() => { - const savedIsButtonDisabled = localStorage.getItem('isButtonDisabled') - return savedIsButtonDisabled !== null ? JSON.parse(savedIsButtonDisabled) : false - }) + const [isButtonDisabled, setIsButtonDisabled] = useState(() => { + const savedIsButtonDisabled = localStorage.getItem("isButtonDisabled"); + return savedIsButtonDisabled !== null ? JSON.parse(savedIsButtonDisabled) : false; + }); useEffect(() => { - localStorage.setItem('isButtonDisabled', JSON.stringify(isButtonDisabled)) - }, [ isButtonDisabled ]) + localStorage.setItem("isButtonDisabled", JSON.stringify(isButtonDisabled)); + }, [isButtonDisabled]); useEffect(() => { if ((emailCodeData as any)?.code === 0) { - setCountdown(10) - setIsButtonDisabled(true) + setCountdown(10); + setIsButtonDisabled(true); } - }, [ emailCodeData ]) + }, [emailCodeData]); useEffect(() => { - let timer: number + let timer: number; if (countdown > 0) { - timer = setTimeout(() => setCountdown(countdown - 1), 1000) + timer = setTimeout(() => setCountdown(countdown - 1), 1000); } else { - setIsButtonDisabled(false) + setIsButtonDisabled(false); } - localStorage.setItem('countdown', String(countdown)) - return () => clearTimeout(timer) - }, [ countdown ]) + localStorage.setItem("countdown", String(countdown)); + return () => clearTimeout(timer); + }, [countdown]); useLayoutEffect(() => { - document.body.className = 'login' + document.body.className = "login"; return () => { - document.body.className = document.body.className.replace('login', '') - } - }, []) + document.body.className = document.body.className.replace("login", ""); + }; + }, []); return ( - - - - - - 向量检索服务免费试用 - 免费试用向量检索服务,玩转大模型生成式检索 -
- 查看详情 > - - - { - if (key === '1') { - slideCaptRef.current?.reset() - } - }} - style={{ marginTop: '50px' }}> - -
- - }/> - - - } - autoComplete="off" - /> - - - - - - {/**/} - {/* } />*/} - {/**/} - -
-
- -
- - } - addonAfter={ - - } - /> - - - } - autoComplete="off" - /> - - +
+
+ +
+ + } + addonAfter={ + - -
- -
- - } - addonAfter={ - - } - /> - - - } - autoComplete="off" - /> - - +
+
+ +
+ + } + addonAfter={ + - -
-
-
+ } + /> + + + } + autoComplete="off" + /> + + + + + +
navigate({ to: '/register' })} + style={{ + position: "absolute", + top: "-70px", + right: "0px", + color: "#fff", + fontSize: "16px", + transform: "rotate(0deg)", + textAlign: "center", + width: "60px", + display: "block", + cursor: "pointer", // 设置手型光标 + }} + onClick={() => navigate({ to: "/register" })} > - 注册 + {languageSet.注册} -
- - navigate({ to: '/pwdRetrieve' })}>忘记密码 - - - - - - - ) -}) +
+ + navigate({ to: "/pwdRetrieve" })}>{languageSet.忘记密码} + + +
+ +
+
+ ); +}); -export const Route = createFileRoute('/login')({ +export const Route = createFileRoute("/login")({ component: Login, -}) +}); -export default Login +export default Login;