diff --git a/web/src/App.js b/web/src/App.js index ff0abbbb..93b4e496 100644 --- a/web/src/App.js +++ b/web/src/App.js @@ -25,7 +25,7 @@ import Playground from './pages/Playground/index.js'; import OAuth2Callback from './components/auth/OAuth2Callback.js'; import PersonalSetting from './components/settings/PersonalSetting.js'; import Setup from './pages/Setup/index.js'; -import SetupCheck from './components/SetupCheck'; +import { useSetupCheck } from './hooks/useSetupCheck.js'; const Home = lazy(() => import('./pages/Home')); const Detail = lazy(() => import('./pages/Detail')); @@ -35,7 +35,7 @@ function App() { const location = useLocation(); return ( - + } /> - + ); } diff --git a/web/src/components/SetupCheck.js b/web/src/components/SetupCheck.js deleted file mode 100644 index 99364b00..00000000 --- a/web/src/components/SetupCheck.js +++ /dev/null @@ -1,18 +0,0 @@ -import React, { useContext, useEffect } from 'react'; -import { Navigate, useLocation } from 'react-router-dom'; -import { StatusContext } from '../context/Status'; - -const SetupCheck = ({ children }) => { - const [statusState] = useContext(StatusContext); - const location = useLocation(); - - useEffect(() => { - if (statusState?.status?.setup === false && location.pathname !== '/setup') { - window.location.href = '/setup'; - } - }, [statusState?.status?.setup, location.pathname]); - - return children; -}; - -export default SetupCheck; \ No newline at end of file diff --git a/web/src/components/fetchTokenKeys.js b/web/src/components/fetchTokenKeys.js deleted file mode 100644 index e9cec001..00000000 --- a/web/src/components/fetchTokenKeys.js +++ /dev/null @@ -1,68 +0,0 @@ -// src/hooks/useTokenKeys.js -import { useEffect, useState } from 'react'; -import { API, showError } from '../helpers'; - -async function fetchTokenKeys() { - try { - const response = await API.get('/api/token/?p=0&size=100'); - const { success, data } = response.data; - if (success) { - const activeTokens = data.filter((token) => token.status === 1); - return activeTokens.map((token) => token.key); - } else { - throw new Error('Failed to fetch token keys'); - } - } catch (error) { - console.error('Error fetching token keys:', error); - return []; - } -} - -function getServerAddress() { - let status = localStorage.getItem('status'); - let serverAddress = ''; - - if (status) { - try { - status = JSON.parse(status); - serverAddress = status.server_address || ''; - } catch (error) { - console.error('Failed to parse status from localStorage:', error); - } - } - - if (!serverAddress) { - serverAddress = window.location.origin; - } - - return serverAddress; -} - -export function useTokenKeys(id) { - const [keys, setKeys] = useState([]); - // const [chatLink, setChatLink] = useState(''); - const [serverAddress, setServerAddress] = useState(''); - const [isLoading, setIsLoading] = useState(true); - - useEffect(() => { - const loadAllData = async () => { - const fetchedKeys = await fetchTokenKeys(); - if (fetchedKeys.length === 0) { - showError('当前没有可用的启用令牌,请确认是否有令牌处于启用状态!'); - setTimeout(() => { - window.location.href = '/token'; - }, 1500); // 延迟 1.5 秒后跳转 - } - setKeys(fetchedKeys); - setIsLoading(false); - // setChatLink(link); - - const address = getServerAddress(); - setServerAddress(address); - }; - - loadAllData(); - }, []); - - return { keys, serverAddress, isLoading }; -} diff --git a/web/src/helpers/index.js b/web/src/helpers/index.js index c43be2c9..1524afbe 100644 --- a/web/src/helpers/index.js +++ b/web/src/helpers/index.js @@ -5,3 +5,4 @@ export * from './api'; export * from './render'; export * from './log'; export * from './data'; +export * from './token'; diff --git a/web/src/helpers/token.js b/web/src/helpers/token.js new file mode 100644 index 00000000..ecdeaa3a --- /dev/null +++ b/web/src/helpers/token.js @@ -0,0 +1,45 @@ +import { API } from './api'; + +/** + * 获取可用的token keys + * @returns {Promise} 返回active状态的token key数组 + */ +export async function fetchTokenKeys() { + try { + const response = await API.get('/api/token/?p=0&size=100'); + const { success, data } = response.data; + if (success) { + const activeTokens = data.filter((token) => token.status === 1); + return activeTokens.map((token) => token.key); + } else { + throw new Error('Failed to fetch token keys'); + } + } catch (error) { + console.error('Error fetching token keys:', error); + return []; + } +} + +/** + * 获取服务器地址 + * @returns {string} 服务器地址 + */ +export function getServerAddress() { + let status = localStorage.getItem('status'); + let serverAddress = ''; + + if (status) { + try { + status = JSON.parse(status); + serverAddress = status.server_address || ''; + } catch (error) { + console.error('Failed to parse status from localStorage:', error); + } + } + + if (!serverAddress) { + serverAddress = window.location.origin; + } + + return serverAddress; +} \ No newline at end of file diff --git a/web/src/hooks/useSetupCheck.js b/web/src/hooks/useSetupCheck.js new file mode 100644 index 00000000..d2233de8 --- /dev/null +++ b/web/src/hooks/useSetupCheck.js @@ -0,0 +1,32 @@ +import { useContext, useEffect } from 'react'; +import { useLocation } from 'react-router-dom'; +import { StatusContext } from '../context/Status'; + +/** + * 自定义Hook:检查系统setup状态并进行重定向 + * @param {Object} options - 配置选项 + * @param {boolean} options.autoRedirect - 是否自动重定向,默认true + * @param {string} options.setupPath - setup页面路径,默认'/setup' + * @returns {Object} 返回setup状态信息 + */ +export function useSetupCheck(options = {}) { + const { autoRedirect = true, setupPath = '/setup' } = options; + const [statusState] = useContext(StatusContext); + const location = useLocation(); + + const isSetupComplete = statusState?.status?.setup !== false; + const needsSetup = !isSetupComplete && location.pathname !== setupPath; + + useEffect(() => { + if (autoRedirect && needsSetup) { + window.location.href = setupPath; + } + }, [autoRedirect, needsSetup, setupPath]); + + return { + isSetupComplete, + needsSetup, + statusState, + currentPath: location.pathname + }; +} \ No newline at end of file diff --git a/web/src/hooks/useTokenKeys.js b/web/src/hooks/useTokenKeys.js new file mode 100644 index 00000000..a6583591 --- /dev/null +++ b/web/src/hooks/useTokenKeys.js @@ -0,0 +1,30 @@ +import { useEffect, useState } from 'react'; +import { fetchTokenKeys, getServerAddress } from '../helpers/token'; +import { showError } from '../helpers'; + +export function useTokenKeys(id) { + const [keys, setKeys] = useState([]); + const [serverAddress, setServerAddress] = useState(''); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const loadAllData = async () => { + const fetchedKeys = await fetchTokenKeys(); + if (fetchedKeys.length === 0) { + showError('当前没有可用的启用令牌,请确认是否有令牌处于启用状态!'); + setTimeout(() => { + window.location.href = '/token'; + }, 1500); // 延迟 1.5 秒后跳转 + } + setKeys(fetchedKeys); + setIsLoading(false); + + const address = getServerAddress(); + setServerAddress(address); + }; + + loadAllData(); + }, []); + + return { keys, serverAddress, isLoading }; +} \ No newline at end of file diff --git a/web/src/index.js b/web/src/index.js index dc0c438d..0f57f5a1 100644 --- a/web/src/index.js +++ b/web/src/index.js @@ -16,7 +16,7 @@ import './index.css'; const root = ReactDOM.createRoot(document.getElementById('root')); const { Sider, Content, Header, Footer } = Layout; root.render( - // + @@ -28,5 +28,5 @@ root.render( - // , + , ); diff --git a/web/src/pages/Chat/index.js b/web/src/pages/Chat/index.js index 77ece906..bd4e19a1 100644 --- a/web/src/pages/Chat/index.js +++ b/web/src/pages/Chat/index.js @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { useTokenKeys } from '../../components/fetchTokenKeys'; +import { useTokenKeys } from '../../hooks/useTokenKeys'; import { Banner, Layout } from '@douyinfe/semi-ui'; import { useParams } from 'react-router-dom'; diff --git a/web/src/pages/Chat2Link/index.js b/web/src/pages/Chat2Link/index.js index a7b5e6ae..553dab3f 100644 --- a/web/src/pages/Chat2Link/index.js +++ b/web/src/pages/Chat2Link/index.js @@ -1,5 +1,5 @@ import React from 'react'; -import { useTokenKeys } from '../../components/fetchTokenKeys'; +import { useTokenKeys } from '../../hooks/useTokenKeys'; const chat2page = () => { const { keys, chatLink, serverAddress, isLoading } = useTokenKeys(); diff --git a/web/src/pages/Home/index.js b/web/src/pages/Home/index.js index ba0c738c..4e8a61d6 100644 --- a/web/src/pages/Home/index.js +++ b/web/src/pages/Home/index.js @@ -5,7 +5,7 @@ import { StatusContext } from '../../context/Status'; import { marked } from 'marked'; import { useTranslation } from 'react-i18next'; import { IconGithubLogo } from '@douyinfe/semi-icons'; -import exampleImage from '..//example.png'; +import exampleImage from '/example.png'; import { Link } from 'react-router-dom'; import NoticeModal from '../../components/layout/NoticeModal'; import { Moonshot, OpenAI, XAI, Zhipu, Volcengine, Cohere, Claude, Gemini, Suno, Minimax, Wenxin, Spark, Qingyan, DeepSeek, Qwen, Midjourney, Grok, AzureAI, Hunyuan, Xinference } from '@lobehub/icons';