---
url: /docs/5.0/server/model.md
---
# CatchModel 模型介绍

在后台项目开发中，大部分业务逻辑都与数据模型操作和数据库交互相关。为了简化开发流程并提供统一的数据操作接口，`CatchAdmin` 框架提供了功能强大的模型基类 `CatchModel`。所有业务模型都继承自 `CatchModel`，从而获得丰富的数据操作功能和内置特性。

::: tip 重要提示
建议仔细阅读本文档，全面掌握 CatchModel 的数据操作功能将显著提升开发效率
:::

## CatchModel 核心类

`CatchModel` 是 `CatchAdmin` 框架的核心模型基类，基于 Laravel Eloquent ORM 进行扩展，继承自 Laravel 的 `Model` 类，并集成了多个高级功能特性：

```php
abstract class CatchModel extends Model
{
    use BaseOperate, Trans, SoftDeletes, ScopeTrait;

    /**
     * 使用 Unix 时间戳格式
     * @var string
     */
    protected $dateFormat = 'U';

    /**
     * 默认分页数量
     */
    protected $perPage = 10;

    /**
     * 关闭 Laravel 自动时间戳管理
     * @var bool
     */
    public $timestamps = false;

    /**
     * 默认类型转换配置
     * @var array
     */
    protected array $defaultCasts = [
        'created_at' => 'datetime:Y-m-d H:i:s',
        'updated_at' => 'datetime:Y-m-d H:i:s',
    ];

    /**
     * 默认隐藏字段
     * @var array
     */
    protected array $defaultHidden = ['deleted_at'];

    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        $this->init();
    }

    /**
     * 初始化模型配置
     */
    protected function init()
    {
        $this->makeHidden($this->defaultHidden);
        $this->mergeCasts($this->defaultCasts);
    }

    /**
     * 自定义软删除启动方法
     */
    public static function bootSoftDeletes(): void
    {
        static::addGlobalScope(new SoftDelete());
    }

    /**
     * 覆盖恢复方法，使用自定义的软删除逻辑
     */
    public function restore(): bool
    {
        if ($this->fireModelEvent('restoring') === false) {
            return false;
        }

        $this->{$this->getDeletedAtColumn()} = 0;
        $this->exists = true;
        $result = $this->save();
        $this->fireModelEvent('restored', false);

        return $result;
    }
}
```

### 时间戳处理机制

`CatchAdmin` 框架中所有数据表的 `created_at` 和 `updated_at` 时间字段都采用 Unix 时间戳（`int` 类型）进行存储，这种设计提升了数据库查询效率。为了在 API 返回给前端时提供用户友好的日期格式，框架内置了数据类型转换配置：

```php
protected array $defaultCasts = [
    'created_at' => 'datetime:Y-m-d H:i:s',
    'updated_at' => 'datetime:Y-m-d H:i:s',
];
```

::: info 为什么 CatchModel 使用 `defaultCasts` 而不是 `casts`？
由于所有业务模型都继承自 `CatchModel`，而日期类型转换是每个数据模型都需要的基础功能。如果直接使用 Laravel 的 `casts` 属性，在子类中定义自己的 `casts` 时可能会覆盖基类的配置。`CatchModel` 使用 `defaultCasts` 可以确保基础转换不被意外覆盖。`defaultHidden` 属性也采用了同样的设计理念。
:::

### 软删除机制

`CatchModel` 采用了自定义的软删除机制，与 Laravel Eloquent 默认的 `null` 值不同，使用 `0` 数值作为数据未删除状态。这种设计更符合数据库索引优化的需求，能够提升大数据量场景下的查询性能。

::: tip
`CatchModel` 的软删除使用方式与 Laravel 原生 SoftDelete 功能保持一致，无需额外配置。
:::

```php
class SoftDelete extends SoftDeletingScope
{
    public function apply(Builder $builder, Model $model)
    {
        $builder->where($model->getQualifiedDeletedAtColumn(), '=', 0);
    }
}
```

## 模型属性配置

`CatchModel` 提供了丰富的模型属性配置选项，用于精细控制数据模型的 CRUD 操作行为、查询逻辑和数据处理特性：

