orderId = $orderId; $this->retryCount = $retryCount; $this->maxRetries = $maxRetries; parent::__construct([ 'order_id' => $orderId, 'retry_count' => $retryCount, 'max_retries' => $maxRetries ]); // 设置队列名称 $this->onQueue('transfer_callback'); } /** * 执行任务 */ public function run(): bool { try { $order = TransferOrder::find($this->orderId); if (!$order) { Log::warning('Transfer order not found for callback', [ 'order_id' => $this->orderId ]); return false; } // 检查订单状态 if ($order->isFinalStatus()) { Log::info('Transfer order already in final status, skipping callback', [ 'order_id' => $order->id, 'status' => $order->status->value ]); return true; } // 检查是否支持回调 if (!$order->transferApp->supportsCallback()) { Log::info('Transfer app does not support callback, completing order', [ 'order_id' => $order->id, 'app_id' => $order->transfer_app_id ]); $order->updateStatus(TransferStatus::COMPLETED); return true; } Log::info('Sending transfer callback', [ 'order_id' => $order->id, 'retry_count' => $this->retryCount, 'callback_url' => $order->transferApp->order_callback_url ]); // 发送回调 $success = CallbackLogic::sendCallback($order); if ($success) { Log::info('Transfer callback sent successfully', [ 'order_id' => $order->id, 'retry_count' => $this->retryCount ]); } else { $this->handleCallbackFailure($order); } } catch (\Exception $e) { Log::error('Transfer callback job failed', [ 'order_id' => $this->orderId, 'retry_count' => $this->retryCount, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); // 处理回调失败 $order = TransferOrder::find($this->orderId); if ($order) { $this->handleCallbackFailure($order); } return false; } return true; } /** * 获取任务数据 * * @return array */ public function payload() { return [ 'order_id' => $this->orderId, 'retry_count' => $this->retryCount, 'max_retries' => $this->maxRetries ]; } /** * 处理回调失败 */ private function handleCallbackFailure(TransferOrder $order): void { if ($this->retryCount < $this->maxRetries) { // 安排重试 $nextRetryCount = $this->retryCount + 1; $delayMinutes = $this->calculateRetryDelay($nextRetryCount); Log::info('Scheduling callback retry', [ 'order_id' => $order->id, 'retry_count' => $nextRetryCount, 'delay_minutes' => $delayMinutes ]); // 更新订单的重试计数 $callbackData = $order->callback_data; $callbackData['retry_count'] = $nextRetryCount; $callbackData['last_retry_at'] = now()->toDateTimeString(); $order->update(['callback_data' => $callbackData]); // 调度重试任务 self::dispatch($order->id, $nextRetryCount, $this->maxRetries) ->delay(now()->addMinutes($delayMinutes)); } else { // 达到最大重试次数,记录失败 Log::error('Transfer callback max retries reached', [ 'order_id' => $order->id, 'retry_count' => $this->retryCount, 'max_retries' => $this->maxRetries ]); // 更新订单状态为失败 $order->updateStatus(TransferStatus::FAILED, '回调发送失败,已达最大重试次数'); } } /** * 计算重试延迟时间(指数退避) */ private function calculateRetryDelay(int $retryCount): int { // 指数退避:1分钟、2分钟、4分钟 return min(pow(2, $retryCount - 1), 30); // 最大30分钟 } /** * 任务失败时的处理 */ public function failed(\Throwable $exception): void { Log::error('Transfer callback job failed permanently', [ 'order_id' => $this->orderId, 'retry_count' => $this->retryCount, 'error' => $exception->getMessage() ]); // 更新订单状态为失败 $order = TransferOrder::find($this->orderId); if ($order && !$order->isFinalStatus()) { $order->updateStatus(TransferStatus::FAILED, '回调任务失败: ' . $exception->getMessage()); } } /** * 获取任务的唯一ID */ public function uniqueId(): string { return "transfer_callback_{$this->orderId}_{$this->retryCount}"; } /** * 静态方法:调度回调任务 */ public static function schedule(int $orderId, int $delayMinutes = 0): void { $job = new self($orderId); if ($delayMinutes > 0) { $job->delay(now()->addMinutes($delayMinutes)); } dispatch($job); } /** * 静态方法:立即发送回调 */ public static function sendNow(int $orderId): void { dispatch_sync(new self($orderId)); } /** * 静态方法:批量调度回调任务 */ public static function scheduleBatch(array $orderIds, int $delayMinutes = 0): void { foreach ($orderIds as $orderId) { self::schedule($orderId, $delayMinutes); } } }