diff --git a/src/assets/css/pages/sign.scss b/src/assets/css/pages/sign.scss index 73f0d1f..d680211 100644 --- a/src/assets/css/pages/sign.scss +++ b/src/assets/css/pages/sign.scss @@ -5,6 +5,10 @@ background-color: #D2D0DD; user-select: none; + a { + cursor: pointer; + } + a:hover { color: constants.$production-color; } @@ -67,6 +71,7 @@ .form { width: 300px; + font-size: 14px; button { font-weight: bolder; @@ -107,7 +112,7 @@ } .sign-up, .forget { - .retry { + .retry, .success { margin-bottom: 16px; a { diff --git a/src/constants/common.constants.ts b/src/constants/common.constants.ts index 393afdb..6377058 100644 --- a/src/constants/common.constants.ts +++ b/src/constants/common.constants.ts @@ -37,6 +37,8 @@ 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_FORGET_SUCCESS = 20007 +export const PERMISSION_RETRIEVE_SUCCESS = 20008 export const PERMISSION_UNAUTHORIZED = 20050 export const PERMISSION_USERNAME_NOT_FOUND = 20051 @@ -53,6 +55,9 @@ 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 PERMISSION_USER_NOT_FOUND = 20065 +export const PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED = 20066 +export const PERMISSION_ACCOUNT_NEED_RESET_PASSWORD = 20067 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 00c4129..3ff3044 100644 --- a/src/constants/urls.constants.ts +++ b/src/constants/urls.constants.ts @@ -1,6 +1,8 @@ export const URL_REGISTER = '/register' export const URL_RESEND = '/resend' export const URL_VERIFY = '/verify' +export const URL_FORGET = '/forget' +export const URL_RETRIEVE = '/retrieve' 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 f8ce3eb..11865e6 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -69,6 +69,15 @@ interface VerifyParam { avatar?: string } +interface ForgetParam { + email: string +} + +interface RetrieveParam { + code: string + password: string +} + interface LoginParam { account: string password: string diff --git a/src/pages/Sign.tsx b/src/pages/Sign.tsx index eb58a2f..b3a5b5c 100644 --- a/src/pages/Sign.tsx +++ b/src/pages/Sign.tsx @@ -10,6 +10,8 @@ import { PERMISSION_LOGIN_USERNAME_PASSWORD_ERROR, PERMISSION_NO_VERIFICATION_REQUIRED, PERMISSION_REGISTER_SUCCESS, + PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED, + PERMISSION_RETRIEVE_SUCCESS, PERMISSION_USER_DISABLE, PERMISSION_USERNAME_NOT_FOUND } from '@/constants/common.constants.ts' @@ -17,7 +19,14 @@ import { getLoginStatus, getUserInfo, requestUserInfo, setToken } from '@/util/a import { AppContext } from '@/App' import { utcToLocalTime } from '@/util/datetime' import { useUpdatedEffect } from '@/util/hooks' -import { r_auth_login, r_auth_register, r_auth_resend, r_auth_verify } from '@/services/auth' +import { + r_auth_forget, + r_auth_login, + r_auth_register, + r_auth_resend, + r_auth_retrieve, + r_auth_verify +} from '@/services/auth' import FitFullscreen from '@/components/common/FitFullscreen' import FitCenter from '@/components/common/FitCenter' import FlexBox from '@/components/common/FlexBox' @@ -433,15 +442,65 @@ const Verify: React.FC = () => { const Forget: React.FC = () => { const navigate = useNavigate() - const [isLoading, setIsLoading] = useState(false) - const [isFinish, setIsFinish] = useState(false) + const [searchParams] = useSearchParams() + const [isSending, setIsSending] = useState(false) + const [isSent, setIsSent] = useState(false) + const [isChanging, setIsChanging] = useState(false) + const [isChanged, setIsChanged] = useState(false) - const handleOnFinish = () => { - setIsFinish(true) + const handleOnSend = (forgetParam: ForgetParam) => { + if (isSending) { + return + } + setIsSending(true) + + void r_auth_forget(forgetParam) + .then((res) => { + const response = res.data + if (response.success) { + void message.success('已发送验证邮件,请查收') + setIsSent(true) + } else { + void message.error('出错了,请稍后重试') + } + }) + .finally(() => { + setIsSending(false) + }) } const handleOnRetry = () => { - setIsFinish(false) + setIsSent(false) + } + + const handleOnChange = (retrieveParam: RetrieveParam) => { + if (isChanging) { + return + } + setIsChanging(true) + + void r_auth_retrieve({ + code: searchParams.get('code') ?? '', + password: retrieveParam.password + }) + .then((res) => { + const response = res.data + + switch (response.code) { + case PERMISSION_RETRIEVE_SUCCESS: + void message.success('密码已更新') + setIsChanged(true) + break + case PERMISSION_RETRIEVE_CODE_ERROR_OR_EXPIRED: + void message.error('验证码有误,请重新获取') + break + default: + void message.error('出错了,请稍后重试') + } + }) + .finally(() => { + setIsChanging(false) + }) } return ( @@ -452,52 +511,109 @@ const Forget: React.FC = () => {
找回密码
Retrieve password
- - {!isFinish ? ( +
+ {!searchParams.get('code') ? ( + !isSent ? ( + <> + + + } + placeholder={'邮箱'} + disabled={isSending} + /> + + + + 确    定 + + + + + ) : ( +
+ 我们向您发送了一封包含找回密码链接的邮件,如未收到,可能被归为垃圾邮件,请仔细检查。 + 重新发送 +
+ ) + ) : !isChanged ? ( <> - - } - placeholder={'邮箱'} - disabled={isLoading} - /> - - - + - 确    定 - - + 新  密  码 + } + placeholder={'密码'} + disabled={isChanging} + /> + + ({ + validator(_, value) { + if ( + !value || + getFieldValue('password') === value + ) { + return Promise.resolve() + } + return Promise.reject( + new Error('两次密码输入必须一致') + ) + } + }) + ]} + > + + + + + 更    改 + + + ) : ( -
- 我们发送了一封包含找回密码链接的邮件到您的邮箱里,如未收到,可能被归为垃圾邮件,请仔细检查。 - 重新发送 -
+
恭喜你,密码已更新,请重新登录。
)}
找到了? - - navigate(`/login${location.search}`, { replace: true }) - } - > - 登录 - + navigate(`/login`, { replace: true })}>登录
- +
diff --git a/src/services/auth.tsx b/src/services/auth.tsx index 6348b95..9bea6d8 100644 --- a/src/services/auth.tsx +++ b/src/services/auth.tsx @@ -1,8 +1,10 @@ import { + URL_FORGET, URL_LOGIN, URL_LOGOUT, URL_REGISTER, URL_RESEND, + URL_RETRIEVE, URL_VERIFY } from '@/constants/urls.constants' import request from '@/services' @@ -13,6 +15,10 @@ export const r_auth_resend = () => request.post(URL_RESEND) export const r_auth_verify = (param: VerifyParam) => request.post(URL_VERIFY, param) +export const r_auth_forget = (param: ForgetParam) => request.post(URL_FORGET, param) + +export const r_auth_retrieve = (param: RetrieveParam) => request.post(URL_RETRIEVE, param) + export const r_auth_login = (param: LoginParam) => request.post(URL_LOGIN, param) export const r_auth_logout = () => request.post(URL_LOGOUT)