Skip to content

CatchModel 模型介绍

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

重要提示

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

CatchModel 核心类

CatchModelCatchAdmin 框架的核心模型基类,基于 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_atupdated_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',
];

为什么 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 的核心数据查询方法,集成了多种高级数据检索功能:

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

列表查询自定义扩展

通过 CatchModelsetBeforeGetList 方法可以在数据查询执行前添加自定义逻辑:

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
public function updateBy($id, array $data): mixed

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

批量更新

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

参数说明:

参数类型说明
$fieldstring更新条件字段(如 id
$conditionarray条件值数组(如 [1, 2, 3]
$dataarray更新数据键值对

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();

使用条件

使用该查询需要数据表包含 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() {
    // 事务内的操作
});

CatchModel 事务处理便捷性

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