在 Laravel 9 中,基于 Spatie\QueryBuilder\QueryBuilder 来生成查询 SQL,同一字段可支持:partial、exact
1、参考:在 Laravel 9 中,在异步队列中复用 Spatie\QueryBuilder\QueryBuilder 来生成查询 SQL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /** * 查询生成器 * @param array $criteria * @return QueryBuilder */ public function QueryBuilder( array $criteria ): QueryBuilder { return QueryBuilder:: for (OrderShippingLog:: class , new Request( $criteria )) ->allowedFilters([ AllowedFilter::exact( 'shop_plat_id' ), AllowedFilter::exact( 'shop_id' ), AllowedFilter::exact( 'logistic_channel_id' ), AllowedFilter::exact( 'logistic_company_id' ), AllowedFilter::exact( 'operated_source' ), AllowedFilter::exact( 'plat_order_no' ), AllowedFilter::exact( 'logistic_freight_no' ), AllowedFilter::exact( 'logistic_freight_transfer_no' ), AllowedFilter::exact( 'logistic_freight_inner_no' ), AllowedFilter::exact( 'logistic_virtual_number' ), AllowedFilter::exact( 'shipping_type' ), AllowedFilter::exact( 'shipping_status' ), AllowedFilter::scope( 'shipping_at_gmt_start' ), AllowedFilter::scope( 'shipping_at_gmt_end' ), AllowedFilter::scope( 'operated_at_gmt_start' ), AllowedFilter::scope( 'operated_at_gmt_end' ), ]) ->with( 'shopPlat:id,title' ) ->with( 'shop:id,title' ) ->with( 'order.orderItemLogisticsFeatures' ) ->with( 'order.urgentType:id,title,color' ) ->with( 'logisticChannel:id,title' ) ->with( 'operatorUser:id,name,number' ) ->defaultSort( '-id' ); } |
2、现在的实现方案,针对某一个字段,只能够使用一种过滤器,或者 partial ,或者 exact。参考:在 Yii 2.0 中,实现过滤器的请求参数形式。
1 2 3 4 5 6 7 8 9 10 11 | { "filter": { "plat_order_no": [ "GM20240202055938", "GM20240131081251" ] }, "sort": "-operated_at_gmt", "per_page": 20, "page": 1 } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | { "filter": { "plat_order_no": [ "like": [ "GM20240202055938", "GM20240131081251" ] ] }, "sort": "-operated_at_gmt", "per_page": 20, "page": 1 } |
3、针对需要 单个模糊检索,多个精确检索 的字段,决定验证其类型为数组,然后判断数组元素的数量,如果大于 1 ,则精确检索,否则,模糊检索。最终实现如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $validator = Validator::make( $params , [ 'filter.plat_order_no' => 'array' , 'filter.plat_order_no.*' => 'max:100' , ], [ 'filter.plat_order_no.array' => '原订单的平台订单号必须是数组' , 'filter.plat_order_no.*.max' => '原订单的平台订单号最大长度是100' , ] ); if ( $validator ->stopOnFirstFailure()->fails()) { throw new BusinessException(BusinessException::MODULE_ORDER, $validator ->getMessageBag()->first()); } return $validator ; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | // 单个模糊检索,多个精确检索:订单号、交易号、退货单号、退货快递单号、货运单号、商品SKU // 键为请求参数,值为 SQL 查询字段 $fields = [ 'plat_order_no' => 'plat_order_no' , ]; foreach ( $fields as $key => $field ) { if (isset( $criteria [ 'filter' ][ $key ])) { if ( count ( $criteria [ 'filter' ][ $key ]) > 1) { // 多个精确检索 $allowedFilters [] = AllowedFilter::exact( $field ); } else { // 单个模糊检索 $allowedFilters [] = AllowedFilter::partial( $field ); } if ( $key != $field ) { $criteria [ 'filter' ][ $field ] = $criteria [ 'filter' ][ $key ]; unset( $criteria [ 'filter' ][ $key ]); } } } $builder = QueryBuilder:: for (ReturnOrder:: class , new Request( $criteria )) ->select( 'return_orders.*' ) ->allowedFilters( $allowedFilters ) ->defaultSort( '-id' ); |
近期评论