海南旅游SAAS
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.

89 lines
2.0 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Common\OrderStatus;
  4. use App\Models\Order;
  5. use App\Models\Product;
  6. use Illuminate\Console\Command;
  7. use Illuminate\Support\Facades\DB;
  8. class OrderTimeout extends Command
  9. {
  10. /**
  11. * The name and signature of the console command.
  12. *
  13. * @var string
  14. */
  15. protected $signature = 'order:timeout';
  16. /**
  17. * The console command description.
  18. *
  19. * @var string
  20. */
  21. protected $description = '订单超时未支付,取消订单并返回库存';
  22. /**
  23. * Create a new command instance.
  24. *
  25. * @return void
  26. */
  27. public function __construct()
  28. {
  29. parent::__construct();
  30. }
  31. /**
  32. * Execute the console command.
  33. *
  34. * @return int
  35. */
  36. public function handle()
  37. {
  38. //需要处理的订单状态
  39. $status_arr = [OrderStatus::UNPAID, OrderStatus::PAY_EARNEST, OrderStatus::OFFLINE_UNPAID];
  40. //记录最小ID,下次查询时按ID正序查询,只处理大于该ID的订单,避免重复扫描数据库
  41. /*$min_id = Order::query()
  42. ->whereIn('status', $status_arr)
  43. ->whereNotNull('timeout')
  44. ->min('id');*/
  45. $min_id = 0;
  46. while (true) {
  47. Order::query()
  48. // ->where('id', '>=', $min_id)
  49. ->whereIn('status', $status_arr)
  50. ->whereNotNull('timeout')
  51. ->orderBy('id')
  52. ->chunk(100, function ($order) use (&$min_id) {
  53. foreach ($order as $v) {
  54. if (!is_null($v->timeout) && strtotime($v->timeout) < time()) {
  55. DB::beginTransaction();
  56. try {
  57. //取消订单
  58. $v->status = OrderStatus::CANCEL;
  59. $v->save();
  60. //加回库存
  61. Product::whereIn('id', explode(',', $v->product_ids))->increment('stock', $v->num);
  62. DB::commit();
  63. $min_id = $v->id;
  64. } catch (\Exception $exception) {
  65. DB::rollBack();
  66. $this->line("订单ID {$v->id} 错误:" . $exception->getMessage());
  67. }
  68. }
  69. }
  70. });
  71. //TODO 产品规格表加库存
  72. $this->line('[' . date('Y-m-d H:i:s') . "] ID游标:$min_id ,等待下一个任务");
  73. sleep(3);
  74. }
  75. return 0;
  76. }
  77. }