hyapp-admin-platform/src/app/app-scope/AppScopeProvider.jsx
2026-05-02 13:02:57 +08:00

72 lines
2.3 KiB
JavaScript

import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
import { useQueryClient } from "@tanstack/react-query";
import { useAuth } from "@/app/auth/AuthProvider.jsx";
import { listAdminApps } from "@/features/app-registry/api";
import { getSelectedAppCode, setSelectedAppCode as setRequestAppCode } from "@/shared/api/request";
import { useAdminQuery } from "@/shared/hooks/useAdminQuery.js";
const AppScopeContext = createContext(null);
const fallbackAppCode = "lalu";
const emptyAppState = { items: [], total: 0 };
export function AppScopeProvider({ children }) {
const { user } = useAuth();
const queryClient = useQueryClient();
const [appCode, setAppCodeState] = useState(() => getSelectedAppCode() || fallbackAppCode);
const { data = emptyAppState, error, loading } = useAdminQuery(() => listAdminApps(), {
enabled: Boolean(user),
errorMessage: "加载 App 列表失败",
initialData: emptyAppState,
queryKey: ["admin-apps"],
staleTime: 5 * 60 * 1000
});
const apps = useMemo(() => data?.items || [], [data?.items]);
const applyAppCode = useCallback(
async (nextAppCode, options = {}) => {
const normalized = normalizeAppCode(nextAppCode) || fallbackAppCode;
setRequestAppCode(normalized);
setAppCodeState(normalized);
if (!options.skipRefresh) {
await queryClient.invalidateQueries({ refetchType: "active" });
}
},
[queryClient]
);
useEffect(() => {
if (!apps.length) {
return;
}
const selectedExists = apps.some((item) => normalizeAppCode(item.appCode) === normalizeAppCode(appCode));
if (!selectedExists) {
void applyAppCode(apps[0].appCode, { skipRefresh: false });
}
}, [appCode, applyAppCode, apps]);
const value = useMemo(
() => ({
appCode,
apps,
error,
loading,
setAppCode: applyAppCode
}),
[appCode, applyAppCode, apps, error, loading]
);
return <AppScopeContext.Provider value={value}>{children}</AppScopeContext.Provider>;
}
export function useAppScope() {
const context = useContext(AppScopeContext);
if (!context) {
throw new Error("useAppScope must be used inside AppScopeProvider");
}
return context;
}
function normalizeAppCode(value) {
return String(value || "").trim().toLowerCase();
}