### 数据结构相关属性

```php
// 树形结构父级字段，建议使用默认值
protected string $parentIdColumn = 'parent_id';

// 排序字段配置
protected string $sortField = 'sort';
protected bool $sortDesc = true;  // 默认倒序

// 列表数据返回格式
protected bool $asTree = false;      // 是否以树形结构返回
protected bool $isPaginate = true;   // 是否启用分页
```

### 查询和表单相关属性

```php
// 列表查询默认字段
protected array $fields = [];

// 表单提交字段配置
protected array $form = [];

// 关联关系处理（如用户与角色的多对多关系）
protected array $formRelations = [];
```

### 权限控制属性

```php
// 数据权限控制
protected bool $dataRange = false;

// 字段权限控制
protected bool $columnAccess = false;

// 创建人自动填充
protected bool $isFillCreatorId = true;
```

### 数据处理属性

```php
// 空值自动转换
protected bool $autoNull2EmptyString = true;

// 动态排序参数
protected string $dynamicQuerySortField = 'sortField';
protected string $dynamicQuerySortOrder = 'order';
```

## 模型方法详解

### 数据查询方法

#### 获取列表数据

```php
public function getList(): mixed
```

该方法是 `CatchModel` 的核心数据查询方法，集成了多种高级数据检索功能：

* 字段权限过滤
* 创建人信息关联
* 快速搜索支持
* 数据权限控制
* 自定义排序规则
* 动态排序支持
* 分页/树形结构返回

#### 列表查询自定义扩展

通过 `CatchModel` 的 `setBeforeGetList` 方法可以在数据查询执行前添加自定义逻辑：

::: code-group

```php [排序示例]
// 添加自定义排序规则
$model->setBeforeGetList(function ($query) {
    return $query->orderByDesc('sort');
})->getList();
```

```php [联表查询]
// 添加表连接
$model->setBeforeGetList(function ($query) {
    return $query->join('some_table', 'table.id', '=', 'some_table.table_id');
})->getList();
```

```php [关联加载]
// 添加关联关系加载
$model->setBeforeGetList(function ($query) {
    return $query->with('someRelations');
})->getList();
```

:::

### 数据保存方法

#### 保存数据（单条记录）

```php
public function storeBy(array $data): mixed
```

`CatchModel` 的数据保存方法，用于处理单条数据记录的数据库存储，支持 Laravel 关联关系的智能处理。操作成功返回主键 ID，失败返回 `false`。

#### 创建数据（批量操作）

```php
public function createBy(array $data): mixed
```

::: tip
`createBy` 方法适用于循环批量创建数据的业务场景，而 `storeBy` 更适合单条数据 CRUD 操作。它会每次创建模型实例，并且触发模型事件
:::

示例如下，每次都是新的模型实例，每次创建都会触发模型事件

```php
foreach($data as $item) {
    $model->createBy($item);
}
```

#### 更新数据

```php
public function updateBy($id, array $data): mixed
```

`CatchModel` 的数据更新方法，根据主键 ID 更新数据记录，支持 Laravel 关联关系的同步更新。

#### 批量更新

```php
public function batchUpdate(string $field, array $condition, array $data): bool
```

**参数说明：**

| 参数         | 类型     | 说明                         |
| ------------ | -------- | ---------------------------- |
| `$field`     | `string` | 更新条件字段（如 `id`）      |
| `$condition` | `array`  | 条件值数组（如 `[1, 2, 3]`） |
| `$data`      | `array`  | 更新数据键值对               |

::: warning CatchModel 批量更新注意事项

* 该方法不会触发 Laravel 模型事件
* 数据条件数量必须与更新数据数量一致
  :::

**使用示例：**

```php
$model = new SomeModel();
$model->batchUpdate('id', [1, 2, 3], [
    'name' => ['小明', '小隋', '小书'],
    'age' => [12, 13, 14]
]);
```

### 数据查询方法

#### 单条数据查询

```php
public function firstBy($value, $field = null, array $columns = ['*']): ?Model
```

