From e268f6eed1acb78cf8467ecb816c36addd9b1652 Mon Sep 17 00:00:00 2001 From: lk Date: Thu, 12 Sep 2024 15:35:59 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=20=20=E6=B3=A8=E5=86=8C=20?= =?UTF-8?q?=20=20=E5=BF=98=E8=AE=B0=E5=AF=86=E7=A0=81=E7=9A=84UI=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/login/index.tsx | 182 ---------------- src/pages/login/register.tsx | 145 ------------- src/pages/login/style.ts | 130 ------------ src/pages/use/login/index.tsx | 224 ++++++++++++++++++++ src/pages/use/login/style.ts | 130 ++++++++++++ src/pages/use/password/retrieve.tsx | 115 ++++++++++ src/pages/use/register/index.tsx | 145 +++++++++++++ src/request.ts | 6 - src/routes.tsx | 412 ++++++++++++++++++------------------ src/service/system.ts | 8 + src/store/system/user.ts | 22 ++ 11 files changed, 854 insertions(+), 665 deletions(-) delete mode 100644 src/pages/login/index.tsx delete mode 100644 src/pages/login/register.tsx delete mode 100644 src/pages/login/style.ts create mode 100644 src/pages/use/login/index.tsx create mode 100644 src/pages/use/login/style.ts create mode 100644 src/pages/use/password/retrieve.tsx create mode 100644 src/pages/use/register/index.tsx diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx deleted file mode 100644 index 0e1580a..0000000 --- a/src/pages/login/index.tsx +++ /dev/null @@ -1,182 +0,0 @@ -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 } from "@tanstack/react-router"; -import { useAtom, useAtomValue } from "jotai"; -import { useTranslation } from "@/i18n.ts"; -import { emailCodeAtom, emailLoginAtom, upLoginAtom, upLoginFormAtom } from "@/store/system/user.ts"; -import React, { memo, useEffect, useLayoutEffect, useState } from "react"; -import { useStyles } from "./style.ts"; -const { Title, Text, Link } = Typography; -const { TabPane } = Tabs; - -const Login = memo(() => { - const [upform] = Form.useForm(); - const [emailform] = Form.useForm(); - const { mutate: upLoginFun } = useAtomValue(upLoginAtom); - const { mutate: emailCodeMutate } = useAtomValue(emailCodeAtom); - const { mutate: emailLoginMutate } = useAtomValue(emailLoginAtom); - - const uphandleSubmit = (values: any) => { - console.log(values); - upLoginFun(values); - }; - const emailhandleSubmit = (values: any) => { - console.log(values); - emailLoginMutate(values); - }; - const handleGetCode = () => { - const email = emailform.getFieldValue("email"); - setCountdown(10); - setIsButtonDisabled(true); - emailCodeMutate({ email }); - }; - - const [countdown, setCountdown] = useState(0); - const [isButtonDisabled, setIsButtonDisabled] = useState(false); - - useEffect(() => { - let timer: number; - if (countdown > 0) { - timer = setTimeout(() => setCountdown(countdown - 1), 1000); - } else { - setIsButtonDisabled(false); - } - return () => clearTimeout(timer); - }, [countdown]); - - const [loginMod] = useState([ - { value: "single", info: "帐号密码登录" }, - { value: "multiple-email", info: "邮箱登录" }, - { value: "multiple-plane", info: "飞机登录" }, - ]); - - useLayoutEffect(() => { - document.body.className = "login"; - return () => { - document.body.className = document.body.className.replace("login", ""); - }; - }, []); - - return ( - - - - - - 向量检索服务免费试用 - 免费试用向量检索服务,玩转大模型生成式检索 -
- 查看详情 > - - -
- - 注册 - -
- - -
- - } /> - - - } /> - - {/**/} - {/* } />*/} - {/**/} - -
-
- -
- - } - addonAfter={ - - } - /> - - - } /> - - -
-
- {/**/} - {/*
*/} - {/* */} - {/* } />*/} - {/* */} - {/*
*/} - {/*
*/} -
- - 忘记账号 - 找回密码 - - -
- -
-
- ); -}); - -export const Route = createFileRoute("/login")({ - component: Login, -}); - -export default Login; diff --git a/src/pages/login/register.tsx b/src/pages/login/register.tsx deleted file mode 100644 index 856d161..0000000 --- a/src/pages/login/register.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import { Layout, Input, Button, Typography, Row, Col, Form } from "antd"; -import { LockOutlined, MailOutlined } from "@ant-design/icons"; -import { createFileRoute } from "@tanstack/react-router"; -import { useAtomValue } from "jotai"; -import React, { memo, useEffect, useState } from "react"; -import {emailCodeAtom} from "@/store/system/user.ts"; -const { Title, Text, Link } = Typography; - -const Register = memo(() => { - const [registerForm] = Form.useForm(); - const { mutate: emailCodeMutate } = useAtomValue(emailCodeAtom); - - const handleRegisterSubmit = (values: any) => { - console.log(values); - // 调用注册API - }; - - const handleGetCode = () => { - const email = registerForm.getFieldValue("email"); - setCountdown(10); - setIsButtonDisabled(true); - emailCodeMutate({ email }); - }; - - const [countdown, setCountdown] = useState(0); - const [isButtonDisabled, setIsButtonDisabled] = useState(false); - - useEffect(() => { - let timer: number; - if (countdown > 0) { - timer = setTimeout(() => setCountdown(countdown - 1), 1000); - } else { - setIsButtonDisabled(false); - } - return () => clearTimeout(timer); - }, [countdown]); - - useEffect(() => { - document.body.className = "register"; - return () => { - document.body.className = document.body.className.replace("register", ""); - }; - }, []); - - return ( - - - - - - 向量检索服务免费试用 - 免费试用向量检索服务,玩转大模型生成式检索 -
- 查看详情 > - - -
- - 注册 - -
-
- - } - addonAfter={ - - } - /> - - - } /> - - - } /> - - - } /> - - -
- - 已有账号?登录 - 忘记密码 - - -
- -
-
- ); -}); - -export const Route = createFileRoute("/register")({ - component: Register, -}); - -export default Register; diff --git a/src/pages/login/style.ts b/src/pages/login/style.ts deleted file mode 100644 index d893eb7..0000000 --- a/src/pages/login/style.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { createStyles } from '@/theme' -import loginBg from '@/assets/login.png' - - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -export const useStyles = createStyles(({ token, css, cx, prefixCls }, props: any) => { - - const prefix = `${prefixCls}-${token.proPrefix}-login-page` - - - const container = css` - display: flex; - align-items: center; - height: 100vh; - background-image: url(${loginBg}); - background-repeat: no-repeat; - background-size: cover; - ` - const language = css` - position: absolute; - top: 10px; - right: 10px; - color: #fff; - font-size: 14px; - cursor: pointer; - ` - - - const loginBlock = css` - width: 100%; - height: 100%; - padding: 40px 0; - display: flex; - align-items: center; - justify-content: center; - ` - - const innerBlock = css` - width: 356px; - margin: 0 auto; - ` - - const logo = css` - height: 30px; - ` - - const infoLine = css` - display: flex; - align-items: center; - justify-content: space-between; - margin: 0; - ` - - const infoLeft = css` - color: #666; - font-size: 14px; - ` - - - const desc = css` - margin: 24px 0; - color: #999; - font-size: 16px; - cursor: pointer; - ` - const active = css` - color: #333; - font-weight: bold; - font-size: 24px; - ` - - const innerBeforeInput = css` - margin-left: 10px; - color: #999; - ` - - const line = css` - margin-left: 10px; - ` - - const innerAfterInput = css` - margin-right: 10px; - color: #999; - ` - - const lineR = css` - margin-right: 10px; - vertical-align: middle; - - ` - - const sendCode = css` - max-width: 65px; - margin-right: 10px; - ` - - const otherLogin = css` - color: #666; - font-size: 14px; - ` - - const icon = css` - margin-left: 10px; - ` - - const submitBtn = css` - width: 100%; - ` - - return { - container: cx(prefix, container, props?.className ?? ''), - language, - loginBlock, - innerBlock, - logo, - infoLine, - infoLeft, - desc, - active, - innerBeforeInput, - line: cx( innerBeforeInput, line), - innerAfterInput, - lineR: cx(innerAfterInput, lineR), - sendCode, - otherLogin, - icon, - submitBtn, - } -}) \ No newline at end of file diff --git a/src/pages/use/login/index.tsx b/src/pages/use/login/index.tsx new file mode 100644 index 0000000..3ea50e5 --- /dev/null +++ b/src/pages/use/login/index.tsx @@ -0,0 +1,224 @@ +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, useState } from "react"; +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 { mutate: emailCodeMutate } = useAtomValue(emailCodeAtom); + const { mutate: emailLoginMutate } = useAtomValue(emailLoginAtom); + const { mutate: telegramCodeMutate } = useAtomValue(telegramCodeAtom); + const { mutate: telegramLoginMutate } = useAtomValue(telegramLoginAtom); + + const uphandleSubmit = (values: any) => { + console.log(values); + upLoginFun(values); + }; + + const getEmailCode = () => { + const email = emailform.getFieldValue("email"); + setCountdown(10); + setIsButtonDisabled(true); + emailCodeMutate({ email }); + }; + const emailhandleSubmit = (values: any) => { + emailLoginMutate(values); + }; + + const getTelegramCode = () => { + const telegram = telegramform.getFieldValue("telegram"); + setCountdown(10); + setIsButtonDisabled(true); + telegramCodeMutate({ telegram }); + }; + const telegramhandleSubmit = (values: any) => { + telegramLoginMutate(values); + }; + + 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; + }); + + useEffect(() => { + localStorage.setItem("countdown", String(countdown)); + }, [countdown]); + + useEffect(() => { + localStorage.setItem("isButtonDisabled", JSON.stringify(isButtonDisabled)); + }, [isButtonDisabled]); + + useEffect(() => { + let timer: number; + if (countdown > 0) { + timer = setTimeout(() => setCountdown(countdown - 1), 1000); + } else { + setIsButtonDisabled(false); + } + return () => clearTimeout(timer); + }, [countdown]); + + useLayoutEffect(() => { + document.body.className = "login"; + return () => { + document.body.className = document.body.className.replace("login", ""); + }; + }, []); + + return ( + + + + + + 向量检索服务免费试用 + 免费试用向量检索服务,玩转大模型生成式检索 +
+ 查看详情 > + + + + +
+ + } /> + + + } /> + + {/**/} + {/* } />*/} + {/**/} + +
+
+ +
+ + } + addonAfter={ + + } + /> + + + } /> + + +
+
+ +
+ + } + addonAfter={ + + } + /> + + + } /> + + +
+
+
+
+ navigate({ to: "/register" })} + > + 注册 + +
+ + navigate({ to: "/pwdRetrieve" })}>忘记密码 + + +
+ +
+
+ ); +}); + +export const Route = createFileRoute("/login")({ + component: Login, +}); + +export default Login; diff --git a/src/pages/use/login/style.ts b/src/pages/use/login/style.ts new file mode 100644 index 0000000..d893eb7 --- /dev/null +++ b/src/pages/use/login/style.ts @@ -0,0 +1,130 @@ +import { createStyles } from '@/theme' +import loginBg from '@/assets/login.png' + + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +export const useStyles = createStyles(({ token, css, cx, prefixCls }, props: any) => { + + const prefix = `${prefixCls}-${token.proPrefix}-login-page` + + + const container = css` + display: flex; + align-items: center; + height: 100vh; + background-image: url(${loginBg}); + background-repeat: no-repeat; + background-size: cover; + ` + const language = css` + position: absolute; + top: 10px; + right: 10px; + color: #fff; + font-size: 14px; + cursor: pointer; + ` + + + const loginBlock = css` + width: 100%; + height: 100%; + padding: 40px 0; + display: flex; + align-items: center; + justify-content: center; + ` + + const innerBlock = css` + width: 356px; + margin: 0 auto; + ` + + const logo = css` + height: 30px; + ` + + const infoLine = css` + display: flex; + align-items: center; + justify-content: space-between; + margin: 0; + ` + + const infoLeft = css` + color: #666; + font-size: 14px; + ` + + + const desc = css` + margin: 24px 0; + color: #999; + font-size: 16px; + cursor: pointer; + ` + const active = css` + color: #333; + font-weight: bold; + font-size: 24px; + ` + + const innerBeforeInput = css` + margin-left: 10px; + color: #999; + ` + + const line = css` + margin-left: 10px; + ` + + const innerAfterInput = css` + margin-right: 10px; + color: #999; + ` + + const lineR = css` + margin-right: 10px; + vertical-align: middle; + + ` + + const sendCode = css` + max-width: 65px; + margin-right: 10px; + ` + + const otherLogin = css` + color: #666; + font-size: 14px; + ` + + const icon = css` + margin-left: 10px; + ` + + const submitBtn = css` + width: 100%; + ` + + return { + container: cx(prefix, container, props?.className ?? ''), + language, + loginBlock, + innerBlock, + logo, + infoLine, + infoLeft, + desc, + active, + innerBeforeInput, + line: cx( innerBeforeInput, line), + innerAfterInput, + lineR: cx(innerAfterInput, lineR), + sendCode, + otherLogin, + icon, + submitBtn, + } +}) \ No newline at end of file diff --git a/src/pages/use/password/retrieve.tsx b/src/pages/use/password/retrieve.tsx new file mode 100644 index 0000000..96def37 --- /dev/null +++ b/src/pages/use/password/retrieve.tsx @@ -0,0 +1,115 @@ +import { Layout, Input, Button, Typography, Row, Col, Form } from "antd"; +import { LockOutlined, MailOutlined, SecurityScanOutlined } from "@ant-design/icons"; +import { createFileRoute, useNavigate } from "@tanstack/react-router"; +import { useAtomValue } from "jotai"; +import React, { memo, useEffect, useState } from "react"; +import { emailCodeAtom } from "@/store/system/user.ts"; +const { Title, Text, Link } = Typography; + +const PwdRetrieve = memo(() => { + const navigate = useNavigate(); + const [retrieveForm] = Form.useForm(); + const { mutate: emailCodeMutate } = useAtomValue(emailCodeAtom); + + const handleRetrieveSubmit = (values: any) => { + console.log(values); + // 调用找回密码API + }; + + const handleGetCode = () => { + const email = retrieveForm.getFieldValue("email"); + setCountdown(10); + setIsButtonDisabled(true); + emailCodeMutate({ email }); + }; + + const [countdown, setCountdown] = useState(0); + const [isButtonDisabled, setIsButtonDisabled] = useState(false); + + useEffect(() => { + let timer: number; + if (countdown > 0) { + timer = setTimeout(() => setCountdown(countdown - 1), 1000); + } else { + setIsButtonDisabled(false); + } + return () => clearTimeout(timer); + }, [countdown]); + + useEffect(() => { + document.body.className = "retrieve"; + return () => { + document.body.className = document.body.className.replace("retrieve", ""); + }; + }, []); + + return ( + + + + + + 向量检索服务免费试用 + 免费试用向量检索服务,玩转大模型生成式检索 +
+ 查看详情 > + + +
+ + } + addonAfter={ + + } + /> + + + } /> + + + } /> + + + } /> + + +
+ + navigate({ to: "/login" })}>返回登录 + + +
+ +
+
+ ); +}); + +export const Route = createFileRoute("/pwdRetrieve")({ + component: PwdRetrieve, +}); + +export default PwdRetrieve; diff --git a/src/pages/use/register/index.tsx b/src/pages/use/register/index.tsx new file mode 100644 index 0000000..916e08f --- /dev/null +++ b/src/pages/use/register/index.tsx @@ -0,0 +1,145 @@ +import { Layout, Input, Button, Typography, Row, Col, Form } from "antd"; +import { LockOutlined, MailOutlined, SecurityScanOutlined } from "@ant-design/icons"; +import { createFileRoute, useNavigate } from "@tanstack/react-router"; +import { useAtomValue } from "jotai"; +import React, { memo, useEffect, useState } from "react"; +import { emailCodeAtom } from "@/store/system/user.ts"; +const { Title, Text, Link } = Typography; + +const Register = memo(() => { + const navigate = useNavigate(); + const [registerForm] = Form.useForm(); + const { mutate: emailCodeMutate } = useAtomValue(emailCodeAtom); + + const handleRegisterSubmit = (values: any) => { + console.log(values); + // 调用注册API + }; + + const handleGetCode = () => { + const email = registerForm.getFieldValue("email"); + setCountdown(10); + setIsButtonDisabled(true); + emailCodeMutate({ email }); + }; + + const [countdown, setCountdown] = useState(0); + const [isButtonDisabled, setIsButtonDisabled] = useState(false); + + useEffect(() => { + let timer: number; + if (countdown > 0) { + timer = setTimeout(() => setCountdown(countdown - 1), 1000); + } else { + setIsButtonDisabled(false); + } + return () => clearTimeout(timer); + }, [countdown]); + + useEffect(() => { + document.body.className = "register"; + return () => { + document.body.className = document.body.className.replace("register", ""); + }; + }, []); + + return ( + + + + + + 向量检索服务免费试用 + 免费试用向量检索服务,玩转大模型生成式检索 +
+ 查看详情 > + + +
+ + } + addonAfter={ + + } + /> + + + } /> + + + } /> + + + } /> + + +
+
+ navigate({ to: "/login" })} + > + 登录 + +
+ + navigate({ to: "/login" })}>返回登录 + + +
+ +
+
+ ); +}); + +export const Route = createFileRoute("/register")({ + component: Register, +}); + +export default Register; diff --git a/src/request.ts b/src/request.ts index c129df6..8e282d5 100644 --- a/src/request.ts +++ b/src/request.ts @@ -71,9 +71,6 @@ axiosInstance.interceptors.response.use( if (window.location.pathname === "/login") { return Promise.reject(new Error("to login")); } - if (window.location.pathname === "/register") { - return Promise.reject(new Error("register")); - } // 401: 未登录 message.error("登录失败,跳转重新登录"); // eslint-disable-next-line no-case-declarations @@ -100,9 +97,6 @@ axiosInstance.interceptors.response.use( if (window.location.pathname === "/login") { return; } - if (window.location.pathname === "/register") { - return; - } setToken(""); // 401: 未登录 message.error("登录失败,跳转重新登录"); diff --git a/src/routes.tsx b/src/routes.tsx index 9763895..1014db6 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -1,105 +1,107 @@ -import NotPermission from '@/components/error/403.tsx' -import NotFound from '@/components/error/404.tsx' -import ErrorPage from '@/components/error/error.tsx' -import Loading from '@/components/loading' -import FetchLoading from '@/components/loading/FetchLoading.tsx' -import PageLoading from '@/components/page-loading' -import { PageStoreProvider } from '@/store' -import { AuthenticatedRoute as AuthenticatedImport } from './_authenticatedRoute.tsx' -import EmptyLayout from '@/layout/EmptyLayout.tsx' +import NotPermission from "@/components/error/403.tsx"; +import NotFound from "@/components/error/404.tsx"; +import ErrorPage from "@/components/error/error.tsx"; +import Loading from "@/components/loading"; +import FetchLoading from "@/components/loading/FetchLoading.tsx"; +import PageLoading from "@/components/page-loading"; +import { PageStoreProvider } from "@/store"; +import { AuthenticatedRoute as AuthenticatedImport } from "./_authenticatedRoute.tsx"; +import EmptyLayout from "@/layout/EmptyLayout.tsx"; // import ListPageLayout from '@/layout/ListPageLayout.tsx' // import { Route as DashboardImport } from '@/pages/dashboard' -import { Route as LoginRouteImport } from '@/pages/login' -import { Route as RegisterRouteImport } from '@/pages/login/register' -import { generateUUID } from '@/utils/uuid.ts' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import Login2 from '@/pages/login2/index.tsx' +import { Route as LoginRouteImport } from "@/pages/use/login"; +import { Route as RegisterRouteImport } from "@/pages/use/register"; +import { Route as PwdRetrieveImport } from "@/pages/use/password/retrieve"; +import { generateUUID } from "@/utils/uuid.ts"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import Login2 from "@/pages/login2/index.tsx"; import { AnyRoute, createRootRouteWithContext, createRoute, - createRouter, lazyRouteComponent, + createRouter, + lazyRouteComponent, Outlet, redirect, - RouterProvider, useRouter, useRouterState, + RouterProvider, + useRouter, + useRouterState, // createHashHistory, -} from '@tanstack/react-router' +} from "@tanstack/react-router"; // import { TanStackRouterDevtools } from '@tanstack/router-devtools' -import { createElement, memo, useEffect, useRef } from 'react' -import RootLayout from './layout/RootLayout' -import { IRootContext, MenuItem } from './global' +import { createElement, memo, useEffect, useRef } from "react"; +import RootLayout from "./layout/RootLayout"; +import { IRootContext, MenuItem } from "./global"; // import { DevTools } from 'jotai-devtools' -import { useAtomValue } from 'jotai' -import { userMenuDataAtom } from '@/store/system/user.ts' -import { ApiContextProvider } from '@/context.ts' -import Register from "@/pages/login/register.tsx"; +import { useAtomValue } from "jotai"; +import { userMenuDataAtom } from "@/store/system/user.ts"; +import { ApiContextProvider } from "@/context.ts"; + const PageRootLayout = () => { - return - - -} + return ( + + + + ); +}; export const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false, - } - } -}) - + }, + }, +}); const rootRoute = createRootRouteWithContext()({ component: () => ( - - <> - - - {/**/} - {/**/} - + <> + + + {/**/} + {/**/} + ), beforeLoad: ({ location }) => { - if (location.pathname === '/') { - return redirect({ to: '/dashboard' }) + if (location.pathname === "/") { + return redirect({ to: "/dashboard" }); } }, - loader: () => { - - }, + loader: () => {}, notFoundComponent: NotFound, pendingComponent: PageLoading, - errorComponent: ({ error }) => , -}) + errorComponent: ({ error }) => , +}); const emptyRoute = createRoute({ getParentRoute: () => rootRoute, - id: '/_empty', + id: "/_empty", component: EmptyLayout, -}) +}); const authRoute = AuthenticatedImport.update({ getParentRoute: () => rootRoute, - id: '/_authenticated', -} as any) + id: "/_authenticated", +} as any); const layoutNormalRoute = createRoute({ getParentRoute: () => rootRoute, - id: '/_normal_layout', + id: "/_normal_layout", component: PageRootLayout, -}) +}); const layoutAuthRoute = createRoute({ getParentRoute: () => authRoute, - id: '/_auth_layout', + id: "/_auth_layout", component: PageRootLayout, -}) +}); const notAuthRoute = createRoute({ getParentRoute: () => layoutNormalRoute, - path: '/not-auth', - component: NotPermission -}) + path: "/not-auth", + component: NotPermission, +}); // const dashboardRoute = DashboardImport.update({ // path: '/dashboard', @@ -107,20 +109,26 @@ const notAuthRoute = createRoute({ // } as any) const loginRoute = LoginRouteImport.update({ - path: '/login', + path: "/login", getParentRoute: () => emptyRoute, -} as any) +} as any); const registerRoute = RegisterRouteImport.update({ - path: '/register', + path: "/register", + getParentRoute: () => emptyRoute, +} as any); + +const pwdRetrieveRoute = PwdRetrieveImport.update({ + path: "/pwdRetrieve", getParentRoute: () => emptyRoute, -} as any) +} as any); + + // const login2Route = LoginRouteImport.update({ // path: '/login2', // getParentRoute: () => emptyRoute, // } as any) - // // const menusRoute = createRoute({ // getParentRoute: () => layoutAuthRoute, @@ -142,21 +150,20 @@ const registerRoute = RegisterRouteImport.update({ // path: '/system/roles', // }).lazy(async () => await import('@/pages/system/roles').then(d => d.Route)) - -declare module '@tanstack/react-router' { +declare module "@tanstack/react-router" { interface FileRoutesByPath { - '/_authenticated': { - preLoaderRoute: typeof AuthenticatedImport - parentRoute: typeof rootRoute - }, - '/_normal_layout': { - preLoaderRoute: typeof layoutNormalRoute - parentRoute: typeof rootRoute - }, - '/_layout': { - preLoaderRoute: typeof layoutAuthRoute - parentRoute: typeof rootRoute - }, + "/_authenticated": { + preLoaderRoute: typeof AuthenticatedImport; + parentRoute: typeof rootRoute; + }; + "/_normal_layout": { + preLoaderRoute: typeof layoutNormalRoute; + parentRoute: typeof rootRoute; + }; + "/_layout": { + preLoaderRoute: typeof layoutAuthRoute; + parentRoute: typeof rootRoute; + }; // '/': { // preLoaderRoute: typeof DashboardImport // parentRoute: typeof layoutAuthRoute @@ -165,15 +172,20 @@ declare module '@tanstack/react-router' { // preLoaderRoute: typeof DashboardImport // parentRoute: typeof layoutAuthRoute // }, - '/login': { - preLoaderRoute: typeof LoginRouteImport - parentRoute: typeof rootRoute - }, - - '/register': { - preLoaderRoute: typeof RegisterRouteImport - parentRoute: typeof rootRoute - }, + "/login": { + preLoaderRoute: typeof LoginRouteImport; + parentRoute: typeof rootRoute; + }; + + "/register": { + preLoaderRoute: typeof RegisterRouteImport; + parentRoute: typeof rootRoute; + }; + + "/pwdRetrieve": { + preLoaderRoute: typeof PwdRetrieveImport; + parentRoute: typeof rootRoute; + }; // '/system/menus': { // preLoaderRoute: typeof menusRoute // parentRoute: typeof layoutAuthRoute @@ -190,26 +202,26 @@ declare module '@tanstack/react-router' { // preLoaderRoute: typeof rolesRoute // parentRoute: typeof layoutAuthRoute // }, - '/welcome': { - preLoaderRoute: typeof rootRoute - parentRoute: typeof layoutAuthRoute - }, + "/welcome": { + preLoaderRoute: typeof rootRoute; + parentRoute: typeof layoutAuthRoute; + }; } } -const modules = import.meta.glob('./pages/**/*.{jsx,tsx}') +const modules = import.meta.glob("./pages/**/*.{jsx,tsx}"); -console.log(modules) +console.log(modules); const generateDynamicRoutes = (menuData: MenuItem[], parentRoute: AnyRoute) => { // 递归生成路由,如果有routes则递归生成子路由 const generateRoutes = (menu: MenuItem, parentRoute: AnyRoute) => { - const path = menu.path?.replace(parentRoute.options?.path, '') - const isLayout = menu.children && menu.children.length > 0 && menu.type === 'menu' + const path = menu.path?.replace(parentRoute.options?.path, ""); + const isLayout = menu.children && menu.children.length > 0 && menu.type === "menu"; - const isApi = menu.type === 'api' - const api = menu.properties?.startsWith('{') ? JSON.parse(menu.properties)?.api : undefined + const isApi = menu.type === "api"; + const api = menu.properties?.startsWith("{") ? JSON.parse(menu.properties)?.api : undefined; if (isLayout && (!menu.path || !menu.component)) { //没有component的layout,直接返回 @@ -217,7 +229,7 @@ const generateDynamicRoutes = (menuData: MenuItem[], parentRoute: AnyRoute) => { getParentRoute: () => layoutAuthRoute, id: `/layout-no-path-${generateUUID()}`, component: EmptyLayout, - }) + }); } // @ts-ignore 添加menu属性,方便后面获取 @@ -226,115 +238,111 @@ const generateDynamicRoutes = (menuData: MenuItem[], parentRoute: AnyRoute) => { menu, isApi, api, - } as any + } as any; if (isLayout) { - options.id = path ?? `/layout-${generateUUID()}` + options.id = path ?? `/layout-${generateUUID()}`; } else { if (!path) { - console.log(`${menu.name}没有设置视图`) - options.id = menu.meta.name + console.log(`${menu.name}没有设置视图`); + options.id = menu.meta.name; } else { - options.path = path + options.path = path; } } - let component = menu.component + let component = menu.component; // menu.type // 1,组件(页面),2,IFrame,3,外链接,4,按钮 - if (menu.type === 'iframe') { - component = '@/components/Iframe' + if (menu.type === "iframe") { + component = "@/components/Iframe"; } //处理component路径 - component = component.replace(/^\/pages/, '') - component = component.replace(/^\//, '') + component = component.replace(/^\/pages/, ""); + component = component.replace(/^\//, ""); return createRoute({ ...options, // @ts-ignore fix import component: lazyRouteComponent(() => { - //处理最后可能包含index || index.tsx || index.jsx - if (component.endsWith('.tsx')) { - component = component.replace(/\.tsx$/, '') + if (component.endsWith(".tsx")) { + component = component.replace(/\.tsx$/, ""); } - if (component.endsWith('.jsx')) { - component = component.replace(/\.jsx$/, '') + if (component.endsWith(".jsx")) { + component = component.replace(/\.jsx$/, ""); } - if (component.endsWith('/index')) { - component = component.replace(/\/index$/, '') + if (component.endsWith("/index")) { + component = component.replace(/\/index$/, ""); } - let module: () => Promise + let module: () => Promise; //优先匹配无index的情况 if (modules[`./pages/${component}.tsx`] || modules[`./pages/${component}.jsx`]) { - module = modules[`./pages/${component}.tsx`] || modules[`./pages/${component}.jsx`] + module = modules[`./pages/${component}.tsx`] || modules[`./pages/${component}.jsx`]; } else { - module = modules[`./pages/${component}/index.tsx`] || modules[`./pages/${component}/index.jsx`] + module = modules[`./pages/${component}/index.tsx`] || modules[`./pages/${component}/index.jsx`]; } if (!module) { - return NotFound + return NotFound; } return module().then((d: any) => { if (d.Route) { d.Route.update({ path: menu.path, - }) + }); } - return d - }) + return d; + }); }), notFoundComponent: NotFound, - }) - } + }); + }; // 对menuData递归生成路由,只处理type =1 的菜单 const did = (menus: MenuItem[], parentRoute: AnyRoute) => { - return menus.filter((item) => [ 'menu', 'iframe', 'api' ].includes(item.type)).map((item, index) => { - // 如果有children则递归生成子路由,同样只处理type =1 的菜单 - const route = generateRoutes(item, parentRoute) - - // console.log(route) - if (item.children && item.children.length > 0) { - const children = did(item.children, route) - if (children.length > 0) { - route.addChildren(children) + return menus + .filter((item) => ["menu", "iframe", "api"].includes(item.type)) + .map((item, index) => { + // 如果有children则递归生成子路由,同样只处理type =1 的菜单 + const route = generateRoutes(item, parentRoute); + + // console.log(route) + if (item.children && item.children.length > 0) { + const children = did(item.children, route); + if (children.length > 0) { + route.addChildren(children); + } } - } - route.init({ originalIndex: index }) - return route - }) - } - - const routes = did(menuData, parentRoute) - - parentRoute.addChildren(routes) - -} -const routeTree = rootRoute.addChildren( - [ - //非Layout - loginRoute, - emptyRoute, - registerRoute, - //login2Route, - // 添加新的自定义路由 - - - //不带权限Layout - layoutNormalRoute.addChildren([ - notAuthRoute, - ]), - - //带权限Layout - // dashboardRoute, - authRoute.addChildren( - [ - layoutAuthRoute - /*.addChildren( + route.init({ originalIndex: index }); + return route; + }); + }; + + const routes = did(menuData, parentRoute); + + parentRoute.addChildren(routes); +}; +const routeTree = rootRoute.addChildren([ + //非Layout + loginRoute, + emptyRoute, + registerRoute, + pwdRetrieveRoute, + //login2Route, + // 添加新的自定义路由 + + //不带权限Layout + layoutNormalRoute.addChildren([notAuthRoute]), + + //带权限Layout + // dashboardRoute, + authRoute.addChildren([ + layoutAuthRoute, + /*.addChildren( [ menusRoute, departmentsRoute, @@ -342,32 +350,27 @@ const routeTree = rootRoute.addChildren( rolesRoute, ] ),*/ - ]), - ] -) - + ]), +]); export const RootProvider = memo((props: { context: Partial }) => { + const { data: menuData, isLoading, refetch } = useAtomValue(userMenuDataAtom); - const { data: menuData, isLoading, refetch } = useAtomValue(userMenuDataAtom) - - const isFetchRef = useRef(false) + const isFetchRef = useRef(false); useEffect(() => { - if (isFetchRef.current) { - return + return; } - isFetchRef.current = true - refetch() - - }, []) + isFetchRef.current = true; + refetch(); + }, []); if (isLoading) { - return + return ; } - generateDynamicRoutes(menuData ?? [], layoutAuthRoute) + generateDynamicRoutes(menuData ?? [], layoutAuthRoute); // const hashHistory = createHashHistory() @@ -375,34 +378,39 @@ export const RootProvider = memo((props: { context: Partial }) => routeTree, // history: hashHistory, context: { queryClient, menuData: [] }, - defaultPreload: 'intent', - defaultPendingComponent: () => , + defaultPreload: "intent", + defaultPendingComponent: () => , InnerWrap: ({ children }) => { - const { matches } = useRouterState() - const { routesById } = useRouter() + const { matches } = useRouterState(); + const { routesById } = useRouter(); //取最后一个match的route - const route = matches[matches.length - 1] + const route = matches[matches.length - 1]; // 排除rootRoute - if (!route || route.id === '__root__') { - return <>{children} + if (!route || route.id === "__root__") { + return <>{children}; } - const options = routesById[route.routeId].options - - return {children} - } - }) - + const options = routesById[route.routeId].options; + + return ( + + {children} + + ); + }, + }); return ( - - - - ) -}) + + + + ); +}); -export default RootProvider \ No newline at end of file +export default RootProvider; diff --git a/src/service/system.ts b/src/service/system.ts index 7c4948e..514e2f6 100644 --- a/src/service/system.ts +++ b/src/service/system.ts @@ -24,6 +24,14 @@ const systemServ = { return request.post("/sys/login/email", data); }, + telegramCode: (data: any) => { + return request.post("/sys/telegram", data); + }, + + telegramLogin: (data: any) => { + return request.post("/sys/login/telegram", data); + }, + logout: () => { // }, diff --git a/src/store/system/user.ts b/src/store/system/user.ts index 3e679b3..f0dad0a 100644 --- a/src/store/system/user.ts +++ b/src/store/system/user.ts @@ -73,6 +73,28 @@ export const emailLoginAtom = atomWithMutation((get) => ({ retry: false, })); +export const telegramCodeAtom = atomWithMutation((get) => ({ + mutationKey: ["telegramCode"], + mutationFn: async (params) => { + return await systemServ.telegramCode(params); + }, + onSuccess: (res) => { + return res.data; + }, + retry: false, +})); +export const telegramLoginAtom = atomWithMutation((get) => ({ + mutationKey: ["telegramLogin"], + mutationFn: async (params) => { + return await systemServ.telegramLogin(params); + }, + onSuccess: (res) => { + message.success(t("login.success")); + return res.data; + }, + retry: false, +})); + export const logoutAtom = atomWithMutation(() => ({ mutationKey: ["logout"], mutationFn: async () => {