{"id":33991105,"url":"https://github.com/mitoop/laravel-query-builder","last_synced_at":"2025-12-13T06:38:54.515Z","repository":{"id":291881131,"uuid":"878815788","full_name":"mitoop/laravel-query-builder","owner":"mitoop","description":"Laravel Query Builder 是一个基于接口设计、具备高扩展性的渐进式搜索构建包，旨在让 Laravel 中的复杂搜索更简单、更清晰、更优雅。","archived":false,"fork":false,"pushed_at":"2025-09-25T08:56:29.000Z","size":165,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-26T04:34:29.377Z","etag":null,"topics":["laravel","query"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mitoop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-26T07:21:24.000Z","updated_at":"2025-09-25T08:56:03.000Z","dependencies_parsed_at":"2025-05-07T02:41:46.040Z","dependency_job_id":"ba62249b-c97d-4c8e-94a6-33886b855ae0","html_url":"https://github.com/mitoop/laravel-query-builder","commit_stats":null,"previous_names":["mitoop/laravel-query-builder"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/mitoop/laravel-query-builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitoop%2Flaravel-query-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitoop%2Flaravel-query-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitoop%2Flaravel-query-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitoop%2Flaravel-query-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitoop","download_url":"https://codeload.github.com/mitoop/laravel-query-builder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitoop%2Flaravel-query-builder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27701745,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-13T02:00:09.769Z","response_time":147,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","query"],"created_at":"2025-12-13T06:38:53.927Z","updated_at":"2025-12-13T06:38:54.506Z","avatar_url":"https://github.com/mitoop.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel Query Builder\n\n**Laravel Query Builder** 是一个基于接口设计、具备高扩展性的渐进式搜索构建包，旨在让 Laravel 中的复杂搜索变得**更简单、更清晰、更优雅**。\n\n它将搜索逻辑从控制器中彻底解耦，使列表搜索功能的开发更加集中、可维护，同时支持高度复用和灵活扩展。\n\n本包的设计灵感来源于 [zhuzhichao/laravel-advanced-search](https://github.com/matrix-lab/laravel-advanced-search) 和 [spatie/laravel-query-builder](https://github.com/spatie/laravel-query-builder)，并结合实际业务需求进行了增强与重构。\n\n---\n\n## 特性\n\n* **DSL 搜索规则**：集中定义搜索逻辑，支持声明式、结构化、可复用的规则。\n* **支持排序与分页**：可自定义排序字段，兼容 `paginate()`、`get()` 等链式调用。\n* **值处理器(ValueResolver)**：统一处理输入值转换，避免重复闭包。\n* **字段类型灵活**：支持 JSON 字段、关联字段、表别名字段。\n* **高级扩展**：支持原生 SQL、闭包、自定义操作符、模型 Scope。\n* **接口驱动**：几乎所有功能可通过自定义类替换，实现高度扩展。\n\n---\n\n## 环境需求\n\n* PHP \u003e= 8.2\n* Laravel ^11.0 | ^12.0\n\n---\n\n## 安装\n\n```bash\ncomposer require mitoop/laravel-query-builder\n```\n\n---\n\n## 快速上手\n\n### 创建 Filter 类\n\nFilter 类用于集中定义搜索逻辑，可通过 Artisan 快速生成：\n\n```bash\nphp artisan make:filter UserFilter\n```\n\n```php\nclass UserFilter extends AbstractFilter\n{\n    protected array $allowedSorts = ['id'];\n\n    protected function rules(): array\n    {\n        return [];\n    }\n}\n```\n\n调用示例：\n\n```php\n$users = User::filter(UserFilter::class)-\u003epaginate();\n```\n\n返回的是原生 Eloquent 查询构建器，仍支持链式调用 `with()`、`paginate()`、`get()` 等。\n\n---\n\n## DSL 搜索规则\n\n### 传统写法（控制器硬编码）\n\n```php\nif ($request-\u003efilled('name')) {\n    $query-\u003ewhere('name', $request-\u003einput('name'));\n}\nif ($request-\u003efilled('email')) {\n    $query-\u003ewhere('email', 'like', '%'.$request-\u003einput('email').'%');\n}\n```\n\n### 使用 DSL（集中在 Filter 中）\n\n```php\nprotected function rules(): array\n{\n    return [\n        'name',\n        'email|like' =\u003e new Like,\n    ];\n}\n```\n\n### DSL 优势\n\n* **集中管理**：所有规则在 `rules()` 中定义，控制器无需关心细节。\n* **结构化**：清晰、易于阅读和维护。\n* **高复用**：支持自定义操作符和值处理器，可在多个 Filter 中复用。\n* **可扩展**：轻松支持 JSON、关联字段、模型 Scope 等复杂查询。\n\n---\n\n### 规则格式\n\n```text\n[前端字段名]:[数据库字段]|[操作符]\n```\n\n* 冒号用于前端字段与数据库字段映射（可选）\n* 竖线用于指定操作符（可选）\n* 支持索引数组、关联数组混合定义\n\n示例：\n\n```php\nprotected function rules(): array\n{\n    return [\n        'name', // 默认 eq\n        'email|like' =\u003e $this-\u003evalue('email', fn($email)=\u003e \"%{$email}%\"),\n        'created_at|between' =\u003e new DateRange,\n        'nickname:profile-\u003enickname|like' =\u003e new Like,\n        'position$name|like' =\u003e new Like,\n    ];\n}\n```\n\n---\n\n### 支持的操作符\n\n* 基础：`eq`, `ne`, `gt`, `lt`, `gte`, `lte`, `like`, `in`, `not_in`, `between`, `is_null`, `not_null`\n* JSON：`json_contains`\n* 自定义操作符：在 `AppServiceProvider` 注册\n\n```php\napp(OperatorFactoryInterface::class)-\u003eregister('new_operator', fn($app) =\u003e new NewOperator);\n```\n\n---\n\n### 值处理器 ValueResolver\n\n用于统一处理输入值，例如模糊搜索或日期范围：\n\n```php\nclass Like implements ValueResolver\n{\n    public function __construct(protected string $prefix = '%', protected string $suffix = '%') {}\n\n    public function resolve($value): string\n    {\n        return $this-\u003eprefix.$value.$this-\u003esuffix;\n    }\n}\n\nclass DateRange implements ValueResolver\n{\n    public function resolve($value): ?array\n    {\n        if (! is_array($value) || count($value) !== 2) return null;\n\n        try {\n            [$start, $end] = $value;\n            $start = Carbon::parse($start)-\u003estartOfDay();\n            $end = Carbon::parse($end)-\u003eendOfDay();\n        } catch (Throwable) {\n            return null;\n        }\n\n        return [$start, $end];\n    }\n}\n```\n\n使用示例：\n\n```php\nprotected function rules(): array\n{\n    return [\n        'email|like' =\u003e new Like,\n        'created_at|between' =\u003e new DateRange,\n    ];\n}\n```\n\n\u003e 如果前端传入值为 `null` 或空数组，该规则会自动跳过，避免无效查询。\n\n---\n\n### 高级规则支持\n\n* **原生 SQL**：`DB::raw(...)`\n* **闭包查询**：\n\n```php\nfunction (Builder $builder) {\n    $builder-\u003ewhere('is_verified', true);\n}\n```\n\n* **模型 Scope**：支持 `scopeXxx()` 或 `#[Scope]` 注解\n* **关键词搜索**：\n\n```php\n$this-\u003ewhenValue('keyword', function(Builder $builder, $keyword) {\n    $builder-\u003ewhereAny(['name', 'email'], 'like', \"%{$keyword}%\");\n});\n```\n\n---\n\n### 排序：sorts 方法\n\n默认通过请求参数 `sorts` 提取排序条件，例如：\n\n```\nsorts=-id,name\n```\n\n* 字段前加 `-` 表示降序，其他为升序\n* 可通过 `$allowedSorts` 限制允许排序字段\n\n```php\nprotected array $allowedSorts = ['id', 'name', 'created_at'];\n```\n\n* 自定义请求参数：\n\n```php\nSortResolver::sortFieldUsing('order_by');\n```\n\n* 完全自定义排序：\n\n```php\nprotected function sorts(): array\n{\n    return [\n        'id' =\u003e 'desc',\n        'created_at asc',\n    ];\n}\n```\n\n---\n\n### 生命周期钩子\n\n* **booting()**：执行构建逻辑前调用，适合设置默认参数\n\n```php\npublic function booting(): void\n{\n    $this-\u003edata['status'] ??= 'active';\n}\n```\n\n* **boot()**：构建逻辑正式开始前调用，适合动态注册过滤器或修改行为\n\n```php\npublic function boot(): void\n{\n    if (method_exists($this, 'with')) {\n        $this-\u003ebuilder-\u003ewith($this-\u003ewith());\n    }\n}\n```\n\n---\n\n### 完整示例：UserFilter\n\n```php\nuse Mitoop\\LaravelQueryBuilder\\Filters\\AbstractFilter;\nuse Mitoop\\LaravelQueryBuilder\\Operators\\Like;\n\nclass UserFilter extends AbstractFilter\n{\n    protected array $allowedSorts = ['id', 'created_at'];\n\n    protected function rules(): array\n    {\n        return [\n            'id',\n            'name|like'  =\u003e new Like,\n            'email|like' =\u003e new Like,\n            'status|in',\n            'created_from:created_at|gte',\n            'created_to:created_at|lte',\n            'created_at|between' =\u003e new DateRange,\n            'nickname:profile-\u003enickname|like' =\u003e new Like,\n            'tag:profile-\u003etags|json_contains',\n            'position$name|like' =\u003e new Like,\n            'u.name',\n            new Scope('active'),\n            $this-\u003ewhenValue('keyword', function (Builder $builder, $keyword) {\n                $builder-\u003ewhereAny(['name', 'email'], 'like', \"%{$keyword}%\");\n            }),\n            'keyword|like_any' =\u003e new LikeAny(['name', 'email']),\n            DB::raw('users.score \u003e 100'),\n            function (Builder $builder) {\n                $builder-\u003ewhere('is_verified', true);\n            },\n        ];\n    }\n}\n```\n\n控制器使用：\n\n```php\n$users = User::filter(UserFilter::class)-\u003epaginate();\n```\n\n---\n\n## 贡献\n\n有什么新的想法和建议，欢迎提交 [issue](https://github.com/mitoop/laravel-query-builder/issues) 或 [Pull Requests](https://github.com/mitoop/laravel-query-builder/pulls)。\n\n---\n\n## 协议\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitoop%2Flaravel-query-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitoop%2Flaravel-query-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitoop%2Flaravel-query-builder/lists"}