Files
Edu/packages/hooks/src/use-permission.ts
SpecialX faaaf29f67 docs: ai 协作文档体系重构与多 ai 仲裁结果落地
1.AI 协作文档体系重构(objections/worklines/contracts+matrix.md)

2.coord 仲裁文档(final-decisions/cross-review/final-rulings/orchestration)

3.各服务 01/02 文档补全

4.共享包初始化(shared-ts/shared-go/hooks/ui-components/ui-tokens)

5.Proto 契约补全

6.004 架构影响地图更新

7.端口分配表

8.设计规格文档
2026-07-10 12:58:22 +08:00

77 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useCallback, useMemo } from "react";
import type { PermissionContext } from "./types.js";
/**
* usePermission - 权限查询 Hook
*
* 用途L2 路由级 + L3 组件级视口控制。
* 权限点命名遵循 F7 裁决:`<RESOURCE>_<ACTION>`(如 `EXAM_READ`)。
* 数据范围用后缀 `_OWN`/`_CHILD`(如 `GRADE_READ_CHILD`)。
*
* 注意权限数据由调用方注入apps/* 从 iam /iam/permissions/effective 获取后传入)。
* 本 hook 不直接调 API保持纯客户端逻辑。
*
* @example
* const { hasPermission, hasAny, hasAll } = usePermission({ permissions, dataScope, roles });
*
* if (hasPermission("EXAM_CREATE")) { ... }
* if (hasPermission("GRADE_READ_CHILD")) { ... } // 数据范围后缀
*/
export interface UsePermissionProps {
/** 权限上下文(从 iam /iam/permissions/effective 获取) */
context: PermissionContext | null;
}
export interface UsePermissionReturn {
/** 检查是否拥有指定权限点 */
hasPermission: (perm: string) => boolean;
/** 检查是否拥有任一权限点 */
hasAny: (...perms: string[]) => boolean;
/** 检查是否拥有全部权限点 */
hasAll: (...perms: string[]) => boolean;
/** 检查是否拥有指定角色 */
hasRole: (role: string) => boolean;
/** 当前数据范围 */
dataScope: PermissionContext["dataScope"] | null;
}
export function usePermission({
context,
}: UsePermissionProps): UsePermissionReturn {
const permissions = context?.permissions ?? [];
const roles = context?.roles ?? [];
const dataScope = context?.dataScope ?? null;
const permissionSet = useMemo(() => new Set(permissions), [permissions]);
const roleSet = useMemo(() => new Set(roles), [roles]);
const hasPermission = useCallback(
(perm: string): boolean => permissionSet.has(perm),
[permissionSet],
);
const hasAny = useCallback(
(...perms: string[]): boolean => perms.some((p) => permissionSet.has(p)),
[permissionSet],
);
const hasAll = useCallback(
(...perms: string[]): boolean => perms.every((p) => permissionSet.has(p)),
[permissionSet],
);
const hasRole = useCallback(
(role: string): boolean => roleSet.has(role),
[roleSet],
);
return {
hasPermission,
hasAny,
hasAll,
hasRole,
dataScope,
};
}