From ae1c9ccc77e61ee6a89beb7f5aed446b9f57fab0 Mon Sep 17 00:00:00 2001 From: iven Date: Fri, 1 May 2026 17:39:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20Login/MainLayout=20=E4=BB=8E?= =?UTF-8?q?=E4=B8=BB=E9=A2=98=E9=85=8D=E7=BD=AE=E8=AF=BB=E5=8F=96=E5=93=81?= =?UTF-8?q?=E7=89=8C=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Login.tsx 从 /api/v1/public/brand 读取品牌名称/标语/特性/版权 - MainLayout 侧边栏 Logo 和 Footer 从 themeConfig 读取 - 启动时调用 loadThemeConfig 缓存主题配置 - 移除所有硬编码品牌文字(HMR Platform → 动态读取) --- apps/web/src/layouts/MainLayout.tsx | 12 ++++++++++-- apps/web/src/pages/Login.tsx | 15 +++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/apps/web/src/layouts/MainLayout.tsx b/apps/web/src/layouts/MainLayout.tsx index ab41509..c3b3399 100644 --- a/apps/web/src/layouts/MainLayout.tsx +++ b/apps/web/src/layouts/MainLayout.tsx @@ -95,6 +95,7 @@ const routeTitleFallback: Record = { '/health/alert-dashboard': '告警仪表盘', '/health/alert-rules': '告警规则', '/health/devices': '设备管理', + '/health/dialysis': '透析管理', }; function getTitleFromMenus(path: string, menus: MenuInfo[]): string | undefined { @@ -347,6 +348,8 @@ const DynamicMenuSection = memo(function DynamicMenuSection({ export default function MainLayout({ children }: { children: React.ReactNode }) { const { sidebarCollapsed, toggleSidebar } = useAppStore(); + const themeConfig = useAppStore((s) => s.themeConfig); + const loadThemeConfig = useAppStore((s) => s.loadThemeConfig); const { user, logout } = useAuthStore(); const pluginMenuItems = usePluginStore((s) => s.pluginMenuItems); const pluginMenuGroups = usePluginStore((s) => s.pluginMenuGroups); @@ -379,6 +382,11 @@ export default function MainLayout({ children }: { children: React.ReactNode }) fetchPlugins(1, 'running'); }, [fetchPlugins]); + // 加载主题配置 + useEffect(() => { + loadThemeConfig(); + }, [loadThemeConfig]); + const handleLogout = useCallback(async () => { await logout(); navigate('/login'); @@ -430,7 +438,7 @@ export default function MainLayout({ children }: { children: React.ReactNode })
navigate('/')}>
H
{!sidebarCollapsed && ( - HMS 健康 + {themeConfig?.brand_name || 'HMS 健康'} )}
@@ -523,7 +531,7 @@ export default function MainLayout({ children }: { children: React.ReactNode }) {/* 底部 */}
- HMS 健康管理平台 + {themeConfig?.brand_copyright || 'HMS 健康管理平台'}
diff --git a/apps/web/src/pages/Login.tsx b/apps/web/src/pages/Login.tsx index 60ef6ea..517ebe9 100644 --- a/apps/web/src/pages/Login.tsx +++ b/apps/web/src/pages/Login.tsx @@ -1,14 +1,21 @@ +import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Form, Input, Button, message, Divider } from 'antd'; import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from '@ant-design/icons'; import { useAuthStore } from '../stores/auth'; import ThemeSwitcher from '../components/ThemeSwitcher'; +import { getPublicBrand, type BrandConfig } from '../api/themes'; export default function Login() { const navigate = useNavigate(); const login = useAuthStore((s) => s.login); const loading = useAuthStore((s) => s.loading); const [messageApi, contextHolder] = message.useMessage(); + const [brand, setBrand] = useState(null); + + useEffect(() => { + getPublicBrand().then(setBrand); + }, []); const onFinish = async (values: { username: string; password: string }) => { try { @@ -37,9 +44,9 @@ export default function Login() { -

HMR Platform

-

新一代健康管理平台

-

慢病跟踪 · 工作流引擎 · 消息中心 · 系统配置

+

{brand?.brand_name || 'HMS 健康管理平台'}

+

{brand?.brand_slogan || '新一代健康管理平台'}

+

{brand?.brand_features || '患者管理 · 健康监测 · 随访管理 · AI 智能分析'}

{[ @@ -103,7 +110,7 @@ export default function Login() {
- HMR Platform · ©汕头市智界科技有限公司 + {brand?.brand_copyright || 'HMS 健康管理平台 · ©汕头市智界科技有限公司'}