npm package: @seed-fe/react-permission
Description: React permission control components and hooks with declarative and imperative APIs
Author: xianghongai
Latest version: 2.0.0-alpha.1

# @seed-fe/react-permission

基于 React 的权限控制组件库，使用 [@seed-fe/permission](https://www.npmjs.com/package/@seed-fe/permission) 实现批量请求处理和缓存优化。提供声明式和命令式两种权限检查方式。

## 特性

- 🚀 **多种使用方式**：声明式组件 `<Permission>` 和命令式 Hook `usePermission()`
- ⚡ **高性能优化**：基于 `@seed-fe/permission` 的批处理和缓存机制
- 🔒 **类型安全**：完整的 TypeScript 类型定义和支持
- 🔧 **灵活配置**：支持全局配置和组件级别覆盖
- 📦 **轻量级**：核心功能专注于权限控制，依赖最小化

## 安装

```bash
# 使用 pnpm (推荐)
pnpm add @seed-fe/react-permission
# 使用 npm
npm install @seed-fe/react-permission
# 使用 yarn
yarn add @seed-fe/react-permission
```

## 快速开始

### 方式一：使用 PermissionProvider

```tsx
import React from 'react';
import { PermissionProvider } from '@seed-fe/react-permission';
import App from './App';

function Root() {
  return (
    <PermissionProvider
      permissionService={async (configs) => {
        const response = await fetch('/api/permissions/check', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ permissions: configs })
        });
        return response.json(); // 支持返回 boolean[] 或 number[] (0/1)
      }}
      permissionServiceOptions={{
        batch: {
          delay: 50,      // 批处理延迟时间（毫秒）
          maxSize: 100    // 最大批量大小
        },
        cache: {
          enable: true,   // 启用缓存
          ttl: 300000     // 缓存有效期（毫秒，5分钟）
        }
      }}
    >
      <App />
    </PermissionProvider>
  );
}
```

### 方式二：使用配置函数

```tsx
import { configurePermission } from '@seed-fe/react-permission';

// 在应用入口配置
configurePermission({
  permissionService: async (configs) => {
    const response = await fetch('/api/permissions/check', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(configs)
    });
    return response.json(); // 支持返回 boolean[] 或 number[] (0/1)
  },
  permissionServiceOptions: {
    batch: { delay: 50, maxSize: 100 },
    cache: { enable: true, ttl: 300000 }
  }
});
```

## 使用示例

### 声明式权限控制

```tsx
import { Permission } from '@seed-fe/react-permission';

function UserActions() {
  return (
    <div>
      {/* 简单权限检查 */}
      <Permission permission="user.edit">
        <button>编辑用户</button>
      </Permission>

      {/* 多权限码检查（任一满足） */}
      <Permission permission={{ code: ['admin', 'moderator'], mode: 'any' }}>
        <button>管理操作</button>
      </Permission>

      {/* 带业务参数 */}
      <Permission permission={{ code: 'user.delete', biz: { userId: '123' } }}>
        <button>删除用户</button>
      </Permission>

      {/* 自定义加载和无权限状态 */}
      <Permission
        permission="premium.feature"
        loading={<div>检查权限中...</div>}
        fallback={<div>需要升级到高级版</div>}
      >
        <PremiumFeature />
      </Permission>
    </div>
  );
}
```

### 命令式权限检查

```tsx
import { usePermission } from '@seed-fe/react-permission';

function UserManagement() {
  const { hasPermission: canEdit, isLoading: editLoading } = usePermission('user.edit');
  const { hasPermission: canDelete, isLoading: deleteLoading } = usePermission('user.delete');

  if (editLoading || deleteLoading) {
    return <div>检查权限中...</div>;
  }

  return (
    <div>
      {canEdit && <button>编辑</button>}
      {canDelete && <button>删除</button>}
    </div>
  );
}
```

### 异步权限检查

```tsx
import { checkPermission } from '@seed-fe/react-permission';

async function handleDeleteUser(userId: string) {
  const canDelete = await checkPermission({
    code: 'user.delete',
    biz: { userId }
  });

  if (canDelete) {
    await deleteUser(userId);
  } else {
    alert('权限不足');
  }
}
```

### 多权限模式

```tsx
// 全部权限都需要满足
<Permission permission={{ code: ['edit', 'delete'], mode: 'all' }}>
  <DangerousButton />
</Permission>

// 任一权限满足即可
<Permission permission={{ code: ['view', 'edit'], mode: 'any' }}>
  <ViewEditButton />
</Permission>
```

### 临时权限服务

```tsx
// 为特定组件使用不同的权限服务
// 支持返回 boolean 或 number (0/1)
const specialService = async (configs) => {
  return configs.map(config => config.code === 'debug' && isDevelopment ? 1 : 0);
};

<Permission permission="debug" permissionService={specialService}>
  <DebugPanel />
</Permission>
```

### 权限回调

```tsx
function UserProfile() {
  const { hasPermission } = usePermission(
    'profile.edit',
    {
      onPermissionChecked: (allowed) => {
        if (allowed) {
          console.log('用户可以编辑资料');
        }
      }
    }
  );

  return (
    <div>
      {hasPermission && <EditProfileButton />}
    </div>
  );
}
```

### 缓存管理

```tsx
import { clearPermissionCache } from '@seed-fe/react-permission';

// 用户登出时清除缓存
function handleLogout() {
  clearPermissionCache();
  // 执行登出逻辑
}
```

## API

### 核心组件和 Hook

#### `<Permission>` 组件

声明式权限控制组件，用于根据用户权限控制子组件的显示与隐藏。

```tsx
<Permission
  permission={string | string[] | PermissionConfig}
  permissionService?={PermissionServiceFn}
  loading?={ReactNode}
  fallback?={ReactNode}
  onPermissionChecked?={(hasPermission: boolean) => void}
>
  {children}
</Permission>
```

#### `usePermission` Hook

命令式权限检查 Hook，提供更细粒度的权限控制。

```tsx
const { hasPermission, isLoading, error } = usePermission(
  permission: string | string[] | PermissionConfig,
  options?: UsePermissionOptions
);
```

### 配置函数

#### `configurePermission`

配置全局权限服务和选项。

```tsx
configurePermission({
  permissionService: PermissionServiceFn,
  permissionServiceOptions?: PermissionServiceOptions
});
```

#### `PermissionProvider`

权限配置提供器组件，通过 React Context 提供全局权限配置。

```tsx
<PermissionProvider
  permissionService={PermissionServiceFn}
  permissionServiceOptions?={PermissionServiceOptions}
>
  {children}
</PermissionProvider>
```

### 工具函数

#### `checkPermission`

命令式权限检查函数，返回 Promise。

```tsx
const hasPermission = await checkPermission(
  permission: PermissionConfig,
  customService?: PermissionServiceFn
);
```

#### `clearPermissionCache`

清除权限缓存。

```tsx
clearPermissionCache();
```

#### `getPermissionStats`

获取权限服务统计信息。

```tsx
const stats = getPermissionStats();
// { hasGlobalService: boolean, hasBatchFunction: boolean }
```

### 类型定义

```tsx
// 权限配置
type PermissionConfig = {
  code: string | readonly string[];
  mode?: 'all' | 'any';
  biz?: Record<string, unknown>;
};

// 权限输入类型
type PermissionInput = string | readonly string[] | PermissionConfig;

// 权限服务函数返回值类型
type PermissionResult = boolean | number;

// 权限服务函数
// 支持返回 boolean[] 或 number[] (0/1)，会自动标准化为 boolean
type PermissionServiceFn = (configs: PermissionConfig[]) => Promise<PermissionResult[]>;

// 权限服务配置
type PermissionServiceOptions = {
  batch?: {
    delay?: number;
    maxSize?: number;
  };
  cache?: {
    enable?: boolean;
    ttl?: number;
  };
};

// Permission 组件属性
interface PermissionComponentProps {
  permission: PermissionInput;
  permissionService?: PermissionServiceFn;
  loading?: ReactNode;
  fallback?: ReactNode;
  onPermissionChecked?: (hasPermission: boolean) => void;
  children: ReactNode;
}

// usePermission Hook 选项
interface UsePermissionOptions {
  permissionService?: PermissionServiceFn;
  onPermissionChecked?: (hasPermission: boolean) => void;
}
```

## 兼容性

- React 16.8+（需要 Hooks 支持）
- TypeScript 4.0+
- 现代浏览器

## 许可证

MIT © [xianghongai](https://github.com/xianghongai)