teamq/laravel-datatables

为'spatie/laravel-query-builder'包自定义筛选和排序设置

1.2.0 2024-09-18 13:18 UTC

This package is auto-updated.

Last update: 2024-09-18 16:12:13 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

这是一个用于筛选和排序的类集合,它扩展了spatie/laravel-query-builder包,同时提供了使用kirschbaum-development/eloquent-power-joins包通过连接从相关模型应用这些筛选和排序的功能。

安装

您可以通过composer安装此包

composer require teamq/laravel-datatables

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="laravel-datatable-config"

这是发布配置文件的内容

return [
    'parameters' => [
        'per_page' => 'per_page',
    ],

    'per_page' => [
        // Represents the value to be sent by the user, to obtain all records, if using the result method.
        'all' => 'all',
    ],
];

用法

分页

此包默认使用Laravel分页;然而,它允许您通过查询参数指定要获取的记录数,您甚至可以获取所有记录。

GET /books?per_page=30

建议使用result方法代替paginateget。因为result封装了两者逻辑,所以请求显示所有,下面result将使用get,但如果您想看到提供的数量,将使用paginate

use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Filters\TextFilter;

$query = QueryBuilder::for(Book::class);

$query->result();

筛选

文本比较运算符
数字比较运算符

您可以使用支持多个比较运算符的高级筛选器。可用的比较运算符位于TeamQ\Datatables\Enums\Comparators

要使用这些高级筛选器,只需将它们作为自定义筛选器调用

GET /books?filter[isbn][value]=54213&filter[isbn][operator]=5
use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Filters\TextFilter;

QueryBuilder::for(Book::class)
        ->allowedFilters([
            AllowedFilter::custom('isbn', new TextFilter()),
        ]);

如果您想通过连接使用关系处理,您必须将false作为第一个参数传递给筛选器,并传递要使用的join类型。

use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Filters\TextFilter;
use TeamQ\Datatables\Enums\JoinType;

QueryBuilder::for(Book::class)
        ->allowedFilters([
            AllowedFilter::custom('isbn', new TextFilter(false, JoinType::Inner)),
        ]);

文本筛选器

以下示例使用比较运算符5,相当于询问是否存在isbn以54213结尾的书籍

GET /books?filter[isbn][value]=54213&filter[isbn][operator]=5
select *
from `books`
where lower(`isbn`) like '%54213'
use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Filters\TextFilter;

QueryBuilder::for(Book::class)
        ->allowedFilters([
            AllowedFilter::custom('isbn', new TextFilter()),
        ]);

数字筛选器

以下示例使用比较运算符9,相当于询问是否存在id为1、5或9的书籍

对于此示例,使用了一个值数组。所有类型的运算符(文本和数字)都支持数组值。

GET /books?filter[id][value][0]=1&filter[id][value][1]=5&filter[id][value][2]=9&filter[id][operator]=9
select *
from `books`
where id in (1, 5, 9)
use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Filters\NumberFilter;

QueryBuilder::for(Book::class)
        ->allowedFilters([
            AllowedFilter::custom('id', new NumberFilter()),
        ]);

日期筛选器

以下示例使用比较运算符8,相当于询问是否存在创建时间不在2019-08-01和2019-08-10之间的书籍

对于此示例,使用了一个值数组。所有类型的运算符(文本和数字)都支持数组值。

GET /books?filter[created_at][value][0]=2019-08-01&filter[created_at][value][1]=2019-08-10&filter[id][operator]=8
select *
from `books`
where created_at not between '2019-08-01' and '2019-08-10'
use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Filters\DateFilter;

QueryBuilder::for(Book::class)
        ->allowedFilters([
            AllowedFilter::custom('created_at', new DateFilter()),
        ]);

全局筛选器

全局筛选器实现了模型及其关系的通用搜索功能。

这绝不是实体之间的全局搜索引擎!!!为此,您可以使用spatie/laravel-searchable

要使用此筛选器,您必须传递要筛选的模型字段或其关系。

GET /books?filter[search]='Luis'
select *
from `books`
where (
          exists (select *
                  from `authors`
                  where `books`.`author_id` = `authors`.`id`
                    and lower(`authors`.`name`) LIKE '%Luis%')
              or
          lower(`books`.`title`) LIKE '%Luis%'
          )
use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Filters\GlobalFilter;

QueryBuilder::for(Book::class)
        ->allowedFilters([
            AllowedFilter::custom('search', new GlobalFilter([
                'author.name',
                'title',
            ])),
        ]);

有关系筛选器

此筛选器接受两个可能的值

  • 1用于筛选“有”
  • 0用于筛选“没有”

当您想允许用户对具有关联模型/关系的记录进行筛选时,请使用此筛选器。例如,您可能希望获取所有拥有书籍的作者。

GET /books?filter[has_books]=1
select * from `authors` where exists (select * from `books` where `authors`.`id` = `books`.`author_id`)
use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Filters\HasRelationshipFilter;

QueryBuilder::for(Author::class)
        ->allowedFilters([
            AllowedFilter::custom('has_books', new HasRelationshipFilter(), 'books'),
        ]);

排序

关系排序

要按相关表的字段排序,您必须使用join,从eloquent中无法轻松完成,因此您可以使用RelationSort,此类接收join类型作为参数。

use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Sorts\RelationSort;

QueryBuilder::for(Book::class)
        ->allowedSorts([
            AllowedSort::custom('author.name', new RelationSort(JoinType::Inner)),
        ])

案例排序

如果您使用枚举或状态,其中每个枚举或状态都由一个数字表示,您可能希望按枚举或状态的名称进行排序,而不是按数字排序,那么您可以使用 CaseSort

您必须传递一个数组 [$key => $value],该数组将被用于生成排序。

作为第二个参数,您可以指定要使用的 Join 类型,如果排序是根据相关模型的字段。默认情况下,它是 Inner Join

use Spatie\QueryBuilder\AllowedFilter;
use TeamQ\Datatables\QueryBuilder;
use TeamQ\Datatables\Sorts\CaseSort;

QueryBuilder::for(Book::class)
        ->allowedSorts([
            AllowedSort::custom('state', new CaseSort([
                1 => 'Active',
                2 => 'Rejected',
                3 => 'Deleted',
                4 => 'Completed',
            ])),
        ]);

测试

可以使用 docker-compose 运行

docker-compose exec app composer test

变更日志

有关最近更改的更多信息,请参阅 变更日志

安全漏洞

请查看我们的安全策略以了解如何报告安全漏洞

致谢

许可证

MIT许可证(MIT)。更多信息请参阅 许可证文件