# @lark-apaas/client-toolkit

## 项目架构设计

### apis 目录

* 导出所有对外暴露的 API 和组件，并通过 npm exports 来控制
* 其他目录作为 internal 实现，不对外暴露

### auth 目录

* 包含与权限相关的 API 和组件


### 开发组件 - 使用 CanRole 组件 (推荐)

```tsx
import { CanRole } from '@lark-apaas/client-toolkit/auth';

function Home() {
  return (
    <div>
      <CanRole roles={['role_admin']}>
        <div>管理员按钮</div>
      </CanRole>
      <CanRole roles={['role_admin', 'role_editor']}>
        <div>编辑按钮</div>
      </CanRole>
    </div>
  );
}
```

### 开发组件 - 使用 AbilityContext 处理复杂场景

```tsx
import { useContext } from 'react';
import { AbilityContext, ROLE_SUBJECT } from '@lark-apaas/client-toolkit/auth';

function Home() {
  const ability = useContext(AbilityContext);
  return (
    <div>
      {ability.can('role_admin', ROLE_SUBJECT) || ability.can('role_editor', ROLE_SUBJECT) ? (
        <div>可见的仪表盘</div>
      ) : null}
    </div>
  );
}
```

### 开发组件 - 进阶示例

### 菜单按权限过滤

```tsx
import { useContext } from 'react';
import { AbilityContext, ROLE_SUBJECT } from '@lark-apaas/client-toolkit/auth';

const menus = [
  { name: 'Dashboard', path: '/dashboard', p: { action: 'role_admin', subject: ROLE_SUBJECT } },
  { name: 'Users', path: '/users', p: { action: 'role_editor', subject: ROLE_SUBJECT } },
  { name: 'Settings', path: '/settings', p: { action: 'role_admin', subject: ROLE_SUBJECT } },
];

function Nav() {
  const ability = useContext(AbilityContext);
  return (
    <nav>
      {menus.map(m => ability.can(m.p.action, m.p.subject) && (
        <a key={m.path} href={m.path}>{m.name}</a>
      ))}
    </nav>
  );
} 
```