AuthContext.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { createContext, useContext, useState, useEffect } from "react";
  2. import type { ReactNode } from "react";
  3. import type { JeecgMenu } from "@/types/menu";
  4. import { getUserPermissions } from "@/services/api";
  5. import { isPublicRoute } from "@/router/publicRoutes.tsx";
  6. interface AuthContextType {
  7. menus: JeecgMenu[];
  8. permissions: Map<string, string[]>; // menuId -> actions[]
  9. loading: boolean;
  10. hasPermission: (menuId: string, action: string) => boolean;
  11. refreshAuth: () => Promise<void>;
  12. }
  13. const AuthContext = createContext<AuthContextType | undefined>(undefined);
  14. export function AuthProvider({ children }: { children: ReactNode }) {
  15. const [menus, setMenus] = useState<JeecgMenu[]>([]);
  16. const [permissions] = useState<Map<string, string[]>>(
  17. new Map()
  18. );
  19. const [loading, setLoading] = useState(true);
  20. const loadAuthData = async () => {
  21. try {
  22. setLoading(true);
  23. const [menusData] = await Promise.all([
  24. getUserPermissions(),
  25. ]);
  26. setMenus(menusData.menu);
  27. } catch (error) {
  28. console.error("加载权限数据失败:", error);
  29. } finally {
  30. setLoading(false);
  31. }
  32. };
  33. useEffect(() => {
  34. // 如果在公开路由页面,跳过权限加载
  35. const currentPath = window.location.pathname;
  36. if (isPublicRoute(currentPath)) {
  37. setLoading(false);
  38. return;
  39. }
  40. loadAuthData();
  41. }, []);
  42. const hasPermission = (menuId: string, action: string): boolean => {
  43. const actions = permissions.get(menuId);
  44. return actions ? actions.includes(action) : false;
  45. };
  46. return (
  47. <AuthContext.Provider
  48. value={{
  49. menus,
  50. permissions,
  51. loading,
  52. hasPermission,
  53. refreshAuth: loadAuthData,
  54. }}
  55. >
  56. {children}
  57. </AuthContext.Provider>
  58. );
  59. }
  60. export function useAuth() {
  61. const context = useContext(AuthContext);
  62. if (!context) {
  63. throw new Error("useAuth must be used within AuthProvider");
  64. }
  65. return context;
  66. }