AuthContext.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import React, { createContext, useContext, useEffect, useState } from 'react';
  2. import { clearToken, getToken } from '@/services/http';
  3. import { getUserInfo, logout as logoutApi, UserInfo } from '@/services/user';
  4. interface AuthContextType {
  5. isLoggedIn: boolean;
  6. user: UserInfo | null;
  7. loading: boolean;
  8. refreshUser: () => Promise<void>;
  9. logout: () => Promise<void>;
  10. }
  11. const AuthContext = createContext<AuthContextType>({
  12. isLoggedIn: false,
  13. user: null,
  14. loading: true,
  15. refreshUser: async () => {},
  16. logout: async () => {},
  17. });
  18. export function AuthProvider({ children }: { children: React.ReactNode }) {
  19. const [user, setUser] = useState<UserInfo | null>(null);
  20. const [loading, setLoading] = useState(true);
  21. const [hasToken, setHasToken] = useState(false);
  22. const refreshUser = async () => {
  23. try {
  24. const token = getToken();
  25. setHasToken(!!token);
  26. if (token) {
  27. const info = await getUserInfo();
  28. setUser(info);
  29. } else {
  30. setUser(null);
  31. }
  32. } catch (error) {
  33. console.error('获取用户信息失败:', error);
  34. setUser(null);
  35. }
  36. };
  37. const logout = async () => {
  38. try {
  39. await logoutApi();
  40. } catch (e) {
  41. console.warn('Logout API failed', e);
  42. }
  43. setUser(null);
  44. setHasToken(false);
  45. await clearToken();
  46. };
  47. useEffect(() => {
  48. const init = async () => {
  49. await refreshUser();
  50. setLoading(false);
  51. };
  52. init();
  53. }, []);
  54. return (
  55. <AuthContext.Provider
  56. value={{
  57. isLoggedIn: hasToken,
  58. user,
  59. loading,
  60. refreshUser,
  61. logout,
  62. }}
  63. >
  64. {children}
  65. </AuthContext.Provider>
  66. );
  67. }
  68. export const useAuth = () => useContext(AuthContext);