feat: 优化web
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
'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 };
|
||||
}
|
||||
Reference in New Issue
Block a user