From bbc669ba3e8ce68b6b41a970c9429e66bee42cab Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 22 Dec 2023 17:57:32 +0800 Subject: [PATCH] Add register to sign page(temp) --- src/assets/css/pages/login-.scss | 65 ----- src/assets/css/pages/sign.scss | 21 +- .../common/sidebar/SidebarFooter.tsx | 6 +- src/constants/common.constants.ts | 6 + src/constants/urls.constants.ts | 2 + src/global.d.ts | 22 +- src/pages/Login-.tsx | 156 ------------ src/pages/Sign.tsx | 225 +++++++++++++++--- src/router/index.tsx | 6 +- src/services/auth.tsx | 12 +- src/util/auth.tsx | 11 - 11 files changed, 247 insertions(+), 285 deletions(-) delete mode 100644 src/assets/css/pages/login-.scss delete mode 100644 src/pages/Login-.tsx diff --git a/src/assets/css/pages/login-.scss b/src/assets/css/pages/login-.scss deleted file mode 100644 index 988f60f..0000000 --- a/src/assets/css/pages/login-.scss +++ /dev/null @@ -1,65 +0,0 @@ -@use "@/assets/css/constants" as constants; - -.login-background { - display: flex; - height: 100vh; - width: 100vw; - justify-content: center; - align-items: center; - background-color: #B3E5FC; -} - -.login-box { - display: flex; - width: 800px; - height: 450px; - background-color: #448AFF; -} - -.login-box-left { - display: flex; - justify-content: center; - align-items: center; - height: 100%; - flex: 2; -} - -.login-box-left-text { - font-size: 3rem; - color: constants.$origin-color; - font-weight: bold; - - > div:last-child { - font-size: 1.8rem; - font-weight: normal; - } -} - -.login-box-right { - position: relative; - height: 100%; - flex: 3; - background-color: constants.$origin-color; -} - -.login-from-text { - position: absolute; - top: 60px; - left: 40px; - font-weight: bold; - font-size: 2rem; -} - -.login-from { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - margin-top: 30px; - width: 100%; - height: 100%; -} - -.login-from-item { - width: 80%; -} \ No newline at end of file diff --git a/src/assets/css/pages/sign.scss b/src/assets/css/pages/sign.scss index 93ddf2a..73aaa2b 100644 --- a/src/assets/css/pages/sign.scss +++ b/src/assets/css/pages/sign.scss @@ -68,6 +68,10 @@ .form { width: 300px; + button { + font-weight: bolder; + } + .addition { justify-content: space-between; margin-bottom: 14px; @@ -87,13 +91,22 @@ } } - - .sign-up { - + .sign-up, .sign-in, .forget { + .footer { + a { + font-weight: bolder; + } + } } - .sign-in { + .sign-up, .forget { + .retry { + margin-bottom: 16px; + a { + font-weight: bolder; + } + } } } diff --git a/src/components/common/sidebar/SidebarFooter.tsx b/src/components/common/sidebar/SidebarFooter.tsx index 98dfab8..77e6aac 100644 --- a/src/components/common/sidebar/SidebarFooter.tsx +++ b/src/components/common/sidebar/SidebarFooter.tsx @@ -2,7 +2,8 @@ import React from 'react' import Icon from '@ant-design/icons' import { COLOR_ERROR } from '@/constants/common.constants' import { getRedirectUrl } from '@/util/route' -import { getLoginStatus, getNickname, logout } from '@/util/auth' +import { getLoginStatus, getNickname, removeToken } from '@/util/auth' +import { r_auth_logout } from '@/services/auth' const SidebarFooter: React.FC = () => { const matches = useMatches() @@ -26,7 +27,8 @@ const SidebarFooter: React.FC = () => { } setExiting(true) - void logout().finally(() => { + void r_auth_logout().finally(() => { + removeToken() notification.info({ message: '已退出登录', icon: diff --git a/src/constants/common.constants.ts b/src/constants/common.constants.ts index 36d67c3..393afdb 100644 --- a/src/constants/common.constants.ts +++ b/src/constants/common.constants.ts @@ -34,6 +34,9 @@ export const PERMISSION_LOGIN_SUCCESS = 20000 export const PERMISSION_PASSWORD_CHANGE_SUCCESS = 20001 export const PERMISSION_LOGOUT_SUCCESS = 20002 export const PERMISSION_TOKEN_RENEW_SUCCESS = 20003 +export const PERMISSION_REGISTER_SUCCESS = 20004 +export const PERMISSION_RESEND_SUCCESS = 20005 +export const PERMISSION_VERIFY_SUCCESS = 20006 export const PERMISSION_UNAUTHORIZED = 20050 export const PERMISSION_USERNAME_NOT_FOUND = 20051 @@ -47,6 +50,9 @@ export const PERMISSION_OLD_PASSWORD_NOT_MATCH = 20058 export const PERMISSION_LOGOUT_FAILED = 20059 export const PERMISSION_TOKEN_ILLEGAL = 20060 export const PERMISSION_TOKEN_HAS_EXPIRED = 20061 +export const PERMISSION_NO_VERIFICATION_REQUIRED = 20062 +export const PERMISSION_VERIFY_CODE_ERROR_OR_EXPIRED = 20063 +export const PERMISSION_ACCOUNT_NEED_INIT = 20064 export const DATABASE_SELECT_SUCCESS = 30000 export const DATABASE_SELECT_FAILED = 30005 diff --git a/src/constants/urls.constants.ts b/src/constants/urls.constants.ts index ba5de7a..4795746 100644 --- a/src/constants/urls.constants.ts +++ b/src/constants/urls.constants.ts @@ -1,3 +1,5 @@ +export const URL_REGISTER = '/register' +export const URL_VERIFY = '/verify' export const URL_LOGIN = '/login' export const URL_TOKEN = '/token' export const URL_LOGOUT = '/logout' diff --git a/src/global.d.ts b/src/global.d.ts index e0e4c8c..53d6df0 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -57,6 +57,23 @@ interface TokenVo { token: string } +interface RegisterParam { + username: string + email: string + password: string +} + +interface VerifyParam { + code: string + nickname?: string + avatar?: string +} + +interface LoginParam { + account: string + password: string +} + interface UserWithPowerInfoVo { id: string username: string @@ -148,11 +165,6 @@ interface GroupVo { updateTime: string } -interface LoginForm { - account: string - password: string -} - interface PageVo { current: number pages: number diff --git a/src/pages/Login-.tsx b/src/pages/Login-.tsx deleted file mode 100644 index 42e3362..0000000 --- a/src/pages/Login-.tsx +++ /dev/null @@ -1,156 +0,0 @@ -import React from 'react' -import '@/assets/css/pages/login-.scss' -import { - PERMISSION_LOGIN_SUCCESS, - PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR, - PERMISSION_USER_DISABLE, - PERMISSION_USERNAME_NOT_FOUND -} from '@/constants/common.constants' -import { utcToLocalTime } from '@/util/datetime' -import { getUserInfo, login, setToken } from '@/util/auth' -import { AppContext } from '@/App' - -const Login: React.FC = () => { - const { refreshRouter } = useContext(AppContext) - const [messageApi, contextHolder] = message.useMessage() - const navigate = useNavigate() - const [searchParams] = useSearchParams() - const [isLoggingIn, setIsLoggingIn] = useState(false) - - const onFinish = (values: LoginForm) => { - setIsLoggingIn(true) - void login(values.account, values.password) - .then((value) => { - const res = value.data - const { code, data } = res - switch (code) { - case PERMISSION_LOGIN_SUCCESS: - setToken(data?.token ?? '') - void messageApi.success('登录成功') - setTimeout(() => { - void getUserInfo().then((user) => { - refreshRouter() - - if (searchParams.has('redirect')) { - navigate(searchParams.get('redirect') ?? '/') - } else { - navigate('/') - } - - notification.success({ - message: '欢迎回来', - description: ( - <> - - 你好 {user.userInfo.nickname} - -
- - 最近登录: - {user.lastLoginTime - ? `${utcToLocalTime(user.lastLoginTime)}【${ - user.lastLoginIp - }】` - : '无'} - - - ), - placement: 'topRight' - }) - }) - }, 1500) - break - case PERMISSION_USERNAME_NOT_FOUND: - case PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR: - void messageApi.error( - <> - 账号密码错误,请重试 - - ) - setIsLoggingIn(false) - break - case PERMISSION_USER_DISABLE: - void messageApi.error( - <> - 该用户已被禁用 - - ) - setIsLoggingIn(false) - break - default: - void messageApi.error( - <> - 服务器出错了 - - ) - setIsLoggingIn(false) - } - }) - .catch(() => { - setIsLoggingIn(false) - }) - } - - return ( - <> - {contextHolder} -
-
-
-
-
欢迎回来
-
Welcome back
-
-
-
-
- 登 录 -
- - - } - placeholder={'邮箱/用户名'} - disabled={isLoggingIn} - /> - - - } - placeholder={'密码'} - disabled={isLoggingIn} - /> - - - - 登    录 - - - -
-
-
- - ) -} - -export default Login diff --git a/src/pages/Sign.tsx b/src/pages/Sign.tsx index 8622291..6ba1a08 100644 --- a/src/pages/Sign.tsx +++ b/src/pages/Sign.tsx @@ -1,43 +1,179 @@ import React, { useState } from 'react' -import '@/assets/css/pages/sign.scss' -import FitFullscreen from '@/components/common/FitFullscreen' -import FitCenter from '@/components/common/FitCenter' -import FlexBox from '@/components/common/FlexBox' import { useNavigate } from 'react-router' import Icon from '@ant-design/icons' -import { getUserInfo, login, setToken } from '@/util/auth.tsx' +import '@/assets/css/pages/sign.scss' import { + DATABASE_DUPLICATE_KEY, PERMISSION_LOGIN_SUCCESS, PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR, + PERMISSION_REGISTER_SUCCESS, PERMISSION_USER_DISABLE, PERMISSION_USERNAME_NOT_FOUND } from '@/constants/common.constants.ts' -import { AppContext } from '@/App.tsx' -import { utcToLocalTime } from '@/util/datetime.tsx' -import { useUpdatedEffect } from '@/util/hooks.tsx' +import { getLoginStatus, getUserInfo, setToken } from '@/util/auth' +import { AppContext } from '@/App' +import { utcToLocalTime } from '@/util/datetime' +import { useUpdatedEffect } from '@/util/hooks' +import { r_auth_login, r_auth_register } from '@/services/auth' +import FitFullscreen from '@/components/common/FitFullscreen' +import FitCenter from '@/components/common/FitCenter' +import FlexBox from '@/components/common/FlexBox' const SignUp: React.FC = () => { const navigate = useNavigate() const [searchParams] = useSearchParams() + const [isSigningUp, setIsSigningUp] = useState(false) + const [isFinish, setIsFinish] = useState(false) + + const handleOnFinish = (registerParam: RegisterParam) => { + if (isSigningUp) { + return + } + setIsSigningUp(true) + void r_auth_register({ + username: registerParam.username, + email: registerParam.email, + password: registerParam.password + }) + .then((res) => { + const response = res.data + switch (response.code) { + case PERMISSION_REGISTER_SUCCESS: + void message.success('恭喜,您快要完成注册了') + setIsFinish(true) + break + case DATABASE_DUPLICATE_KEY: + void message.error('用户名或邮箱已被注册,请重试') + setIsSigningUp(false) + break + default: + void message.error('服务器出错了,请稍后重试') + setIsSigningUp(false) + } + }) + .catch(() => { + setIsSigningUp(false) + }) + } + + const handleOnRetry = () => {} return (
-
Welcome join us
- - navigate( - `/login${ - searchParams.toString() ? `?${searchParams.toString()}` : '' - }` - ) - } - > - 登录 - - - +
+
创建账号
+
Create account
+
+ + {!isFinish ? ( + <> + + } + placeholder={'用户名'} + maxLength={39} + showCount={true} + disabled={isSigningUp} + /> + + + } + placeholder={'邮箱'} + disabled={isSigningUp} + /> + + + } + placeholder={'密码'} + disabled={isSigningUp} + /> + + ({ + validator(_, value) { + if (!value || getFieldValue('password') === value) { + return Promise.resolve() + } + return Promise.reject( + new Error('两次密码输入必须一致') + ) + } + }) + ]} + > + } + placeholder={'确认密码'} + disabled={isSigningUp} + /> + + + + 注    册 + + + + ) : ( +
+ 我们发送了一封包含激活账号链接的邮件到您的邮箱里,如未收到,可能被归为垃圾邮件,请仔细检查。 + 重新发送 +
+ )} + +
@@ -45,6 +181,21 @@ const SignUp: React.FC = () => { ) } +const Verify: React.FC = () => { + const navigate = useNavigate() + const [searchParams] = useSearchParams() + + useUpdatedEffect(() => { + if (!getLoginStatus()) { + navigate(`/login${searchParams.toString() ? `?${searchParams.toString()}` : ''}`, { + replace: true + }) + } + }, []) + + return <> +} + const Forget: React.FC = () => { const navigate = useNavigate() const [searchParams] = useSearchParams() @@ -72,7 +223,10 @@ const Forget: React.FC = () => { <> } @@ -93,7 +247,7 @@ const Forget: React.FC = () => { ) : ( -
+
我们发送了一封包含找回密码链接的邮件到您的邮箱里,如未收到,可能被归为垃圾邮件,请仔细检查。 重新发送
@@ -108,7 +262,8 @@ const Forget: React.FC = () => { searchParams.toString() ? `?${searchParams.toString()}` : '' - }` + }`, + { replace: true } ) } > @@ -128,13 +283,13 @@ const SignIn: React.FC = () => { const [searchParams] = useSearchParams() const [isSigningIn, setIsSigningIn] = useState(false) - const handleOnFinish = (loginForm: LoginForm) => { + const handleOnFinish = (loginParam: LoginParam) => { if (isSigningIn) { return } setIsSigningIn(true) - void login(loginForm.account, loginForm.password) + void r_auth_login({ account: loginParam.account, password: loginParam.password }) .then((res) => { const response = res.data const { code, data } = response @@ -216,7 +371,7 @@ const SignIn: React.FC = () => { } @@ -226,7 +381,7 @@ const SignIn: React.FC = () => { } @@ -243,7 +398,8 @@ const SignIn: React.FC = () => { searchParams.toString() ? `?${searchParams.toString()}` : '' - }` + }`, + { replace: true } ) }} > @@ -262,7 +418,7 @@ const SignIn: React.FC = () => {
- 还没有账户? + 还没有账号? navigate( @@ -270,7 +426,8 @@ const SignIn: React.FC = () => { searchParams.toString() ? `?${searchParams.toString()}` : '' - }` + }`, + { replace: true } ) } > @@ -290,7 +447,7 @@ const Sign: React.FC = () => { const match = useMatches().reduce((_, second) => second) const [isSwitch, setIsSwitch] = useState(false) - const leftPage = ['register', 'forget'] + const leftPage = ['register', 'verify', 'forget'] useUpdatedEffect(() => { lastPage.current = currentPage.current @@ -303,6 +460,8 @@ const Sign: React.FC = () => { switch (leftPage.includes(currentPage.current) ? currentPage.current : lastPage.current) { case 'forget': return + case 'verify': + return default: return } diff --git a/src/router/index.tsx b/src/router/index.tsx index 3714009..4135a7f 100644 --- a/src/router/index.tsx +++ b/src/router/index.tsx @@ -21,9 +21,9 @@ const root: RouteJsonObject[] = [ component: lazySignPage }, { - path: 'confirm', - absolutePath: '/confirm', - id: 'confirm', + path: 'verify', + absolutePath: '/verify', + id: 'verify', component: lazySignPage }, { diff --git a/src/services/auth.tsx b/src/services/auth.tsx index 1770854..8cf2075 100644 --- a/src/services/auth.tsx +++ b/src/services/auth.tsx @@ -1,10 +1,10 @@ -import { URL_LOGIN, URL_LOGOUT } from '@/constants/urls.constants' +import { URL_LOGIN, URL_LOGOUT, URL_REGISTER, URL_VERIFY } from '@/constants/urls.constants' import request from '@/services' -export const r_auth_login = (account: string, password: string) => - request.post(URL_LOGIN, { - account, - password - }) +export const r_auth_register = (param: RegisterParam) => request.post(URL_REGISTER, param) + +export const r_auth_verify = (param: VerifyParam) => request.post(URL_VERIFY, param) + +export const r_auth_login = (param: LoginParam) => request.post(URL_LOGIN, param) export const r_auth_logout = () => request.post(URL_LOGOUT) diff --git a/src/util/auth.tsx b/src/util/auth.tsx index 4768ff4..ea138c3 100644 --- a/src/util/auth.tsx +++ b/src/util/auth.tsx @@ -8,7 +8,6 @@ import { floorNumber, randomColor, randomFloat, randomInt } from '@/util/common' import { getLocalStorage, removeLocalStorage, setLocalStorage } from '@/util/browser' import { getFullTitle } from '@/util/route' import { r_sys_user_info } from '@/services/system' -import { r_auth_login, r_auth_logout } from '@/services/auth' let captcha: Captcha @@ -65,16 +64,6 @@ export const getCaptcha = (width: number, high: number, num: number) => { } } -export const login = async (account: string, password: string) => { - return await r_auth_login(account, password) -} - -export const logout = async () => { - return r_auth_logout().finally(() => { - removeToken() - }) -} - export const getLoginStatus = () => { return getLocalStorage(STORAGE_TOKEN_KEY) !== null }