---
url: /docs/5.0/server/data_permission.md
---
# CatchAdmin 数据权限

> 基于角色的细粒度数据访问控制系统

## 数据权限介绍

数据权限是企业级权限管理的重要组成部分，用于控制用户只能访问和操作特定范围内的数据。由于并非所有项目都需要这种细粒度的数据控制，CatchAdmin 默认不启用数据权限功能。

**应用场景**：

* **企业多部门**：不同部门只能访问自己部门的数据
* **层级管理**：上级可以查看下级的数据，但下级不能查看上级数据
* **个人数据隔离**：用户只能查看自己创建的数据

CatchAdmin 的数据权限与角色系统紧密集成，通过角色配置实现灵活的数据访问控制：
![pSlzXdO.png](https://s1.ax1x.com/2023/01/16/pSlzXdO.png)

## 数据权限类型

CatchAdmin 提供五种数据权限级别，覆盖不同的业务需求：

### 1. 全部数据权限

* **权限范围**：可以访问系统中的所有数据
* **适用角色**：系统管理员、超级用户
* **使用场景**：数据统计分析、系统维护

### 2. 自定义数据权限

* **权限范围**：可以自定义指定特定的数据范围
* **适用角色**：特殊权限的管理角色
* **使用场景**：跨部门项目负责人、特定业务管理员

### 3. 部门数据权限

* **权限范围**：只能访问本部门的数据
* **适用角色**：部门普通成员
* **使用场景**：销售部门只看销售数据、技术部门只看技术数据

### 4. 部门及以下数据权限

* **权限范围**：可以访问本部门及其下级部门的数据
* **适用角色**：部门主管、中层管理者
* **使用场景**：部门经理管理整个部门体系的数据

### 5. 仅本人数据权限

* **权限范围**：只能访问自己创建的数据
* **适用角色**：普通员工、实习生
* **使用场景**：个人工作记录、私人数据管理

## 使用约定

### 数据表要求

要使用数据权限功能，数据表必须满足以下结构要求：

1. **creator\_id 字段**：必需字段，用于标识数据的创建者

   ```sql
   `creator_id` int(11) NOT NULL DEFAULT 0 COMMENT '创建者ID'
   ```

2. **部门关联**：如果使用部门相关权限，用户表需要包含部门信息
   ```sql
   `dept_id` int(11) NOT NULL DEFAULT 0 COMMENT '所属部门ID'
   ```

### 字段说明

* **creator\_id**：CatchAdmin 统一使用此字段标识数据归属
* **自动填充**：CatchModel 会自动填充 creator\_id 字段
* **权限过滤**：系统根据此字段进行数据权限过滤

## 配置步骤

### 前置条件

使用数据权限前，请确保满足以下条件：

1. **权限模块已启用**：数据权限依赖权限管理模块
2. **角色数据权限配置**：为角色设置合适的数据权限范围
3. **用户部门设置**：使用部门权限时，用户必须设置所属部门
4. **数据表结构**：确保相关表包含 `creator_id` 字段

### 配置流程

1. **角色配置**：在角色管理中设置数据权限类型
2. **用户分配**：为用户分配对应的角色
3. **部门设置**：为用户设置所属部门（如需要）
4. **模型配置**：在相关模型中启用数据权限

## 代码实现

### 模型中启用数据权限

在需要数据权限控制的模型中引入 `DataRange` trait：

```php title="modules/Permissions/Models/Traits/DataRange.php"
use Modules\Permissions\Models\Traits\DataRange;

class UserModel extends CatchModel
{
    use DataRange;

    // 其他模型代码...
}
```

### 自动权限过滤

引入 `DataRange` trait 后，模型的列表查询会自动应用数据权限过滤：

```php
// 自动应用当前用户的数据权限
$users = UserModel::getList();
```

### 手动权限查询

如需在特定查询中单独使用数据权限，可以使用 `dataRange` 作用域：

```php
// 手动应用数据权限
$filteredData = UserModel::select('*')
    ->dataRange()
    ->where('status', 1)
    ->get();
```

### 权限检查方法

```php
// 检查当前用户对特定数据的访问权限
if ($model->hasDataPermission($dataId)) {
    // 有权限访问
    return $model->find($dataId);
} else {
    // 无权限访问
    throw new PermissionDenied('无权限访问此数据');
}
```

## 使用注意事项

1. **性能考虑**：数据权限会在查询中添加额外的 WHERE 条件，大数据量时建议添加相关索引
2. **权限调试**：开发时可通过日志查看生成的 SQL 语句，确认权限过滤是否正确
3. **角色变更**：用户角色变更后，数据权限会立即生效，无需重新登录
4. **数据一致性**：确保所有相关表都正确设置了 `creator_id` 字段
