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