setName('shopro:print-retry') ->addOption('order-id', null, Option::VALUE_REQUIRED, 'failed print task order id') ->addOption('all', null, Option::VALUE_NONE, 'retry all failed print tasks') ->addOption('recover-missing', null, Option::VALUE_NONE, 'create print tasks for recently paid orders missing one') ->addOption('lookback', null, Option::VALUE_REQUIRED, 'recovery lookback in minutes', 1440) ->addOption('dry-run', null, Option::VALUE_NONE, 'report work without changing print tasks') ->setDescription('Requeue failed Shopro receipt print tasks'); } protected function execute(Input $input, Output $output) { $orderId = (int)$input->getOption('order-id'); $all = (bool)$input->getOption('all'); $recoverMissing = (bool)$input->getOption('recover-missing'); $dryRun = (bool)$input->getOption('dry-run'); if (!$orderId && !$all && !$recoverMissing) { $output->error('Use --order-id=, --all, or --recover-missing.'); return 1; } $staleBefore = time() - 300; $tasks = []; if ($orderId || $all) { $query = Db::name('shopro_order_print_task') ->whereRaw('(status = -1 OR ((status = 0 OR status = 2) AND updated_at < ' . $staleBefore . '))'); if ($orderId) { $query->where('order_id', $orderId); } $tasks = $query->select(); } foreach ($tasks as $task) { if (!$dryRun) { Db::name('shopro_order_print_task')->where('id', $task['id'])->update([ 'status' => 0, 'updated_at' => time(), 'last_error' => '', ]); \think\Queue::push('\\addons\\shopro\\job\\OrderPrint@handle', ['order_id' => $task['order_id']], 'shopro-high'); } } $recovered = 0; if ($recoverMissing) { $lookback = max(1, min(43200, (int)$input->getOption('lookback'))); $orders = Db::name('shopro_order')->alias('o') ->join('shopro_order_print_task t', 't.order_id = o.id', 'LEFT') ->where('o.status', '>=', 1) ->where('o.paytime', '>=', time() - $lookback * 60) ->whereNull('t.id') ->field('o.id,o.order_sn') ->select(); foreach ($orders as $order) { if ($dryRun) { $recovered++; continue; } $created = Db::transaction(function () use ($order) { $exists = Db::name('shopro_order_print_task')->where('order_id', $order['id'])->lock(true)->find(); if ($exists) { return false; } Db::name('shopro_order_print_task')->insert([ 'order_id' => $order['id'], 'order_sn' => $order['order_sn'], 'status' => 0, 'attempts' => 0, 'verify_attempts' => 0, 'created_at' => time(), 'updated_at' => time(), ]); return true; }); if ($created) { \think\Queue::push('\\addons\\shopro\\job\\OrderPrint@handle', ['order_id' => $order['id']], 'shopro-high'); $recovered++; } } } $prefix = $dryRun ? 'Would requeue ' : 'Requeued '; $output->info($prefix . count($tasks) . ' receipt print task(s); ' . ($dryRun ? 'would recover ' : 'recovered ') . $recovered . ' missing task(s).'); return 0; } }