feat: update

This commit is contained in:
2025-11-06 16:37:01 +08:00
parent c0d54b8513
commit 855f289579
59 changed files with 3398 additions and 572 deletions

36
stores/index.ts Normal file
View File

@@ -0,0 +1,36 @@
/**
* Stores 模块统一导出
*/
// User Store
export {
useUserStore,
useUser,
useIsLoggedIn,
useToken,
useUserActions,
restoreUserState,
} from './userStore';
export type { User } from './userStore';
// Settings Store
export {
useSettingsStore,
useTheme,
useLanguage,
useNotificationsEnabled,
useSoundEnabled,
useHapticsEnabled,
useSettingsActions,
restoreSettingsState,
} from './settingsStore';
export type { Theme, Language } from './settingsStore';
// Tenant Store
export {
default as useTenantStore,
useTenantInfo,
useTenantStates,
useTenantActions,
restoreTenantState,
} from './tenantStore';

167
stores/settingsStore.ts Normal file
View File

@@ -0,0 +1,167 @@
/**
* 应用设置状态管理
* 使用 Zustand + AsyncStorage 持久化
*/
import { create } from 'zustand';
import { useShallow } from 'zustand/react/shallow';
import AsyncStorage from '@react-native-async-storage/async-storage';
/**
* 主题类型
*/
export type Theme = 'light' | 'dark' | 'auto';
/**
* 语言类型
*/
export type Language = 'zh-CN' | 'en-US';
/**
* 设置状态接口
*/
interface SettingsState {
// 状态
theme: Theme;
language: Language;
notificationsEnabled: boolean;
soundEnabled: boolean;
hapticsEnabled: boolean;
// 操作
setTheme: (theme: Theme) => void;
setLanguage: (language: Language) => void;
setNotificationsEnabled: (enabled: boolean) => void;
setSoundEnabled: (enabled: boolean) => void;
setHapticsEnabled: (enabled: boolean) => void;
resetSettings: () => void;
}
/**
* 默认设置
*/
const DEFAULT_SETTINGS = {
theme: 'auto' as Theme,
language: 'zh-CN' as Language,
notificationsEnabled: true,
soundEnabled: true,
hapticsEnabled: true,
};
/**
* 设置状态 Store
*/
export const useSettingsStore = create<SettingsState>()((set, get) => ({
// 初始状态
...DEFAULT_SETTINGS,
// 设置主题
setTheme: (theme) => {
set({ theme });
// 手动持久化
AsyncStorage.setItem('settings-storage', JSON.stringify(get()));
if (__DEV__) {
console.log('🎨 Theme changed:', theme);
}
},
// 设置语言
setLanguage: (language) => {
set({ language });
// 手动持久化
AsyncStorage.setItem('settings-storage', JSON.stringify(get()));
if (__DEV__) {
console.log('🌐 Language changed:', language);
}
},
// 设置通知开关
setNotificationsEnabled: (enabled) => {
set({ notificationsEnabled: enabled });
// 手动持久化
AsyncStorage.setItem('settings-storage', JSON.stringify(get()));
if (__DEV__) {
console.log('🔔 Notifications:', enabled ? 'enabled' : 'disabled');
}
},
// 设置声音开关
setSoundEnabled: (enabled) => {
set({ soundEnabled: enabled });
// 手动持久化
AsyncStorage.setItem('settings-storage', JSON.stringify(get()));
if (__DEV__) {
console.log('🔊 Sound:', enabled ? 'enabled' : 'disabled');
}
},
// 设置触觉反馈开关
setHapticsEnabled: (enabled) => {
set({ hapticsEnabled: enabled });
// 手动持久化
AsyncStorage.setItem('settings-storage', JSON.stringify(get()));
if (__DEV__) {
console.log('📳 Haptics:', enabled ? 'enabled' : 'disabled');
}
},
// 重置所有设置
resetSettings: () => {
set(DEFAULT_SETTINGS);
// 手动持久化
AsyncStorage.setItem('settings-storage', JSON.stringify(DEFAULT_SETTINGS));
if (__DEV__) {
console.log('🔄 Settings reset to default');
}
},
}));
// 从 AsyncStorage 恢复状态的函数
export const restoreSettingsState = async () => {
try {
const stored = await AsyncStorage.getItem('settings-storage');
if (stored) {
const state = JSON.parse(stored);
useSettingsStore.setState(state);
if (__DEV__) {
console.log('✅ Settings state restored from storage');
}
}
} catch (error) {
console.error('Failed to restore settings state:', error);
}
};
/**
* 选择器 Hooks
*/
// 获取主题
export const useTheme = () => useSettingsStore((state) => state.theme);
// 获取语言
export const useLanguage = () => useSettingsStore((state) => state.language);
// 获取通知状态
export const useNotificationsEnabled = () =>
useSettingsStore((state) => state.notificationsEnabled);
// 获取声音状态
export const useSoundEnabled = () => useSettingsStore((state) => state.soundEnabled);
// 获取触觉反馈状态
export const useHapticsEnabled = () => useSettingsStore((state) => state.hapticsEnabled);
// 获取设置操作方法
// 使用 useShallow 避免每次渲染都返回新对象
export const useSettingsActions = () =>
useSettingsStore(
useShallow((state) => ({
setTheme: state.setTheme,
setLanguage: state.setLanguage,
setNotificationsEnabled: state.setNotificationsEnabled,
setSoundEnabled: state.setSoundEnabled,
setHapticsEnabled: state.setHapticsEnabled,
resetSettings: state.resetSettings,
}))
);

