72 lines
2.3 KiB
JavaScript
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();
|
|
}
|