Files
hms/apps/web/src/stores/app.ts
iven 669ca44360
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
feat(web): 主题设置联动 — 扩展 ThemeConfig 品牌字段 + 设置页面表单
- ThemeConfig 接口增加 brand_name/brand_slogan/brand_features/brand_copyright
- 新增 BrandConfig 接口和 getPublicBrand 公开品牌信息获取
- app store 增加 themeConfig 缓存和 loadThemeConfig 方法
- ThemeSettings 页面增加品牌设置表单(品牌名称/标语/特性/版权)
2026-05-01 17:37:10 +08:00

76 lines
1.9 KiB
TypeScript

import { create } from 'zustand';
import type { ThemeConfig } from '../api/themes';
import { getTheme } from '../api/themes';
export type ThemeName = 'blue' | 'warm' | 'dark' | 'emerald';
export interface ThemeOption {
key: ThemeName;
label: string;
desc: string;
preview: { primary: string; bg: string; surface: string };
}
export const THEME_OPTIONS: ThemeOption[] = [
{
key: 'blue',
label: '信任蓝',
desc: '专业沉稳 · 企业风格',
preview: { primary: '#2563EB', bg: '#F8FAFC', surface: '#FFFFFF' },
},
{
key: 'warm',
label: '温润东方',
desc: '暖色人文 · 医疗关怀',
preview: { primary: '#C4623A', bg: '#F5F0EB', surface: '#FFFFFF' },
},
{
key: 'dark',
label: '深邃夜色',
desc: '暗色护眼 · 深度专注',
preview: { primary: '#60A5FA', bg: '#0F172A', surface: '#1E293B' },
},
{
key: 'emerald',
label: '翡翠清雅',
desc: '清新自然 · 健康生机',
preview: { primary: '#5B7A5E', bg: '#F4F7F4', surface: '#FFFFFF' },
},
];
const STORAGE_KEY = 'hms-theme';
function loadTheme(): ThemeName {
try {
const saved = localStorage.getItem(STORAGE_KEY);
if (saved && THEME_OPTIONS.some((t) => t.key === saved)) return saved as ThemeName;
} catch {}
return 'blue';
}
interface AppState {
theme: ThemeName;
sidebarCollapsed: boolean;
themeConfig: ThemeConfig | null;
toggleSidebar: () => void;
setTheme: (theme: ThemeName) => void;
loadThemeConfig: () => Promise<void>;
}
export const useAppStore = create<AppState>((set) => ({
theme: loadTheme(),
sidebarCollapsed: false,
themeConfig: null,
toggleSidebar: () => set((s) => ({ sidebarCollapsed: !s.sidebarCollapsed })),
setTheme: (theme) => {
try { localStorage.setItem(STORAGE_KEY, theme); } catch {}
set({ theme });
},
loadThemeConfig: async () => {
try {
const config = await getTheme();
set({ themeConfig: config });
} catch {}
},
}));