plokko/resource-query

该软件包最新版本(0.2.5)没有可用的许可信息。

0.2.5 2024-06-26 10:38 UTC

This package is auto-updated.

Last update: 2024-08-26 14:18:41 UTC


README

使用Ajax功能的Laravel查询的自动过滤和排序。

该软件包的范围

此软件包添加了帮助自动化创建后端定义的用户查询(Ajax)的类,具有高级功能,如过滤、排序、分页、资源铸造和智能铸造。查询将基于预定义的Eloquent查询,用户可以通过应用预定义的查询参数来自定义查询。所有查询参数都易于在后台定义和自定义,从而可以严格控制用户可以看到或执行的内容。

安装

使用composer安装它 composer require plokko/resource-query

初始化

要使用此类,您必须扩展基本 ResourceQuery 类或使用构建器。如果您打算重用相同的设置,则扩展 ResourceQuery 类是首选,如果您打算一次性使用它,则构建器方法更快。

扩展ResourceQuery

创建一个新的类,它扩展 plokko\ResourceQuery\ResourceQuery 并实现返回基础查询的 getQuery() 函数

use plokko\ResourceQuery\ResourceQuery;

class ExampleResourceQuery extends ResourceQuery{

    protected function getQuery():Builder {
        // Return the base query
        return MyModel::select('id','a','b')
                ->where('fixed_condition',1);
    }
    
}

使用构建器

或通过定义 ResourceQueryBuilder

use plokko\ResourceQuery\ResourceQueryBuilder;

$query = MyModel::select('id','etc');
//Add the base query
$resource =  new ResourceQueryBuilder($query);

示例用法

class MyController extends Controller {
    //...
    public function example1(Request $request){
        $resource = new ExampleResourceQuery();
        if($request->ajax()){
            return $resource;
        }
        view('example',compact('resource'));
    }
    public function example2(Request $request){
        $query = MyModel::select('id','etc');
        $resource =  new ResourceQueryBuilder($query);

        if($request->ajax()){
            return $resource;
        }
        view('example',compact('resource'));
    }
    //...
}

添加过滤器

过滤器由一个过滤器名称(与过滤器相关联的请求查询参数)、一个用于解析过滤器的条件以及一个(可选的)字段名称组成,用于指定要应用过滤器的表字段。

条件可以是基本查询条件(如 =!=<>likein 等),也可以是简写助手如 like%%like%like%,它们将在输入的前后或两端添加 "%" 字符,或者是一个Callable函数,它将解析过滤器。Callable过滤器将传递3个参数:0. \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder 查询 - 在其中应用过滤器的查询

  1. mixed $value - 被过滤的值
  2. FilterCondition $condition - 当前条件,用于检索条件或字段名称等。

您可以通过多种方式添加过滤器

// With the add function (default)
$resource->filters->add(<FILTER_NAME:string>,[<CONDITION:string|callable>],[<FIELD_NAME:string>]);
// Called as a parameter
$resource->filters-><FILTER_NAME>;
// Accessed as an array
$resource->filters['<FILTER_NAME>'];
// Called as a function
$resource->filters-><FILTER_NAME>([<CONDITION:string|callable>],[<FIELD_NAME:string>]);

您还可以使用 conditionfield 函数定义或修改过滤器条件或字段名称,例如

$resource->filters->add('filter1')->condition('=')->field('fieldA');
$resource->filters->filter2->condition('like')->field('fieldB');

您可以使用以下方式删除过滤器

$resource->filters->remove('<FILTER_NAME>');

或使用unset函数

unset($resource->filters['<FILTER_NAME>']);

如果您想删除所有过滤器,请使用 php $resource->removeFilters();

过滤器定义

过滤器可以在类初始化期间添加(如果扩展ResourceQuery)

class MyClassResource extends ResourceQuery{
    //...
    function __construct() {
        //Remember to call parent constructor for inizialization
        parent::__construct();
        // Adding filters
        $this->filter('filter1','=','fieldA');
        $this->filter('filter2','like','fieldB');
        //...
    }
    //...
}

或通过直接调用资源

$query = MyModel::select('id','etc');
$resource =  new ResourceQueryBuilder($query);
// Note: this works also with already defined classes by adding or replacing existing filters
// Ex. replace lines above with: $resource = new ExampleResourceQuery();
$resource->filters->add('filter1','=','fieldA');
$resource->filters->add('filter2','like','fieldB');

过滤器根名称

如果您想将所有过滤器封装在一个数组中(例如:“url?filter[filter-name]=value”),您可以使用 setFiltersRoot 定义它

$resource->setFiltersRoot('filter');//<-- 'filter' will be used as the root query parameter 

或在类定义中设置 $filtersRoot

class ExampleResourceQuery extends ResourceQuery{
    protected $filtersRoot = 'filter';
    //...
}

其他过滤器规则

默认过滤器值

如果您想在字段不存在时应用默认值,请使用 defaultValue 函数

$resource->filters->add('filter1','=','fieldA')->defaultValue('1234');//If filter "filter1" is not set it will be applied with value "123"

值格式化

如果您想在应用过滤器之前格式化过滤器值(例如,转义字符、大写等),请使用 formatValue 函数添加Callable函数。原始过滤器值将作为参数传递,并使用返回值作为新的过滤器值。

