没有不值得去解决的问题,也没有不值得去学习的技术!

在 Laravel 9 中,基于 Spatie\QueryBuilder\QueryBuilder 来生成查询 SQL,同一字段可支持:partial、exact

1、参考:在 Laravel 9 中,在异步队列中复用 Spatie\QueryBuilder\QueryBuilder 来生成查询 SQL



    /**
     * 查询生成器
     * @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 中,实现过滤器的请求参数形式


{
    "filter": {
        "plat_order_no": [
            "GM20240202055938",
            "GM20240131081251"
        ]
    },
    "sort": "-operated_at_gmt",
    "per_page": 20,
    "page": 1
}




{
    "filter": {
        "plat_order_no": [
			"like": [
				"GM20240202055938",
				"GM20240131081251"
			]
        ]
    },
    "sort": "-operated_at_gmt",
    "per_page": 20,
    "page": 1
}


3、针对需要 单个模糊检索,多个精确检索 的字段,决定验证其类型为数组,然后判断数组元素的数量,如果大于 1 ,则精确检索,否则,模糊检索。最终实现如下。


$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;




        // 单个模糊检索,多个精确检索:订单号、交易号、退货单号、退货快递单号、货运单号、商品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');


   

PHP / Laravel / Yii2 老项目维护与长期技术支持

如果你的 PHP / Laravel / Yii2 项目已经上线,但遇到原开发离职、Bug 长期无人修复、接口不稳定、性能下降、代码难以接手等问题,可以联系我做一次远程技术排查。

适合以下情况:
✅ 老旧 PHP 系统无人维护
✅ Laravel / Yii2 项目 Bug 修复
✅ 后台管理系统小功能迭代
✅ RESTful API 接口排查
✅ MySQL / Redis / Nginx 性能问题
✅ 长期远程兼职维护

可先从一次小问题开始:
✅ 线上报错排查
✅ 接口异常分析
✅ 慢查询与性能瓶颈定位
✅ 代码结构初步评估
✅ 部署环境与日志检查

如需咨询,请联系我,并注明:PHP 维护咨询

联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理