/** * 设置状态管理器 * @author 阿瑞 * @description 应用全局设置的状态管理,包括主题、布局等配置的存储和管理 * @version 1.1.0 * @date 2024 * @updated 修复SSR初始化问题 */ import { create } from 'zustand'; import { StorageEnum, ThemeColorPresets, ThemeLayout, ThemeMode } from '@/types/enum'; // ==================== 本地存储工具函数 ==================== /** * 从 localStorage 中获取指定键的值 * @template T - 返回值的类型 * @param key - 存储键名,使用 StorageEnum 枚举值 * @returns 解析后的值或 null */ export const getItem = (key: StorageEnum): T | null => { let value = null; try { // 关键代码行注释:检查是否在客户端环境(SSR兼容性处理) if (typeof window !== 'undefined') { // 尝试从 localStorage 获取数据 const result = window.localStorage.getItem(key); if (result) { // 解析 JSON 字符串为对象 value = JSON.parse(result); } } } catch (error) { // 捕获解析错误,避免程序崩溃 console.error('localStorage 读取失败:', error); } return value; }; // ==================== 类型定义 ==================== /** * 应用设置类型定义 * @interface SettingsType */ type SettingsType = { /** 主题色彩预设 */ themeColorPresets: ThemeColorPresets; /** 主题模式(明亮/暗黑) */ themeMode: ThemeMode; /** 主题布局类型 */ themeLayout: ThemeLayout; /** 是否拉伸布局 */ themeStretch: boolean; /** 是否显示面包屑导航 */ breadCrumb: boolean; /** 是否启用多标签页 */ multiTab: boolean; }; /** * 设置状态管理器类型定义 * @interface SettingStore */ type SettingStore = { /** 当前设置状态 */ settings: SettingsType; /** 操作方法集合,使用 actions 命名空间避免状态污染 */ actions: { /** 更新设置并同步到本地存储 */ setSettings: (settings: SettingsType) => void; /** 清除本地存储的设置 */ clearSettings: () => void; /** 切换主题模式 */ toggleThemeMode: () => void; }; }; // ==================== 本地存储操作函数 ==================== /** * 将数据存储到 localStorage * @template T - 存储值的类型 * @param key - 存储键名 * @param value - 要存储的值 */ export const setItem = (key: StorageEnum, value: T): void => { // 关键代码行注释:检查客户端环境再进行localStorage操作 if (typeof window !== 'undefined') { // 将对象序列化为 JSON 字符串存储 localStorage.setItem(key, JSON.stringify(value)); } }; /** * 从 localStorage 中移除指定键的数据 * @param key - 要移除的键名 */ export const removeItem = (key: StorageEnum): void => { // 关键代码行注释:SSR兼容性检查 if (typeof window !== 'undefined') { localStorage.removeItem(key); } }; /** * 清空所有 localStorage 数据 */ export const clearItems = () => { // 关键代码行注释:SSR兼容性检查 if (typeof window !== 'undefined') { localStorage.clear(); } }; // ==================== 默认设置配置 ==================== /** * 默认设置配置 * 确保服务端和客户端初始化时使用相同的默认值 */ const DEFAULT_SETTINGS: SettingsType = { themeColorPresets: ThemeColorPresets.Default, themeMode: ThemeMode.Light, // 关键代码行注释:SSR时默认使用明亮模式 themeLayout: ThemeLayout.Vertical, themeStretch: true, breadCrumb: true, multiTab: true, }; // ==================== Zustand 状态管理器 ==================== /** * 设置状态管理器 * 使用 zustand 创建全局设置状态,包含默认配置和操作方法 */ const useSettingStore = create((set) => ({ // 关键代码行注释:初始化设置,服务端渲染时使用默认值,客户端使用localStorage或默认值 settings: typeof window !== 'undefined' ? getItem(StorageEnum.Settings) || DEFAULT_SETTINGS : DEFAULT_SETTINGS, // 操作方法集合 actions: { /** * 设置新的配置并同步到本地存储 * @param settings - 新的设置配置 */ setSettings: (settings) => { // 更新状态 set({ settings }); // 同步保存到本地存储 setItem(StorageEnum.Settings, settings); }, /** * 清除本地存储的设置数据 * 注意:这里只清除本地存储,不重置当前状态 */ clearSettings() { removeItem(StorageEnum.Settings); }, /** * 切换主题模式 */ toggleThemeMode() { set((state) => { // 切换主题模式:明亮 ↔ 暗黑 const newThemeMode = state.settings.themeMode === ThemeMode.Light ? ThemeMode.Dark : ThemeMode.Light; // 创建新的设置对象 const newSettings = { ...state.settings, themeMode: newThemeMode, }; // 同步保存到本地存储 setItem(StorageEnum.Settings, newSettings); // 返回新状态 return { settings: newSettings }; }); }, }, })); // ==================== 导出的 Hook 函数 ==================== /** * 获取当前设置状态的 Hook * @returns 当前的设置配置对象 */ export const useSettings = () => useSettingStore((state) => state.settings); /** * 获取设置操作方法的 Hook * @returns 设置操作方法对象(setSettings, clearSettings, toggleThemeMode) */ export const useSettingActions = () => useSettingStore((state) => state.actions); /** * 获取当前主题模式的 Hook * @returns 当前的主题模式(ThemeMode.Light 或 ThemeMode.Dark) */ export const useThemeMode = () => useSettingStore((state) => state.settings.themeMode);