feat: update
This commit is contained in:
36
stores/index.ts
Normal file
36
stores/index.ts
Normal 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
167
stores/settingsStore.ts
Normal 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
122
stores/tenantStore.ts
Normal 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
161
stores/userStore.ts
Normal 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,
|
||||
}))
|
||||
);
|
||||
Reference in New Issue
Block a user