122
stores/tenantStore.ts Normal file
View File

@@ -0,0 +1,122 @@
/**
* 租户状态管理
* 使用 Zustand + AsyncStorage 持久化
*/
import { create } from 'zustand';
import { useShallow } from 'zustand/react/shallow';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { STORAGE_KEYS } from '@/utils/storage';
import { tenantService } from '@/services/tenantService';
import { useEffect } from 'react';
/**
* 租户信息接口
*/
// export interface Tenant {
// id: string;
// username: string;
// email: string;
// avatar?: string;
// nickname?: string;
// phone?: string;
// createdAt?: string;
// }
/**
* 租户状态接口
*/
interface TenantState {
// 状态
tenantInfo: Record<string, any> | null;
// 操作
setTenantInfo: (data: Record<string, any>) => void;
requestTenantInfo: (data?: Record<string, any>) => Promise<any>;
}
/**
* 租户状态 Store
*/
const useTenantStore = create<TenantState>()((set, get) => ({
// 初始状态
tenantInfo: null,
// 设置租户信息(通用方法,包含持久化逻辑)
setTenantInfo: (data: any) => {
set({ tenantInfo: data });
// 手动持久化
// AsyncStorage.setItem(STORAGE_KEYS.TENANT_STORE, JSON.stringify({ tenantInfo: data }));
if (__DEV__) {
console.log('💾 Tenant info saved:', data);
}
},
// 获取租户信息(调用 API 并使用 setTenantInfo 保存)
requestTenantInfo: async () => {
try {
const params = {
domain_addr: 'https://51zhh5.notbug.org',
};
const { data } = await tenantService.getPlatformData(params);
// 调用 setTenantInfo 来保存数据,避免重复代码
get().setTenantInfo(data);
if (__DEV__) {
console.log('✅ Tenant info loaded:', data);
}
return Promise.resolve(data);
} catch (error) {
console.error('Failed to request tenant info:', error);
return Promise.reject(error);
}
},
}));
// 从 AsyncStorage 恢复状态的函数
export const restoreTenantState = async () => {
try {
const stored = await AsyncStorage.getItem(STORAGE_KEYS.TENANT_STORE);
if (stored) {
const state = JSON.parse(stored);
useTenantStore.setState(state);
if (__DEV__) {
console.log('✅ Tenant state restored from storage');
}
}
} catch (error) {
console.error('Failed to restore tenant state:', error);
}
};
/**
* 选择器 Hooks优化性能避免不必要的重渲染
*/
// 获取用户信息
export const useTenantInfo = () => useTenantStore((state) => state.tenantInfo);
// 获取租户状态
export const useTenantStates = () =>
useTenantStore(
useShallow((state) => ({
tenantInfo: state.tenantInfo,
tenantLoad: !!state.tenantInfo?.tid || !!state.tenantInfo?.create_time,
}))
);
// 获取租户操作方法
// 使用 useShallow 避免每次渲染都返回新对象
export const useTenantActions = () =>
useTenantStore(
useShallow((state) => ({
setTenantInfo: state.setTenantInfo,
requestTenantInfo: state.requestTenantInfo,
}))
);
export default useTenantStore;

