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)。