71 lines
2.0 KiB
TypeScript
71 lines
2.0 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import { iamMenu } from '@/lib/api/iam';
|
|
import type { MenuNode } from '@/lib/api/types/menu';
|
|
import { useAuthStore } from '@/stores/auth-store';
|
|
import { useLayoutStore } from '@/stores/layout-store';
|
|
import { useTenantStore } from '@/stores/tenant-store';
|
|
|
|
type NavMenuState = {
|
|
items: MenuNode[];
|
|
loading: boolean;
|
|
error: string | null;
|
|
authed: boolean;
|
|
permissions: string[];
|
|
};
|
|
|
|
/** 从 AppChrome 提取的导航菜单数据获取逻辑 */
|
|
export function useNavMenu(): NavMenuState {
|
|
const accessToken = useAuthStore((s) => s.accessToken);
|
|
const authed = Boolean(accessToken);
|
|
const tenantId = useTenantStore((s) => s.tenantId);
|
|
const setPerms = useLayoutStore((s) => s.setPerms);
|
|
|
|
const [items, setItems] = useState<MenuNode[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [permissions, setPermissions] = useState<string[]>([]);
|
|
|
|
useEffect(() => {
|
|
if (!accessToken) {
|
|
setItems([]);
|
|
setError(null);
|
|
setPerms([]);
|
|
setPermissions([]);
|
|
return;
|
|
}
|
|
let cancelled = false;
|
|
setLoading(true);
|
|
setError(null);
|
|
Promise.all([
|
|
iamMenu.nav().catch(() => [] as MenuNode[]),
|
|
iamMenu.perms().catch(() => ({ perms: [] as string[] })),
|
|
])
|
|
.then(([tree, pr]) => {
|
|
if (cancelled) return;
|
|
const navItems = Array.isArray(tree) ? tree : [];
|
|
const perms = Array.isArray(pr?.perms) ? pr.perms : [];
|
|
setItems(navItems);
|
|
setPerms(perms);
|
|
setPermissions(perms);
|
|
})
|
|
.catch((e: unknown) => {
|
|
if (!cancelled) {
|
|
setError(e instanceof Error ? e.message : String(e));
|
|
setItems([]);
|
|
setPerms([]);
|
|
setPermissions([]);
|
|
}
|
|
})
|
|
.finally(() => {
|
|
if (!cancelled) setLoading(false);
|
|
});
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [accessToken, tenantId, setPerms]);
|
|
|
|
return { items, loading, error, authed, permissions };
|
|
}
|