chore: 初始化仓库基线(AGENTS.md、git 规范、敏感文件排除)
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { create } from 'zustand';
|
||||
import type { Room, TelemetryRecord } from '../types';
|
||||
|
||||
interface AppState {
|
||||
currentRoom: Room | null;
|
||||
setCurrentRoom: (room: Room | null) => void;
|
||||
refreshTrigger: number;
|
||||
triggerRefresh: () => void;
|
||||
realtimeData: TelemetryRecord[];
|
||||
setRealtimeData: (data: TelemetryRecord[]) => void;
|
||||
wsConnected: boolean;
|
||||
setWsConnected: (connected: boolean) => void;
|
||||
}
|
||||
|
||||
export const useAppStore = create<AppState>()((set) => ({
|
||||
currentRoom: null,
|
||||
setCurrentRoom: (room) => set({ currentRoom: room }),
|
||||
refreshTrigger: 0,
|
||||
triggerRefresh: () => set((state) => ({ refreshTrigger: state.refreshTrigger + 1 })),
|
||||
realtimeData: [],
|
||||
setRealtimeData: (data) => set({ realtimeData: data }),
|
||||
wsConnected: false,
|
||||
setWsConnected: (connected) => set({ wsConnected: connected }),
|
||||
}));
|
||||
@@ -0,0 +1,97 @@
|
||||
import { create } from 'zustand';
|
||||
import { persist, createJSONStorage } from 'zustand/middleware';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { loginApi, getMeApi } from '../api/auth';
|
||||
import { TOKEN_KEY, REFRESH_TOKEN_KEY } from '../api/client';
|
||||
import { wsManager } from '../utils/ws';
|
||||
import type { User } from '../types';
|
||||
|
||||
interface AuthState {
|
||||
token: string | null;
|
||||
refreshToken: string | null;
|
||||
user: User | null;
|
||||
isLoading: boolean;
|
||||
error: string | null;
|
||||
login: (username: string, password: string) => Promise<boolean>;
|
||||
logout: () => Promise<void>;
|
||||
fetchUser: () => Promise<void>;
|
||||
restoreSession: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const useAuthStore = create<AuthState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
token: null,
|
||||
refreshToken: null,
|
||||
user: null,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
|
||||
login: async (username: string, password: string) => {
|
||||
set({ isLoading: true, error: null });
|
||||
try {
|
||||
const res = await loginApi(username, password);
|
||||
const token = res.accessToken;
|
||||
const refreshToken = res.refreshToken || null;
|
||||
|
||||
await AsyncStorage.setItem(TOKEN_KEY, token);
|
||||
if (refreshToken) {
|
||||
await AsyncStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
|
||||
}
|
||||
|
||||
set({
|
||||
token,
|
||||
refreshToken,
|
||||
user: res.user,
|
||||
isLoading: false,
|
||||
error: null,
|
||||
});
|
||||
|
||||
wsManager.connect(token);
|
||||
return true;
|
||||
} catch (err: any) {
|
||||
const msg =
|
||||
err?.response?.data?.message ||
|
||||
err?.response?.data?.msg ||
|
||||
err?.message ||
|
||||
'登录失败';
|
||||
set({ isLoading: false, error: msg });
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
logout: async () => {
|
||||
wsManager.disconnect();
|
||||
await AsyncStorage.multiRemove([TOKEN_KEY, REFRESH_TOKEN_KEY]);
|
||||
set({ token: null, refreshToken: null, user: null, error: null });
|
||||
},
|
||||
|
||||
fetchUser: async () => {
|
||||
const user = await getMeApi();
|
||||
set({ user });
|
||||
},
|
||||
|
||||
restoreSession: async () => {
|
||||
const token = await AsyncStorage.getItem(TOKEN_KEY);
|
||||
if (token) {
|
||||
set({ token });
|
||||
try {
|
||||
await get().fetchUser();
|
||||
wsManager.connect(token);
|
||||
} catch {
|
||||
await get().logout();
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: 'auth-storage',
|
||||
storage: createJSONStorage(() => AsyncStorage),
|
||||
partialize: (state) => ({
|
||||
token: state.token,
|
||||
refreshToken: state.refreshToken,
|
||||
user: state.user,
|
||||
}),
|
||||
},
|
||||
),
|
||||
);
|
||||
Reference in New Issue
Block a user