You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							82 lines
						
					
					
						
							2.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							82 lines
						
					
					
						
							2.0 KiB
						
					
					
				
								<?php
							 | 
						|
								
							 | 
						|
								namespace App\Console\Commands;
							 | 
						|
								
							 | 
						|
								use App\Common\OrderStatus;
							 | 
						|
								use App\Models\Order;
							 | 
						|
								use App\Models\Product;
							 | 
						|
								use Illuminate\Console\Command;
							 | 
						|
								use Illuminate\Support\Facades\DB;
							 | 
						|
								
							 | 
						|
								class OrderTimeout extends Command
							 | 
						|
								{
							 | 
						|
								    /**
							 | 
						|
								     * The name and signature of the console command.
							 | 
						|
								     *
							 | 
						|
								     * @var string
							 | 
						|
								     */
							 | 
						|
								    protected $signature = 'order:timeout';
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * The console command description.
							 | 
						|
								     *
							 | 
						|
								     * @var string
							 | 
						|
								     */
							 | 
						|
								    protected $description = '订单超时未支付,取消订单并返回库存';
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Create a new command instance.
							 | 
						|
								     *
							 | 
						|
								     * @return void
							 | 
						|
								     */
							 | 
						|
								    public function __construct()
							 | 
						|
								    {
							 | 
						|
								        parent::__construct();
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
									/**
							 | 
						|
									 * Execute the console command.
							 | 
						|
									 *
							 | 
						|
									 * @return int
							 | 
						|
									 */
							 | 
						|
								    public function handle()
							 | 
						|
									{
							 | 
						|
										//需要处理的订单状态
							 | 
						|
										$status_arr = [OrderStatus::UNPAID, OrderStatus::PAY_EARNEST, OrderStatus::OFFLINE_UNPAID];
							 | 
						|
								
							 | 
						|
										//记录最小ID,下次查询时按ID正序查询,只处理大于该ID的订单,避免重复扫描数据库
							 | 
						|
										$min_id = Order::query()->whereIn('status', $status_arr)->min('id');
							 | 
						|
								
							 | 
						|
								    	while (true) {
							 | 
						|
											Order::query()
							 | 
						|
												->where('id', '>=', $min_id)
							 | 
						|
												->whereIn('status', $status_arr)
							 | 
						|
												->whereNotNull('timeout')
							 | 
						|
												->orderBy('id')
							 | 
						|
												->chunk(100, function ($order) use (&$min_id) {
							 | 
						|
													foreach ($order as $v) {
							 | 
						|
														if (!is_null($v->timeout) && strtotime($v->timeout) < time()) {
							 | 
						|
															DB::beginTransaction();
							 | 
						|
															try {
							 | 
						|
																//取消订单
							 | 
						|
																$v->status = OrderStatus::CANCEL;
							 | 
						|
																$v->save();
							 | 
						|
								
							 | 
						|
																//加回库存
							 | 
						|
																Product::whereIn('id', explode(',', $v->product_ids))->increment('stock', $v->num);
							 | 
						|
								
							 | 
						|
																DB::commit();
							 | 
						|
																$min_id = $v->id;
							 | 
						|
															} catch (\Exception $exception) {
							 | 
						|
																DB::rollBack();
							 | 
						|
																$this->line("订单ID {$v->id} 错误:" . $exception->getMessage());
							 | 
						|
															}
							 | 
						|
														}
							 | 
						|
													}
							 | 
						|
												});
							 | 
						|
											$this->line('[' . date('Y-m-d H:i:s') . "] ID游标:$min_id ,等待下一个任务");
							 | 
						|
											sleep(3);
							 | 
						|
										}
							 | 
						|
										return 0;
							 | 
						|
								    }
							 | 
						|
								}
							 |