`CatchModel` 的单条数据查询方法，根据指定数据库字段查询单条记录，默认使用主键 `id` 字段。支持数据权限和字段权限过滤。

### 数据删除方法

#### 删除数据

```php
public function deleteBy($id, bool $force = false, bool $softForce = false): ?bool
```

`CatchModel` 的数据删除方法，根据主键 ID 删除数据记录，默认采用安全的软删除机制。当 `$force` 参数设置为 `true` 时进行永久物理删除。

#### 删除软删除数据

```php
public function deleteTrash($id): mixed
```

彻底删除已被 `CatchModel` 软删除标记的数据记录，执行永久性数据库删除操作。

#### 批量删除

```php
public function deletesBy(array|string $ids, bool $force = false, ?Closure $callback = null): bool
```

`CatchModel` 的批量删除方法，支持同时处理正常数据和软删除数据的批量删除操作。`$ids` 参数支持灵活的数据格式，可以是 PHP 数组或逗号分隔的字符串（如 `"1,2,3,4,5"`）。

`$callback` 参数可用于处理删除后的回调逻辑：

```php
$ids = [1, 2, 3];
$this->deletesBy($ids, false, function($ids) {
    // $ids [1, 2, 3]
    // 这里处理删除后的逻辑
});
```

#### 恢复数据

```php
public function restoreBy(array|string $ids): true
```

配合 CatchAdmin 后台管理系统的数据回收站功能，用于恢复 `CatchModel` 软删除的数据记录。

### 辅助功能方法

#### 排序功能

通过设置 `sortField` 属性可以指定默认排序字段：

```php
protected string $sortField = 'sort';
```

默认使用倒序排序，如需正序排序可设置：

```php
protected bool $sortDesc = false;
```

#### 状态切换

```php
public function toggleBy($id, string $field = 'status'): bool
```

通过主键 ID 进行状态字段的切换，默认操作 `status` 字段。

#### 处理树状数据的子级更新

```php
public function updateChildren(mixed $parentId, string $field, mixed $value): void
```

递归更新树形结构中指定父级下所有子级的字段值。

#### 字段别名处理

```php
public function aliasField(string|array $fields): string|array
```

为字段添加表名前缀，避免联表查询时的字段冲突。

#### 创建人相关方法

```php
// 设置创建人 ID
public function setCreatorId()

// 获取创建人信息（Scope 查询）
public function scopeCreator()
```

使用创建人查询 Scope：

```php
Model::select('*')->creator()->get();
```

::: info 使用条件
使用该查询需要数据表包含 `creator_id` 字段，否则无效果。
:::

#### 模糊查询

```php
public function whereLike($field, $value)
```

提供便捷的模糊查询方法。

#### 快速搜索

```php
public function quickSearch(array $params = [])
```

该方法通过模型的 `searchable` 属性配合请求参数进行动态搜索：

```php
protected array $searchable = [
    'status' => '=',
    'nickname' => 'like'
];
```

在 `CatchModel` 中配置 `searchable` 属性后，框架会自动生成相应的数据库查询条件：

```php
Model::select('*')
    ->where('status', $request->get('status'))
    ->whereLike('nickname', $request->get('nickname'))
    ->get();
```

`CatchModel` 的快速搜索支持数据库别名字段，特别适用于多表 `JOIN` 联查询场景。例如当 A 和 B 两张表都包含 `status` 字段时，可以精确指定查询目标

```php
// 在 CatchModel 中可以指定使用 A 表的 status 字段进行精确查询
protected array $searchable = [
    'A.status' => '=',

];
```

### CatchModel 数据库事务处理

`CatchModel` 在模型类中内置集成了 Laravel 数据库事务处理方法，无需额外引入 `DB` Facade：

```php
// 开启事务
$this->beginTransaction();

// 提交事务
$this->commit();

// 回滚事务
$this->rollback();

// 事务闭包
$this->transaction(function() {
    // 事务内的操作
});
```

::: tip CatchModel 事务处理便捷性
相比传统的 `DB::beginTransaction()` 方式，`CatchModel` 直接在模型中调用事务方法更加便捷，提升了 PHP 开发效率。
:::
