diff --git a/web/src/api/runtime.ts b/web/src/api/runtime.ts new file mode 100644 index 0000000..e82a6dd --- /dev/null +++ b/web/src/api/runtime.ts @@ -0,0 +1,47 @@ +import {useQuery} from '@tanstack/react-query'; + +export interface RuntimeConfig { + apiVersion: string; + system: { + nameZh: string; + nameEn: string; + logo: string; + icpCode: string; + version: string; + defaultView: string; + defaultColorMode: 'light' | 'dark' | 'system'; + }; + theme: {id: string; version: string}; + features: Record; +} + +const fallback: RuntimeConfig = { + apiVersion: 'v1', + system: { + nameZh: '皮卡监控', + nameEn: 'Pika Monitor', + logo: '/api/logo', + icpCode: '', + version: '', + defaultView: 'grid', + defaultColorMode: 'system', + }, + theme: {id: 'default', version: ''}, + features: {}, +}; + +/** 从 /api/config 获取运行时配置(系统名称、logo、版本等)。失败时返回 fallback。 */ +export const useRuntimeConfig = () => { + return useQuery({ + queryKey: ['runtime-config'], + queryFn: async (): Promise => { + const res = await fetch('/api/config'); + if (!res.ok) throw new Error('无法加载运行时配置'); + return res.json(); + }, + staleTime: 5 * 60 * 1000, + retry: 1, + }); +}; + +export {fallback as defaultRuntimeConfig}; diff --git a/web/src/components/index.ts b/web/src/components/index.ts deleted file mode 100644 index 2c0d42f..0000000 --- a/web/src/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { PageHeader } from './PageHeader'; -export type { Action } from './PageHeader'; diff --git a/web/src/global.d.ts b/web/src/global.d.ts deleted file mode 100644 index 67066d3..0000000 --- a/web/src/global.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -export {}; - -declare global { - interface AdminRuntimeConfig { - apiVersion: 'v1'; - system: { - nameZh: string; - nameEn: string; - logo: string; - icpCode: string; - version: string; - defaultView: string; - defaultColorMode: 'light' | 'dark' | 'system'; - }; - theme: {id: string; version: string}; - features: Record; - legacySystemConfig: Window['SystemConfig']; - } - - interface Window { - PikaRuntime: AdminRuntimeConfig; - SystemConfig: { - SystemNameZh: string; - SystemNameEn: string; - ICPCode: string; - DefaultView: string; - Version: string; - }; - } -} diff --git a/web/src/pages/AdminLayout/Header.tsx b/web/src/layouts/AdminLayout/Header.tsx similarity index 96% rename from web/src/pages/AdminLayout/Header.tsx rename to web/src/layouts/AdminLayout/Header.tsx index 5b0a091..4abbceb 100644 --- a/web/src/pages/AdminLayout/Header.tsx +++ b/web/src/layouts/AdminLayout/Header.tsx @@ -4,6 +4,7 @@ import type {MenuProps} from 'antd'; import {App as AntApp, Avatar, Button, Dropdown, Space} from 'antd'; import {BookOpen, Eye, LogOut, Moon, Sun, User as UserIcon} from 'lucide-react'; import {logout} from '@/api/auth'; +import {useRuntimeConfig} from '@/api/runtime'; import type {User} from '@/types'; interface HeaderProps { @@ -16,6 +17,7 @@ interface HeaderProps { export const AdminHeader = ({userInfo, appliedTheme, themeButtonRef, onToggleTheme}: HeaderProps) => { const navigate = useNavigate(); const {message: messageApi, modal} = AntApp.useApp(); + const {data: runtime} = useRuntimeConfig(); const handleLogout = () => { modal.confirm({ @@ -51,7 +53,7 @@ export const AdminHeader = ({userInfo, appliedTheme, themeButtonRef, onToggleThe />
-

{window.SystemConfig?.SystemNameZh}

+

{runtime?.system.nameZh}

控制台

diff --git a/web/src/pages/AdminLayout/MobileNav.tsx b/web/src/layouts/AdminLayout/MobileNav.tsx similarity index 100% rename from web/src/pages/AdminLayout/MobileNav.tsx rename to web/src/layouts/AdminLayout/MobileNav.tsx diff --git a/web/src/pages/AdminLayout/Sider.tsx b/web/src/layouts/AdminLayout/Sider.tsx similarity index 95% rename from web/src/pages/AdminLayout/Sider.tsx rename to web/src/layouts/AdminLayout/Sider.tsx index 8717457..5aa4db1 100644 --- a/web/src/pages/AdminLayout/Sider.tsx +++ b/web/src/layouts/AdminLayout/Sider.tsx @@ -1,11 +1,13 @@ import {useLocation, useNavigate} from 'react-router-dom'; import {menuItems, SIDEBAR_WIDTH, HEADER_HEIGHT} from './menu'; import {cn} from '@/lib/utils'; +import {useRuntimeConfig} from '@/api/runtime'; import type {VersionInfo} from '@/api/version'; export const AdminSider = ({version}: {version?: VersionInfo}) => { const location = useLocation(); const navigate = useNavigate(); + const {data: runtime} = useRuntimeConfig(); return (