From 6883e74cf51b7a34bb74bea478c0b6335c8c961d Mon Sep 17 00:00:00 2001 From: zhenhui <1276357500@qq.com> Date: Wed, 6 May 2026 17:15:47 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BC=98=E5=8C=96=E7=BB=9F=E4=B8=80=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E6=8E=A8=E9=80=81=E6=8A=A5=E9=94=99=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/process/AngpowImportJobs.php | 84 +++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/app/process/AngpowImportJobs.php b/app/process/AngpowImportJobs.php index d7abe9a..81266ce 100644 --- a/app/process/AngpowImportJobs.php +++ b/app/process/AngpowImportJobs.php @@ -6,6 +6,7 @@ use app\common\model\MallItem; use app\common\model\MallOrder; use app\common\model\MallUserAsset; use GuzzleHttp\Client; +use support\Log; use Workerman\Timer; use Workerman\Worker; @@ -181,6 +182,7 @@ class AngpowImportJobs $data = json_decode($body, true); if (!is_array($data)) { + Log::error($this->formatAngpowInvalidJsonBodyForLog($res, $body, $orderIds)); foreach ($orders as $order) { if (!$order instanceof MallOrder) { continue; @@ -205,7 +207,9 @@ class AngpowImportJobs return; } - // 失败:整批视为失败(对方未提供逐条返回) + // 失败:整批视为失败(对方未提供逐条返回);解析后的 JSON 仅写入项目日志 + $this->logAngpowPushRejectedParsedBody($orderIds, $data); + foreach ($orders as $order) { if (!$order instanceof MallOrder) { continue; @@ -266,6 +270,84 @@ class AngpowImportJobs ]; } + /** + * 对方返回体无法解析为「根级 JSON 对象」时,生成写入项目日志的完整说明(不落库订单 fail_reason)。 + * + * @param list $orderIds + * @param mixed $response Guzzle 响应或其它 + */ + private function formatAngpowInvalidJsonBodyForLog(mixed $response, string $rawBody, array $orderIds): string + { + $httpPart = 'HTTP unknown'; + if (is_object($response) && method_exists($response, 'getStatusCode')) { + $code = $response->getStatusCode(); + if (is_int($code)) { + $httpPart = 'HTTP ' . $code; + } + } + + $trimmed = trim($rawBody); + if ($trimmed === '') { + $detail = 'empty body'; + } elseif (json_last_error() !== JSON_ERROR_NONE) { + $msg = json_last_error_msg(); + $detail = is_string($msg) && $msg !== '' ? $msg : 'JSON parse error'; + } else { + $detail = 'root is not a JSON object'; + } + + $idPart = implode(',', $orderIds); + + $snippet = ''; + if ($trimmed !== '') { + $oneLine = preg_replace('/\s+/', ' ', $trimmed); + $snippet = is_string($oneLine) && $oneLine !== '' ? $oneLine : $trimmed; + $maxLen = 8000; + if (function_exists('mb_strlen') && function_exists('mb_substr')) { + if (mb_strlen($snippet, 'UTF-8') > $maxLen) { + $snippet = mb_substr($snippet, 0, $maxLen, 'UTF-8') . '…'; + } + } elseif (strlen($snippet) > $maxLen) { + $snippet = substr($snippet, 0, $maxLen) . '…'; + } + } + + $head = '[AngpowImport] response not a JSON object | order_ids=' . $idPart . ' | ' . $httpPart . ' | ' . $detail; + if ($snippet === '') { + return $head; + } + + return $head . ' | body=' . $snippet; + } + + /** + * 可解析 JSON 但业务失败时,将解析结果写入项目日志(订单仍只记 message 等业务文案)。 + * + * @param list $orderIds + * @param array $parsed + */ + private function logAngpowPushRejectedParsedBody(array $orderIds, array $parsed): void + { + $flags = JSON_UNESCAPED_UNICODE; + if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) { + $flags = $flags | JSON_INVALID_UTF8_SUBSTITUTE; + } + $encoded = json_encode($parsed, $flags); + if (!is_string($encoded)) { + $encoded = 'json_encode failed'; + } + $maxLen = 8000; + if (function_exists('mb_strlen') && function_exists('mb_substr')) { + if (mb_strlen($encoded, 'UTF-8') > $maxLen) { + $encoded = mb_substr($encoded, 0, $maxLen, 'UTF-8') . '…'; + } + } elseif (strlen($encoded) > $maxLen) { + $encoded = substr($encoded, 0, $maxLen) . '…'; + } + + Log::error('[AngpowImport] push rejected (parsed JSON) | order_ids=' . implode(',', $orderIds) . ' | body=' . $encoded); + } + /** * 单条失败原因压成一行,避免异常信息自带换行导致与 attempt 分段混在一起。 */