161
stores/userStore.ts Normal file
View File

@@ -0,0 +1,161 @@
/**
* 用户状态管理
* 使用 Zustand + AsyncStorage 持久化
*/
import { create } from 'zustand';
import { useShallow } from 'zustand/react/shallow';
import AsyncStorage from '@react-native-async-storage/async-storage';
/**
* 用户信息接口
*/
export interface User {
id: string;
username: string;
email: string;
avatar?: string;
nickname?: string;
phone?: string;
createdAt?: string;
}
/**
* 用户状态接口
*/
interface UserState {
// 状态
user: User | null;
isLoggedIn: boolean;
token: string | null;
// 操作
setUser: (user: User) => void;
setToken: (token: string) => void;
login: (user: User, token: string) => void;
logout: () => void;
updateUser: (updates: Partial<User>) => void;
}
/**
* 用户状态 Store
*/
export const useUserStore = create<UserState>()((set, get) => ({
// 初始状态
user: null,
isLoggedIn: false,
token: null,
// 设置用户信息
setUser: (user) => {
const newState = { user, isLoggedIn: true };
set(newState);
// 手动持久化
AsyncStorage.setItem('user-storage', JSON.stringify(newState));
},
// 设置 token
setToken: (token) => {
set({ token });
// 手动持久化 - 延迟执行以确保状态已更新
setTimeout(() => {
const state = get();
AsyncStorage.setItem('user-storage', JSON.stringify(state));
}, 0);
},
// 登录
login: (user, token) => {
const newState = {
user,
token,
isLoggedIn: true,
};
set(newState);
// 同时保存 token 到 AsyncStorage用于 API 请求)
AsyncStorage.setItem('auth_token', token);
// 手动持久化整个状态
AsyncStorage.setItem('user-storage', JSON.stringify(newState));
if (__DEV__) {
console.log('✅ User logged in:', user.username);
}
},
// 登出
logout: () => {
const newState = {
user: null,
token: null,
isLoggedIn: false,
};
set(newState);
// 清除 AsyncStorage 中的 token
AsyncStorage.removeItem('auth_token');
// 清除持久化状态
AsyncStorage.removeItem('user-storage');
if (__DEV__) {
console.log('👋 User logged out');
}
},
// 更新用户信息
updateUser: (updates) => {
const currentUser = get().user;
if (currentUser) {
const newUser = { ...currentUser, ...updates };
set({ user: newUser });
// 手动持久化
AsyncStorage.setItem('user-storage', JSON.stringify({ ...get(), user: newUser }));
if (__DEV__) {
console.log('📝 User updated:', updates);
}
}
},
}));
// 从 AsyncStorage 恢复状态的函数
export const restoreUserState = async () => {
try {
const stored = await AsyncStorage.getItem('user-storage');
if (stored) {
const state = JSON.parse(stored);
useUserStore.setState(state);
if (__DEV__) {
console.log('✅ User state restored from storage');
}
}
} catch (error) {
console.error('Failed to restore user state:', error);
}
};
/**
* 选择器 Hooks优化性能避免不必要的重渲染
*/
// 获取用户信息
export const useUser = () => useUserStore((state) => state.user);
// 获取登录状态
export const useIsLoggedIn = () => useUserStore((state) => state.isLoggedIn);
// 获取 token
export const useToken = () => useUserStore((state) => state.token);
// 获取用户操作方法
// 使用 useShallow 避免每次渲染都返回新对象
export const useUserActions = () =>
useUserStore(
useShallow((state) => ({
setUser: state.setUser,
setToken: state.setToken,
login: state.login,
logout: state.logout,
updateUser: state.updateUser,
}))
);