Files
SaaS2/src/store/settingStore.ts
2025-06-05 23:05:33 +08:00

209 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 设置状态管理器
* @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 = <T>(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 = <T>(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<SettingStore>((set) => ({
// 关键代码行注释初始化设置服务端渲染时使用默认值客户端使用localStorage或默认值
settings: typeof window !== 'undefined'
? getItem<SettingsType>(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);