示例

$resource->filters->add('filter1','=','fieldA')->formatValue(function($value){ return trim($value); });

仅当存在另一个过滤器时才应用

如果您只想在有其他过滤器存在的情况下应用过滤器,可以使用applyIfPresent函数。

$resource->filters->add('filter1','=','fieldA');
$resource->filters->add('filter2','like','fieldB');
// If fitler1 or filter2 are empty fitler3 will be ignored
$resource->filters->add('filter3','=','fieldC')->applyIfPresent('filter1','filter2');

只在另一个过滤器不存在时应用。

如果您只想在有其他过滤器不存在的情况下应用过滤器,可以使用applyIfNotPresent函数。

$resource->filters->add('filter1','=','fieldA');
$resource->filters->add('filter2','like','fieldB');
// If fitler1 or filter2 are not empty fitler3 will be ignored
$resource->filters->add('filter3','=','fieldC')->applyIfNotPresent('filter1','filter2');

排序

与过滤类似,您可以通过多种方式声明排序查询参数,使用OrderBy参数。

$resource->orderBy->add('<SORTING_PARAMETER>'[,<FIELD>][,<DIRECTION>]);
$resource->orderBy-><SORTING_PARAMETER>;
$resource->orderBy['<SORTING_PARAMETER>'];
$resource->orderBy-><SORTING_PARAMETER>([,<FIELD>][,<DIRECTION>]);

对于每个过滤器,您可以指定一个相关表字段进行排序,使用field('<FIELD>')函数,以及一个默认排序方向,使用defaultOrder('<DIRECTION>')。如果您想使排序方向固定且不可由用户修改,可以使用direction('<DIRECTION>')方法。

如果您想自定义排序,可以将回调函数作为field参数传递;将要应用排序的查询将被作为第一个参数传递,排序方向作为第二个参数。

示例

$resource->orderBy->email->field('email');
$resource->orderBy->name->field('username')->defaultOrder('desc');
// Forced ascending
$resource->orderBy->add('name-asc','username','asc');
// Example custom filter
$resource->orderBy->test1->field(function($query,$direction){
    $query->orderBy('email',$direction)
          ->orderBy('name',$direction)
          ->orderBy('id','asc');        
});

默认排序顺序

如果您想指定默认排序顺序,您可以:

排序查询参数

过滤器查询参数可以通过ResourceQuery的$orderField参数设置。过滤器可以作为键值对指定,排序参数作为键,方向作为值,或者使用两种简写语法之一(作为字符串,逗号分隔)。

  • <sorting_parameter>[:<direction>]
  • [+|-]<sorting_parameter>,其中前置"+"表示升序,"-"表示降序。

示例

page?order_by[field1]=&order_by[field2]=asc&order_by[field3]=desc

或者

page?order_by=field1,field2:asc,field3:desc

或者

page?order_by=field1,+field2,-field3

JavaScript API

该包包括一个JavaScript对应版本,以帮助查询后端;由于它与PHP实现紧密相关,因此该包与composer包一起分发,而不是作为单独的npm包。

将其包含在resources/js/app.js中。

import ResourceQuery from "../../vendors/plokko/resource-query/js/ResourceQuery";
// Make it available in pages
window.ResourceQuery = ResourceQuery;
//...

注意:Axios是一个必需的依赖项。

用法

通过指定目标URL和方法(默认为get)来创建一个新的ResourceQuery实例。

let rq = new ResourceQuery('/url','get');

后端应该是以下形式:

class MyController extends Controller {
    //...
    function testPage(Request $request){
        $resource = new UserResourceQuery();
        //...add filters, etc.

        // if it's an Ajax resource return the resource directly 
        if($request->ajax()){
            return $resource;
        }

        // Or else return the HTML page
        return view('mypage');
    }
    //...
}

您可以添加或修改过滤器、排序和选项。

// Set filters root parameter (must be the same as the back-end)
rq.filtersRoot = 'filters';
// Set orderby parameter (must be the same as the back-end)
rq.orderField = 'order_by';

// Add a filter
rq.filters.test1 = 'a';
// or
rq.filter('test1','a');
// or
rq.addFilters({test1:'a',test2:'b'});

// Order
rq.order_by = ['field1',['field2','desc']];
// or
rq.orderBy('field1','asc');

// Clears all the filters
rq.clearFilters();
// Clears all the orderby options
rq.clearOrderBy();
//Clears all the filters and orderby options
rq.resetQuery();

// Set page (if pagination is enabled)
rq.page = 2;
// Set the page size (may be ignored by the back-end if not allowed)
rq.pageSize = 10; // 10 element per page

请求取消和选项

支持通过token选项进行请求取消。

let rq = new ResourceQuery('/url','get');
let cancelToken = ResourceQuery.cancelToken;
rq.get({cancelToken})
    .then(r => {
        console.log('Data received',r);
    })
    .catch(e => {
        // Check if the request was user-cancelled            
        if (ResourceQuery.isCancel(e)) {
            //the request was user-cancelled, no error thrown
            console.warn('user cancelled');
        } else {
            console.error('Request error:', e);
        }
    });
//...

// When you want to cancel the request
cancelcancelToken.cancel();

有关其他支持配置选项的详细信息,请参阅Axios请求配置(某些属性可能被忽略)。