在 Laravel 9 中,在异步队列中复用 Spatie\QueryBuilder\QueryBuilder 来生成查询 SQL
1、在 Laravel 9 中,现在已经实现一个列表的 API,其基于 Spatie\QueryBuilder\QueryBuilder 实现从 API 请求轻松构建 Eloquent 查询。但是,现在需要在列表页面实现一个导出 Excel 的功能,计划在异步队列中实现。那么,要想复用之前的构建 Eloquent 查询的代码,好像只能够将 Request 对象传递至队列中?
2、提示报错:Serialization of ‘Closure’ is not allowed。如图1
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | { "status_code": 500, "code": 0, "message": "Serialization of 'Closure' is not allowed", "trace": { "line": 158, "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Queue.php", "class": "Exception", "trace": [ "#0 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Queue.php(158): serialize(Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob))", "#1 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Queue.php(127): Illuminate\\Queue\\Queue->createObjectPayload(Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob), 'queues:export_q...')", "#2 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\RedisQueue.php(212): Illuminate\\Queue\\Queue->createPayloadArray(Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob), 'queues:export_q...', '')", "#3 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Queue.php(105): Illuminate\\Queue\\RedisQueue->createPayloadArray(Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob), 'queues:export_q...', '')", "#4 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\RedisQueue.php(136): Illuminate\\Queue\\Queue->createPayload(Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob), 'queues:export_q...', '')", "#5 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Queue\\Queue.php(57): Illuminate\\Queue\\RedisQueue->push(Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob), '', 'export_queue')", "#6 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Bus\\Dispatcher.php(246): Illuminate\\Queue\\Queue->pushOn('export_queue', Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob))", "#7 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Bus\\Dispatcher.php(229): Illuminate\\Bus\\Dispatcher->pushCommandToQueue(Object(Illuminate\\Queue\\RedisQueue), Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob))", "#8 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Bus\\Dispatcher.php(77): Illuminate\\Bus\\Dispatcher->dispatchToQueue(Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob))", "#9 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Bus\\PendingDispatch.php(193): Illuminate\\Bus\\Dispatcher->dispatch(Object(Modules\\Order\\Jobs\\OrderShippingLogExportJob))", "#10 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Bus\\Dispatchable.php(18): Illuminate\\Foundation\\Bus\\PendingDispatch->__destruct()", "#11 E:\\wwwroot\\object\\Modules\\Order\\Services\\OrderShippingLogService.php(205): Modules\\Order\\Jobs\\OrderShippingLogExportJob::dispatch(Object(App\\Models\\JobStatus), Array, Object(Illuminate\\Http\\Request))", "#12 E:\\wwwroot\\object\\Modules\\Order\\Http\\Controllers\\Api\\OrderShippingLogController.php(46): Modules\\Order\\Services\\OrderShippingLogService->export(Array, Object(Illuminate\\Http\\Request))", "#13 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Controller.php(54): Modules\\Order\\Http\\Controllers\\Api\\OrderShippingLogController->export()", "#14 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction('export', Array)", "#15 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php(259): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(Modules\\Order\\Http\\Controllers\\Api\\OrderShippingLogController), 'export')", "#16 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Route.php(204): Illuminate\\Routing\\Route->runController()", "#17 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(725): Illuminate\\Routing\\Route->run()", "#18 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(141): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))", "#19 E:\\wwwroot\\object\\vendor\\spatie\\laravel-permission\\src\\Middlewares\\RoleOrPermissionMiddleware.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#20 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Spatie\\Permission\\Middlewares\\RoleOrPermissionMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'order_transport...')", "#21 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Middleware\\SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#22 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))", "#23 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Auth\\Middleware\\Authenticate.php(44): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#24 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Auth\\Middleware\\Authenticate->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'api')", "#25 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#26 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(726): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))", "#27 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(703): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))", "#28 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(667): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))", "#29 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(656): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))", "#30 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(190): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))", "#31 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(141): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))", "#32 E:\\wwwroot\\object\\app\\Http\\Middleware\\QueryListenerMiddleware.php(30): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#33 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): App\\Http\\Middleware\\QueryListenerMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))", "#34 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#35 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))", "#36 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))", "#37 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#38 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))", "#39 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#40 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))", "#41 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Http\\Middleware\\HandleCors.php(62): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#42 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Http\\Middleware\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))", "#43 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Http\\Middleware\\TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#44 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(180): Illuminate\\Http\\Middleware\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))", "#45 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(116): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))", "#46 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(165): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))", "#47 E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(134): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))", "#48 E:\\wwwroot\\object\\public\\index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))", "#49 {main}" ] } } |
3、尝试先将请求对象转换为数组,然后在异步队列中,再重新转换为请求对象。尝试打印 原生的请求对象 与 转换后的请求对象 的所有请求数据。完全相等,符合预期。
1 2 3 4 5 6 | $params = $this ->request->all(); print_r( $params ); $request = new Request( $params ); print_r( $request ); print_r( $request ->all()); exit ; |
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | Array ( [filter] => Array ( [shop_plat_id] => Array ( [0] => 1 [1] => 2 ) [shop_id] => Array ( [0] => 1 [1] => 14 ) [logistic_channel_id] => Array ( [0] => 304872 [1] => 474241 ) [logistic_company_id] => Array ( [0] => 10336 [1] => 10340 ) [operated_source] => Array ( [0] => 1 [1] => 2 ) [plat_order_no] => Array ( [0] => GM20240202055938 [1] => GM20240131081251 ) [logistic_freight_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_freight_transfer_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_freight_inner_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_virtual_number] => Array ( [0] => GM20240202055938766 [1] => GM20240131081251410 ) [shipping_type] => Array ( [0] => 1 [1] => 2 ) [shipping_status] => Array ( [0] => 2 [1] => 3 ) [shipping_at_gmt_start] => 2024-02-02 05:52:31 [shipping_at_gmt_end] => 2024-02-04 05:52:31 [operated_at_gmt_start] => 2024-02-02 05:52:31 [operated_at_gmt_end] => 2024-02-04 05:52:31 ) [per_page] => 20 [page] => 1 ) Illuminate\Http\Request Object ( [attributes] => Symfony\Component\HttpFoundation\ParameterBag Object ( [parameters:protected] => Array ( ) ) [request] => Symfony\Component\HttpFoundation\InputBag Object ( [parameters:protected] => Array ( ) ) [query] => Symfony\Component\HttpFoundation\InputBag Object ( [parameters:protected] => Array ( [filter] => Array ( [shop_plat_id] => Array ( [0] => 1 [1] => 2 ) [shop_id] => Array ( [0] => 1 [1] => 14 ) [logistic_channel_id] => Array ( [0] => 304872 [1] => 474241 ) [logistic_company_id] => Array ( [0] => 10336 [1] => 10340 ) [operated_source] => Array ( [0] => 1 [1] => 2 ) [plat_order_no] => Array ( [0] => GM20240202055938 [1] => GM20240131081251 ) [logistic_freight_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_freight_transfer_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_freight_inner_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_virtual_number] => Array ( [0] => GM20240202055938766 [1] => GM20240131081251410 ) [shipping_type] => Array ( [0] => 1 [1] => 2 ) [shipping_status] => Array ( [0] => 2 [1] => 3 ) [shipping_at_gmt_start] => 2024-02-02 05:52:31 [shipping_at_gmt_end] => 2024-02-04 05:52:31 [operated_at_gmt_start] => 2024-02-02 05:52:31 [operated_at_gmt_end] => 2024-02-04 05:52:31 ) [per_page] => 20 [page] => 1 ) ) [server] => Symfony\Component\HttpFoundation\ServerBag Object ( [parameters:protected] => Array ( ) ) [files] => Symfony\Component\HttpFoundation\FileBag Object ( [parameters:protected] => Array ( ) ) [cookies] => Symfony\Component\HttpFoundation\InputBag Object ( [parameters:protected] => Array ( ) ) [headers] => Symfony\Component\HttpFoundation\HeaderBag Object ( [headers:protected] => Array ( ) [cacheControl:protected] => Array ( ) ) [content:protected] => [languages:protected] => [charsets:protected] => [encodings:protected] => [acceptableContentTypes:protected] => [pathInfo:protected] => [requestUri:protected] => [baseUrl:protected] => [basePath:protected] => [method:protected] => [format:protected] => [session:protected] => [locale:protected] => [defaultLocale:protected] => en [preferredFormat:Symfony\Component\HttpFoundation\Request:private] => [isHostValid:Symfony\Component\HttpFoundation\Request:private] => 1 [isForwardedValid:Symfony\Component\HttpFoundation\Request:private] => 1 [json:protected] => [convertedFiles:protected] => [userResolver:protected] => [routeResolver:protected] => ) Array ( [filter] => Array ( [shop_plat_id] => Array ( [0] => 1 [1] => 2 ) [shop_id] => Array ( [0] => 1 [1] => 14 ) [logistic_channel_id] => Array ( [0] => 304872 [1] => 474241 ) [logistic_company_id] => Array ( [0] => 10336 [1] => 10340 ) [operated_source] => Array ( [0] => 1 [1] => 2 ) [plat_order_no] => Array ( [0] => GM20240202055938 [1] => GM20240131081251 ) [logistic_freight_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_freight_transfer_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_freight_inner_no] => Array ( [0] => PH900016739XX [1] => PH900890788XX ) [logistic_virtual_number] => Array ( [0] => GM20240202055938766 [1] => GM20240131081251410 ) [shipping_type] => Array ( [0] => 1 [1] => 2 ) [shipping_status] => Array ( [0] => 2 [1] => 3 ) [shipping_at_gmt_start] => 2024-02-02 05:52:31 [shipping_at_gmt_end] => 2024-02-04 05:52:31 [operated_at_gmt_start] => 2024-02-02 05:52:31 [operated_at_gmt_end] => 2024-02-04 05:52:31 ) [per_page] => 20 [page] => 1 ) |
4、最终实现如下,符合预期。如图2
1 2 3 4 5 6 7 8 | $orderShippingLogQueryBuilder = $this ->repository->QueryBuilder( $params ); $orderShippingLogQueryBuilder ->chunk(100, function ( $orderShippingLogs ) { foreach ( $orderShippingLogs as $orderShippingLog ) { echo $orderShippingLog ->id; } }); exit ; |
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' ); } |
1 条回复
[…] 1、参考:在 Laravel 9 中,在异步队列中复用 SpatieQueryBuilderQueryBuilder 来生成查询 SQL […]