id ?? 0); $userId = is_array($userData) ? ($userData['id'] ?? 0) : ($userData->id ?? 0); try { if ($orderId) { Db::transaction(function () use ($orderId, $userId) { $order = Order::with('items')->where('id', $orderId)->lock(true)->find(); if (!$order) { return; } $user = User::get($userId ?: $order->user_id); $ext = is_array($order->ext) ? $order->ext : (json_decode($order->ext ?? '', true) ?: []); // 幂等防重:检查是否已经执行过减库存与活动支付处理 if (empty($ext['paid_forward_processed'])) { // 订单减库存 $stockSale = new StockSale(); $stockSale->forwardStockSale($order); // 处理发票审核改为等待开具 if ($order->invoice_status == 1) { $invoice = OrderInvoice::where('order_id', $order->id)->find(); if ($invoice) { $invoice->status = 'waiting'; $invoice->save(); } } // 处理活动,加入拼团,完成拼团,添加赠品记录等 ActivityFacade::buyOk($order, $user); // 将订单参与活动信息改为已支付 $orderOper = new OrderOper(); $orderOper->activityOrderPaid($order); $ext['paid_forward_processed'] = time(); $order->ext = $ext; $order->save(); } // 触发订单支付完成事件(下游结算服务内置原生幂等) $eventData = ['order' => $order, 'user' => $user]; \think\Hook::listen('order_paid_after', $eventData); }); } // 删除 job $job->delete(); } catch (HttpResponseException $e) { $data = $e->getResponse()->getData(); $message = $data ? ($data['msg'] ?? '') : $e->getMessage(); format_log_error($e, 'OrderPaid.paid.HttpResponseException', $message); $this->handleFailure($job, $orderId, 'paid', $message); } catch (\Throwable $e) { $message = $e->getMessage(); format_log_error($e, 'OrderPaid.paid', $message); $this->handleFailure($job, $orderId, 'paid', $message); } } /** * 订单选择线下支付(货到付款)完成 */ public function offline(Job $job, $data) { $orderData = $data['order'] ?? null; $userData = $data['user'] ?? null; $orderId = is_array($orderData) ? ($orderData['id'] ?? 0) : ($orderData->id ?? 0); $userId = is_array($userData) ? ($userData['id'] ?? 0) : ($userData->id ?? 0); try { if ($orderId) { Db::transaction(function () use ($orderId, $userId) { $order = Order::with('items')->where('id', $orderId)->lock(true)->find(); if (!$order) { return; } $user = User::get($userId ?: $order->user_id); $ext = is_array($order->ext) ? $order->ext : (json_decode($order->ext ?? '', true) ?: []); if (empty($ext['offline_forward_processed'])) { // 订单减库存 $stockSale = new StockSale(); $stockSale->forwardStockSale($order); // 处理活动,加入拼团,完成拼团,添加赠品记录等 ActivityFacade::buyOk($order, $user); $ext['offline_forward_processed'] = time(); $order->ext = $ext; $order->save(); } // 触发订单选择线下支付(货到付款)完成事件 $eventData = ['order' => $order, 'user' => $user]; \think\Hook::listen('order_offline_after', $eventData); }); } // 删除 job $job->delete(); } catch (HttpResponseException $e) { $data = $e->getResponse()->getData(); $message = $data ? ($data['msg'] ?? '') : $e->getMessage(); format_log_error($e, 'OrderPaid.offline.HttpResponseException', $message); $this->handleFailure($job, $orderId, 'offline', $message); } catch (\Throwable $e) { $message = $e->getMessage(); format_log_error($e, 'OrderPaid.offline', $message); $this->handleFailure($job, $orderId, 'offline', $message); } } /** * 生产级失败与阶梯重试处理 */ protected function handleFailure(Job $job, $orderId, $action, $errorMessage) { $attempts = $job->attempts(); $maxAttempts = 5; if ($attempts >= $maxAttempts) { \think\Log::record("[OrderPaid CRITICAL] 订单 ID:{$orderId} ({$action}) 处理连续失败 {$attempts} 次已达上限: {$errorMessage}", 'error'); $this->failed([ 'job' => "OrderPaid@{$action}", 'order_id' => $orderId, 'error' => $errorMessage, 'attempts' => $attempts, 'failed_time' => time(), ]); $job->delete(); } else { $delay = min(60, $attempts * 5); $job->release($delay); } } }