orderId = $orderId; $this->retryReason = $retryReason; parent::__construct(['order_id' => $orderId, 'retry_reason' => $retryReason]); } /** * 执行任务 * * @return bool */ public function run(): bool { try { // 获取订单 $order = TransferOrder::find($this->orderId); if (!$order) { Log::warning('Retry failed order job: Order not found', [ 'order_id' => $this->orderId ]); return false; } // 检查订单状态是否可以重试 if (!$order->canRetry()) { Log::info('Retry failed order job: Order cannot be retried', [ 'order_id' => $this->orderId, 'status' => $order->status->value ]); return false; } Log::info('Retrying failed transfer order', [ 'order_id' => $this->orderId, 'type' => $order->type->value, 'retry_reason' => $this->retryReason, 'attempt' => $this->attempts() ]); // 重置订单状态为已创建 $order->updateStatus(TransferStatus::CREATED, '重试处理'); // 根据订单类型进行重试处理 $success = false; if ($order->isTransferOut()) { $success = OrderLogic::processTransferOut($order); } elseif ($order->isTransferIn()) { // 转入订单通常不需要重试,因为资金已经到账 // 但可以重试回调发送 $success = $this->retryTransferInCallback($order); } if ($success) { Log::info('Transfer order retry successful', [ 'order_id' => $this->orderId, 'type' => $order->type->value ]); } else { Log::warning('Transfer order retry failed', [ 'order_id' => $this->orderId, 'type' => $order->type->value, 'attempt' => $this->attempts() ]); // 如果是最后一次尝试,标记为最终失败 if ($this->attempts() >= $this->tries) { $order->updateStatus(TransferStatus::FAILED, '重试次数已达上限'); } } } catch (\Exception $e) { Log::error('Retry failed order job error', [ 'order_id' => $this->orderId, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); // 重新抛出异常以触发重试机制 throw $e; } return true; } /** * 获取任务数据 * * @return array */ public function payload() { return [ 'order_id' => $this->orderId, 'retry_reason' => $this->retryReason ]; } /** * 重试转入订单的回调发送 * * @param TransferOrder $order * @return bool */ protected function retryTransferInCallback(TransferOrder $order): bool { try { // 如果应用支持回调,则发送回调 if ($order->transferApp->supportsCallback()) { SendCallbackJob::dispatch($order); return true; } // 如果不支持回调,直接标记为完成 $order->updateStatus(TransferStatus::COMPLETED); return true; } catch (\Exception $e) { Log::error('Retry transfer in callback failed', [ 'order_id' => $order->id, 'error' => $e->getMessage() ]); return false; } } /** * 任务失败处理 * * @param \Throwable $exception * @return void */ public function failed(\Throwable $exception): void { Log::error('Retry failed order job finally failed', [ 'order_id' => $this->orderId, 'error' => $exception->getMessage(), 'attempts' => $this->attempts() ]); // 尝试更新订单状态为最终失败 try { $order = TransferOrder::find($this->orderId); if ($order && $order->canRetry()) { $order->updateStatus(TransferStatus::FAILED, '重试任务失败: ' . $exception->getMessage()); } } catch (\Exception $e) { Log::error('Failed to update order status after retry job failed', [ 'order_id' => $this->orderId, 'error' => $e->getMessage() ]); } } /** * 计算重试延迟时间 * * @return int */ public function backoff(): int { // 指数退避:第1次重试延迟60秒,第2次延迟120秒,第3次延迟240秒 return 60 * pow(2, $this->attempts() - 1); } /** * 获取任务标识 * * @return string */ public function getJobIdentifier(): string { return "retry_failed_order_{$this->orderId}"; } }