|
|
|
|
/**
|
|
|
|
|
* 用户状态管理
|
|
|
|
|
* 使用 Zustand + AsyncStorage 持久化
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { create } from 'zustand';
|
|
|
|
|
import { useShallow } from 'zustand/react/shallow';
|
|
|
|
|
import storageManager, { STORAGE_KEYS } from '@/utils/storageManager';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用户信息接口
|
|
|
|
|
*/
|
|
|
|
|
export interface User {
|
|
|
|
|
id: string;
|
|
|
|
|
username: string;
|
|
|
|
|
email: string;
|
|
|
|
|
avatar?: string;
|
|
|
|
|
nickname?: string;
|
|
|
|
|
phone?: string;
|
|
|
|
|
createdAt?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 状态
|
|
|
|
|
interface State {
|
|
|
|
|
user: User | null;
|
|
|
|
|
isLoggedIn: boolean;
|
|
|
|
|
token: string | null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 操作
|
|
|
|
|
interface Actions {
|
|
|
|
|
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<State & Actions>()((set, get) => ({
|
|
|
|
|
// 初始状态
|
|
|
|
|
user: null,
|
|
|
|
|
isLoggedIn: false,
|
|
|
|
|
token: null,
|
|
|
|
|
|
|
|
|
|
// 设置用户信息
|
|
|
|
|
setUser: (user) => {
|
|
|
|
|
const newState = { user, isLoggedIn: true };
|
|
|
|
|
set(newState);
|
|
|
|
|
// 手动持久化
|
|
|
|
|
storageManager.session.setItem(STORAGE_KEYS.USER_STORE, newState);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 设置 token
|
|
|
|
|
setToken: (token) => {
|
|
|
|
|
set({ token });
|
|
|
|
|
// 手动持久化 - 延迟执行以确保状态已更新
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
storageManager.session.setItem(STORAGE_KEYS.USER_STORE, get());
|
|
|
|
|
}, 0);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 登录
|
|
|
|
|
login: (user, token) => {
|
|
|
|
|
const newState = {
|
|
|
|
|
user,
|
|
|
|
|
token,
|
|
|
|
|
isLoggedIn: true,
|
|
|
|
|
};
|
|
|
|
|
set(newState);
|
|
|
|
|
|
|
|
|
|
// 同时保存 token 到 AsyncStorage(用于 API 请求)
|
|
|
|
|
storageManager.session.setItem('auth_token', token);
|
|
|
|
|
// 手动持久化整个状态
|
|
|
|
|
storageManager.session.setItem(STORAGE_KEYS.USER_STORE, newState);
|
|
|
|
|
|
|
|
|
|
if (__DEV__) {
|
|
|
|
|
console.log('✅ User logged in:', user.username);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 登出
|
|
|
|
|
logout: () => {
|
|
|
|
|
const newState = {
|
|
|
|
|
user: null,
|
|
|
|
|
token: null,
|
|
|
|
|
isLoggedIn: false,
|
|
|
|
|
};
|
|
|
|
|
set(newState);
|
|
|
|
|
|
|
|
|
|
// 清除 AsyncStorage 中的 token
|
|
|
|
|
storageManager.session.removeItem('auth_token');
|
|
|
|
|
// 清除持久化状态
|
|
|
|
|
storageManager.session.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 });
|
|
|
|
|
// 手动持久化
|
|
|
|
|
storageManager.session.setItem(STORAGE_KEYS.USER_STORE, { ...get(), user: newUser });
|
|
|
|
|
|
|
|
|
|
if (__DEV__) {
|
|
|
|
|
console.log('📝 User updated:', updates);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
// 从 AsyncStorage 恢复状态的函数
|
|
|
|
|
export const restoreUserState = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const stored = await storageManager.session.getItem(STORAGE_KEYS.USER_STORE);
|
|
|
|
|
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,
|
|
|
|
|
}))
|
|
|
|
|
);
|