feat(admin-portal): 完整实现 admin-portal 管理端微前端

包含 src 全部实现、Dockerfile、配置文件等
This commit is contained in:
SpecialX
2026-07-10 19:09:12 +08:00
parent 02d09c47fa
commit b3511910d1
69 changed files with 11955 additions and 693 deletions

View File

@@ -0,0 +1,107 @@
"use client";
import {
createContext,
useContext,
useState,
useEffect,
useCallback,
type ReactNode,
} from "react";
import {
getToken,
getUser,
login as loginApi,
logout as logoutApi,
} from "@/lib/auth";
import type { CurrentUser } from "@/types/view-models";
interface AuthContextValue {
user: CurrentUser | null;
isAuthenticated: boolean;
isLoading: boolean;
hasPermission: (perm: string) => boolean;
hasAnyPermission: (perms: string[]) => boolean;
login: (email: string, password: string) => Promise<void>;
logout: () => void;
}
const AuthContext = createContext<AuthContextValue | null>(null);
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUserState] = useState<CurrentUser | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const token = getToken();
const stored = getUser();
if (token && stored) {
setUserState(stored);
}
setIsLoading(false);
}, []);
const login = useCallback(async (email: string, password: string) => {
const result = await loginApi(email, password);
setUserState(result.user);
}, []);
const logout = useCallback(() => {
setUserState(null);
logoutApi();
}, []);
const hasPermission = useCallback(
(perm: string) => {
if (!user) return false;
if (user.permissions.includes("*")) return true;
return user.permissions.includes(perm);
},
[user],
);
const hasAnyPermission = useCallback(
(perms: string[]) => {
if (!user) return false;
if (user.permissions.includes("*")) return true;
return perms.some((p) => user.permissions.includes(p));
},
[user],
);
return (
<AuthContext.Provider
value={{
user,
isAuthenticated: user !== null,
isLoading,
hasPermission,
hasAnyPermission,
login,
logout,
}}
>
{children}
</AuthContext.Provider>
);
}
export function useAuth(): AuthContextValue {
const ctx = useContext(AuthContext);
if (!ctx) {
throw new Error("useAuth must be used within AuthProvider");
}
return ctx;
}
/** 权限 Hook复用 AuthProvider */
export function usePermission() {
const { user, hasPermission, hasAnyPermission } = useAuth();
return {
hasPermission,
hasAnyPermission,
permissions: user?.permissions ?? [],
dataScope: user?.dataScope ?? "SELF",
roles: user?.roles ?? [],
};
}