diff --git a/web/src/components/auth/OAuth2Callback.js b/web/src/components/auth/OAuth2Callback.js index 6d0bbe70..7d435574 100644 --- a/web/src/components/auth/OAuth2Callback.js +++ b/web/src/components/auth/OAuth2Callback.js @@ -1,4 +1,4 @@ -import React, { useContext, useEffect, useState } from 'react'; +import React, { useContext, useEffect } from 'react'; import { useNavigate, useSearchParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { API, showError, showSuccess, updateAPI, setUserData } from '../../helpers'; @@ -7,22 +7,28 @@ import Loading from '../common/Loading'; const OAuth2Callback = (props) => { const { t } = useTranslation(); - const [searchParams, setSearchParams] = useSearchParams(); + const [searchParams] = useSearchParams(); + const [, userDispatch] = useContext(UserContext); + const navigate = useNavigate(); - const [userState, userDispatch] = useContext(UserContext); - const [prompt, setPrompt] = useState(t('处理中...')); + // 最大重试次数 + const MAX_RETRIES = 3; - let navigate = useNavigate(); + const sendCode = async (code, state, retry = 0) => { + try { + const { data: resData } = await API.get( + `/api/oauth/${props.type}?code=${code}&state=${state}`, + ); + + const { success, message, data } = resData; + + if (!success) { + throw new Error(message || 'OAuth2 callback error'); + } - const sendCode = async (code, state, count) => { - const res = await API.get( - `/api/oauth/${props.type}?code=${code}&state=${state}`, - ); - const { success, message, data } = res.data; - if (success) { if (message === 'bind') { showSuccess(t('绑定成功!')); - navigate('/console/setting'); + navigate('/console/personal'); } else { userDispatch({ type: 'login', payload: data }); localStorage.setItem('user', JSON.stringify(data)); @@ -31,27 +37,34 @@ const OAuth2Callback = (props) => { showSuccess(t('登录成功!')); navigate('/console/token'); } - } else { - showError(message); - if (count === 0) { - setPrompt(t('操作失败,重定向至登录界面中...')); - navigate('/console/setting'); // in case this is failed to bind GitHub - return; + } catch (error) { + if (retry < MAX_RETRIES) { + // 递增的退避等待 + await new Promise((resolve) => setTimeout(resolve, (retry + 1) * 2000)); + return sendCode(code, state, retry + 1); } - count++; - setPrompt(t('出现错误,第 ${count} 次重试中...', { count })); - await new Promise((resolve) => setTimeout(resolve, count * 2000)); - await sendCode(code, state, count); + + // 重试次数耗尽,提示错误并返回设置页面 + showError(error.message || t('授权失败')); + navigate('/console/personal'); } }; useEffect(() => { - let code = searchParams.get('code'); - let state = searchParams.get('state'); - sendCode(code, state, 0).then(); + const code = searchParams.get('code'); + const state = searchParams.get('state'); + + // 参数缺失直接返回 + if (!code) { + showError(t('未获取到授权码')); + navigate('/console/personal'); + return; + } + + sendCode(code, state); }, []); - return ; + return ; }; export default OAuth2Callback; diff --git a/web/src/components/common/Loading.js b/web/src/components/common/Loading.js index a12be053..73822755 100644 --- a/web/src/components/common/Loading.js +++ b/web/src/components/common/Loading.js @@ -1,22 +1,14 @@ import React from 'react'; import { Spin } from '@douyinfe/semi-ui'; -import { useTranslation } from 'react-i18next'; -const Loading = ({ prompt: name = '', size = 'large' }) => { - const { t } = useTranslation(); +const Loading = ({ size = 'small' }) => { return ( -
-
- - - {name ? t('{{name}}', { name }) : t('加载中...')} - -
+
+
); }; diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index e1837de9..7babcad6 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -179,7 +179,6 @@ "注销": "Logout", "登录": "Sign in", "注册": "Sign up", - "加载{name}中...": "Loading {name}...", "未登录或登录已过期,请重新登录!": "Not logged in or session expired. Please login again!", "用户登录": "User Login", "密码": "Password", @@ -933,7 +932,6 @@ "更新令牌后需等待几分钟生效": "It will take a few minutes to take effect after updating the token.", "一小时": "One hour", "新建数量": "New quantity", - "加载失败,请稍后重试": "Loading failed, please try again later", "未设置": "Not set", "API文档": "API documentation", "不是合法的 JSON 字符串": "Not a valid JSON string",