123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- import React, { createContext, ReactNode, useEffect, useReducer } from 'react';
- import { TOKEN_KEY, UserInfo, USERINFO_KEY } from '@app/constants';
- import { getAllItems, storageApp } from '@common/StorageHelper.ts';
- type RequiredUserInfo = Required<UserInfo>;
- type AuthState = {
- loading: boolean;
- token?: string; // token
- userInfo?: RequiredUserInfo; // 用户信息
- };
- type ActionMap = {
- retrieve: { token: string; userInfo: RequiredUserInfo } | undefined; // 应用启动取回本地缓存
- login: { token: string; userInfo: RequiredUserInfo }; // 登录
- logout: undefined; // 退出登录
- update: RequiredUserInfo; // 更新用户信息
- };
- type Action = {
- [Key in keyof ActionMap]: {
- type: Key;
- payload: ActionMap[Key];
- };
- }[keyof ActionMap];
- function reducer(state: AuthState, action: Action): AuthState {
- switch (action.type) {
- case 'retrieve':
- return {
- ...state,
- loading: false,
- token: action.payload?.token,
- userInfo: action.payload?.userInfo,
- };
- case 'login':
- return {
- ...state,
- loading: false,
- token: action.payload.token,
- userInfo: action.payload.userInfo,
- };
- case 'logout':
- return {
- ...state,
- loading: false,
- token: undefined,
- userInfo: undefined,
- };
- case 'update':
- return {
- ...state,
- loading: false,
- userInfo: action.payload,
- };
- }
- }
- const initialState = {
- loading: true,
- token: undefined,
- userInfo: undefined,
- };
- const AuthContext = createContext<
- | {
- state: AuthState;
- dispatch: React.Dispatch<Action>;
- }
- | undefined
- >(undefined);
- const AuthProvider = ({ children }: { children: ReactNode }) => {
- const [state, dispatch] = useReducer(reducer, initialState);
- useEffect(() => {
- async function retrieve() {
- try {
- const values = await getAllItems([
- { key: TOKEN_KEY },
- { key: USERINFO_KEY },
- ]);
- if (values[0][1] && values[1][1]) {
- const tokenValue = values[0][1];
- const userInfoValue = JSON.parse(values[1][1]);
- dispatch({
- type: 'retrieve',
- payload: {
- token: tokenValue,
- userInfo: { ...userInfoValue, isFirstLogin: false },
- },
- });
- } else {
- dispatch({
- type: 'retrieve',
- payload: undefined,
- });
- }
- } catch {
- dispatch({
- type: 'retrieve',
- payload: undefined,
- });
- }
- }
- retrieve();
- }, []);
- return (
- <AuthContext.Provider value={{ state, dispatch }}>
- {children}
- </AuthContext.Provider>
- );
- };
- export type { AuthState, RequiredUserInfo };
- export { AuthContext, AuthProvider };
|