|
|
@ -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; |
|
|
|
|
|
} |
|
|
|
|
|
} |