取消
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
||||
import { ConfigProvider, App as AntApp, Spin } from 'antd';
|
||||
import zhCN from 'antd/locale/zh_CN';
|
||||
import dayjs from 'dayjs';
|
||||
import 'dayjs/locale/zh-cn';
|
||||
dayjs.locale('zh-cn');
|
||||
import MaintenancePage from './pages/MaintenancePage';
|
||||
import AppLayout from './components/Layout/AppLayout';
|
||||
import LoginPage from './pages/LoginPage';
|
||||
import ProjectsPage from './pages/ProjectsPage';
|
||||
@@ -62,47 +61,11 @@ const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
const App = () => {
|
||||
const { checkAuth } = useAuthStore();
|
||||
const [siteReady, setSiteReady] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// 处理 URL 中的开发者访问令牌
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const devToken = params.get('dev_access');
|
||||
if (devToken) {
|
||||
localStorage.setItem('dev_access_token', devToken);
|
||||
// 清除 URL 中的令牌参数
|
||||
params.delete('dev_access');
|
||||
const newSearch = params.toString();
|
||||
window.history.replaceState({}, '', window.location.pathname + (newSearch ? `?${newSearch}` : ''));
|
||||
}
|
||||
|
||||
// 检查网站状态(仅当用户没有有效 dev token 时)
|
||||
checkAuth();
|
||||
if (!localStorage.getItem('dev_access_token')) {
|
||||
import('./api').then(({ getSiteInfo }) => {
|
||||
getSiteInfo()
|
||||
.then((info) => {
|
||||
if (!info.siteEnabled && !window.location.pathname.startsWith('/maintenance')) {
|
||||
window.location.href = '/maintenance';
|
||||
}
|
||||
})
|
||||
.catch(() => { /* 请求失败时默认放行 */ })
|
||||
.finally(() => setSiteReady(true));
|
||||
});
|
||||
} else {
|
||||
setSiteReady(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 网站状态检查中显示 loading
|
||||
if (!siteReady && !localStorage.getItem('dev_access_token')) {
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
|
||||
<Spin size="large" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfigProvider
|
||||
locale={zhCN}
|
||||
@@ -130,7 +93,6 @@ const App = () => {
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/maintenance" element={<MaintenancePage />} />
|
||||
<Route path="/join-team" element={<JoinTeamPage />} />
|
||||
<Route path="/private-portrait-authorized" element={<PrivatePortraitAuthorizeResult />} />
|
||||
<Route
|
||||
|
||||
@@ -66,12 +66,6 @@ export async function apiRequest<T>(path: string, options: RequestOptions = {}):
|
||||
if (token) headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
// 开发者访问令牌(网站关闭时用于绕过限制)
|
||||
const devAccessToken = localStorage.getItem('dev_access_token');
|
||||
if (devAccessToken) {
|
||||
headers['X-Dev-Access'] = devAccessToken;
|
||||
}
|
||||
|
||||
let bodyStr: string | undefined;
|
||||
if (body !== undefined) {
|
||||
const json = JSON.stringify(body);
|
||||
@@ -116,13 +110,6 @@ export async function apiRequest<T>(path: string, options: RequestOptions = {}):
|
||||
|
||||
// Handle error responses
|
||||
if (!res.ok) {
|
||||
// 网站关闭 → 跳转到维护页面
|
||||
if (res.status === 503 && parsed?.detail?.code === 'SITE_CLOSED') {
|
||||
if (!window.location.pathname.startsWith('/maintenance')) {
|
||||
window.location.href = '/maintenance';
|
||||
}
|
||||
throw new Error(parsed?.detail?.message || '系统正在升级维护');
|
||||
}
|
||||
let msg = parsed?.detail?.message || parsed?.message || `请求失败 (${res.status})`;
|
||||
if (typeof parsed?.detail === 'string') {
|
||||
msg = parsed.detail;
|
||||
|
||||
@@ -290,7 +290,7 @@ export async function verifyCaptcha(captchaId: string, x: number): Promise<strin
|
||||
return res.token;
|
||||
}
|
||||
// ── Site Info ─────────────────────────────────────────────
|
||||
export async function getSiteInfo(): Promise<{ siteName: string; siteLogo: string; userAgreementPrivacyUrl: string; siteCopyright: string; operationManual: string; siteEnabled: boolean }> {
|
||||
export async function getSiteInfo(): Promise<{ siteName: string; siteLogo: string; userAgreementPrivacyUrl: string; siteCopyright: string; operationManual: string }> {
|
||||
if (USE_MOCK) return { siteName: 'VideoGen.AI', siteLogo: '', userAgreementPrivacyUrl: '', siteCopyright: '© 2024 民众智创 版权所有', operationManual: '' };
|
||||
return api.get('/auth/site-info', false);
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Input, Space, Typography, message } from 'antd';
|
||||
import { ToolOutlined, SafetyOutlined } from '@ant-design/icons';
|
||||
import { getSiteInfo } from '../api';
|
||||
|
||||
const MaintenancePage: React.FC = () => {
|
||||
const [devToken, setDevToken] = useState('');
|
||||
const [showDevInput, setShowDevInput] = useState(false);
|
||||
const [siteName, setSiteName] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
// site-info 在网站关闭时仍可访问(白名单)
|
||||
getSiteInfo().then((info) => {
|
||||
if (info.siteName) setSiteName(info.siteName);
|
||||
}).catch(() => {});
|
||||
}, []);
|
||||
|
||||
const handleDevAccess = () => {
|
||||
const token = devToken.trim();
|
||||
if (!token) {
|
||||
message.warning('请输入开发者访问令牌');
|
||||
return;
|
||||
}
|
||||
localStorage.setItem('dev_access_token', token);
|
||||
message.success('开发者访问已启用,正在刷新...');
|
||||
window.location.href = '/';
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
minHeight: '100vh',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
background: 'linear-gradient(135deg, #f8fafc 0%, #eef2ff 100%)',
|
||||
padding: 24,
|
||||
textAlign: 'center',
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
{/* 开发者入口 — 右下角 */}
|
||||
<div style={{ position: 'absolute', right: 20, bottom: 20 }}>
|
||||
{!showDevInput ? (
|
||||
<Typography.Link
|
||||
onClick={() => setShowDevInput(true)}
|
||||
style={{ fontSize: 12, color: '#94a3b8' }}
|
||||
>
|
||||
<SafetyOutlined /> 开发者入口
|
||||
</Typography.Link>
|
||||
) : (
|
||||
<Space.Compact>
|
||||
<Input.Password
|
||||
placeholder="输入开发者访问令牌"
|
||||
value={devToken}
|
||||
onChange={(e) => setDevToken(e.target.value)}
|
||||
onPressEnter={handleDevAccess}
|
||||
style={{ width: 200 }}
|
||||
/>
|
||||
<Button type="primary" onClick={handleDevAccess}>
|
||||
确认
|
||||
</Button>
|
||||
</Space.Compact>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 主内容 */}
|
||||
<div
|
||||
style={{
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 20,
|
||||
background: 'rgba(99, 102, 241, 0.1)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginBottom: 32,
|
||||
}}
|
||||
>
|
||||
<ToolOutlined style={{ fontSize: 40, color: '#6366f1' }} />
|
||||
</div>
|
||||
|
||||
{siteName && (
|
||||
<Typography.Text type="secondary" style={{ fontSize: 13, marginBottom: 8, letterSpacing: 1 }}>
|
||||
{siteName}
|
||||
</Typography.Text>
|
||||
)}
|
||||
|
||||
<Typography.Title level={2} style={{ marginBottom: 8, color: '#1e293b' }}>
|
||||
系统正在升级维护
|
||||
</Typography.Title>
|
||||
|
||||
<Typography.Paragraph type="secondary" style={{ fontSize: 15, maxWidth: 400 }}>
|
||||
为了提供更好的服务,系统正在进行升级维护。
|
||||
<br />
|
||||
请稍后再来,感谢您的理解与支持!
|
||||
</Typography.Paragraph>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MaintenancePage;
|
||||
Reference in New Issue
Block a user