Skip to content

Repository ​

Repository 是唯一与 Model 交互的层。所有查询必须从 $this->query() 起手:受控表($dataScoped = true)会在这里挂上数据权限全局作用域。绕开 query() 等于绕开数据权限。

query() 起手 ​

php
protected function query(): Builder
{
    $query = $this->model->newQuery();
    if ($this->dataScoped) {
        // 非「全部」快照时挂 DataScopeScope
        // …
    }

    return $query;
}

public function find(int|string $id): ?array
{
    return $this->query()->where($this->model->getQualifiedKeyName(), $id)->first()?->toArray();
}

基类在 core\base\Repository。子类声明 $dataScoped / $ownerColumn / $deptColumn 即受控;create() 在受控表上可自动填 $creatorColumn(默认 created_by)。

看全表:DataScope::bypass() ​

认证查找、全局查重、删除保护等必须看见范围外的行时,用 DataScope::bypass(),并在方法注释写明理由:

php
/** 用户名是否已占用。含软删行:唯一索引对软删行同样生效。 */
public function existsUsername(string $username, int $excludeId = 0): bool
{
    return DataScope::bypass(function () use ($username, $excludeId): bool {
        $query = $this->query()
            ->withoutGlobalScope(SoftDeletingScope::class)
            ->where($this->qualify('username'), $username);
        if ($excludeId > 0) {
            $query->where($this->qualify('id'), '<>', $excludeId);
        }

        return $query->exists();
    });
}

上例来自 app\repository\system\AdminRepository(类注释也写明:认证查找、查重与部门删除保护经 bypass 看全表)。

分页形状 ​

getList() 返回:

php
[
    'list' => [/* … */],
    'pagination' => [
        'current_page' => 1,
        'per_page'     => 15,
        'total'        => 100,
        'last_page'    => 7,
    ],
]

每页上限 Repository::MAX_PAGE_SIZE(100)。

基于 MIT 许可发布