1 changed files with 79 additions and 0 deletions
			
			
		@ -0,0 +1,79 @@ | 
				
			|||
<?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() | 
				
			|||
	{ | 
				
			|||
		//记录最小ID,下次查询时按ID正序查询,只处理大于该ID的订单,避免重复扫描数据库
 | 
				
			|||
		$min_id = Order::query()->where('status', OrderStatus::UNPAID)->min('id'); | 
				
			|||
    	while (true) { | 
				
			|||
			Order::query() | 
				
			|||
				->where([ | 
				
			|||
					['status', '=', OrderStatus::UNPAID], | 
				
			|||
					['id', '>=', $min_id], | 
				
			|||
				]) | 
				
			|||
				->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(); | 
				
			|||
							} catch (\Exception $exception) { | 
				
			|||
								DB::rollBack(); | 
				
			|||
							} | 
				
			|||
						} | 
				
			|||
						$min_id = $v->id; | 
				
			|||
					} | 
				
			|||
				}); | 
				
			|||
			$this->line('[' . date('Y-m-d H:i:s') . "] ID游标:$min_id ,等待下一个任务"); | 
				
			|||
			sleep(3); | 
				
			|||
		} | 
				
			|||
		return 0; | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue