This commit is contained in:
Your Name
2026-06-01 17:43:01 +08:00
parent cbf992d6df
commit 0a781bda54
2 changed files with 154 additions and 28 deletions
@@ -1086,11 +1086,21 @@ class ExpressTrackingService
$detail = self::loadTrackingDetailNormalized($num);
if (is_array($detail)) {
$fromDb = self::effectiveSignUnixFromTrackingDetail($detail);
if ($fromDb > 0) {
$memo[$cacheKey] = $fromDb;
// 与 logisticsTrace:库内有轨迹明细时才视为「库内可查」
if (!empty($detail['traces'])) {
$fromDb = self::effectiveSignUnixFromTrackingDetail($detail);
if ($fromDb > 0) {
$memo[$cacheKey] = $fromDb;
return $fromDb;
return $fromDb;
}
} else {
$fromHead = self::effectiveSignUnixFromTrackingDetail($detail);
if ($fromHead > 0) {
$memo[$cacheKey] = $fromHead;
return $fromHead;
}
}
}
@@ -1100,10 +1110,7 @@ class ExpressTrackingService
return 0;
}
$ec = strtolower(trim($expressCompany));
if ($ec === '') {
$ec = 'auto';
}
$ec = ExpressTrackService::normalizeExpressCompanyCode($num, (string) $expressCompany);
$api = ExpressTrackService::query($ec, $num, $recipientPhone, '');
$fromApi = self::effectiveSignUnixFromKuaidiPayload($api);
$memo[$cacheKey] = $fromApi;
@@ -1111,6 +1118,94 @@ class ExpressTrackingService
return $fromApi;
}
/**
* 按业务订单 id 解析签收时间,与 PrescriptionOrderLogic::logisticsTrace 同口径。
* allowHttp 为 true 时:库内无轨迹则 queryAndUpdate 落库后再读,避免「快递单 API 已签收、提成结算库内为空」。
*/
public static function syncSignUnixFromLogisticsForPrescriptionOrder(int $orderId, bool $allowHttp = true): int
{
static $memo = [];
$cacheKey = $orderId . '|' . ($allowHttp ? '1' : '0');
if (isset($memo[$cacheKey])) {
return $memo[$cacheKey];
}
$order = PrescriptionOrder::where('id', $orderId)->whereNull('delete_time')->find();
if (!$order) {
$memo[$cacheKey] = 0;
return 0;
}
$num = trim((string) ($order->tracking_number ?? ''));
if ($num === '') {
$memo[$cacheKey] = 0;
return 0;
}
$detail = self::loadTrackingDetailNormalized($num);
if (is_array($detail)) {
if (!empty($detail['traces'])) {
$fromDb = self::effectiveSignUnixFromTrackingDetail($detail);
if ($fromDb > 0) {
$memo[$cacheKey] = $fromDb;
return $fromDb;
}
} else {
$fromHead = self::effectiveSignUnixFromTrackingDetail($detail);
if ($fromHead > 0) {
$memo[$cacheKey] = $fromHead;
return $fromHead;
}
}
}
if (!$allowHttp) {
$memo[$cacheKey] = 0;
return 0;
}
$tracking = self::resolveTrackingByNumber($num);
if ($tracking) {
try {
self::queryAndUpdate((int) $tracking->id, false);
} catch (\Throwable $e) {
Log::warning('syncSignUnixFromLogisticsForPrescriptionOrder queryAndUpdate failed: ' . $e->getMessage(), [
'order_id' => $orderId,
'tracking_number' => $num,
]);
}
$detailAfter = self::loadTrackingDetailNormalized($num);
if (is_array($detailAfter)) {
$fromDb = self::effectiveSignUnixFromTrackingDetail($detailAfter);
if ($fromDb > 0) {
$memo[$cacheKey] = $fromDb;
return $fromDb;
}
}
}
$ec = ExpressTrackService::normalizeExpressCompanyCode(
$num,
(string) ($order->express_company ?? 'auto')
);
$api = ExpressTrackService::query(
$ec,
$num,
(string) ($order->recipient_phone ?? ''),
''
);
$fromApi = self::effectiveSignUnixFromKuaidiPayload($api);
$memo[$cacheKey] = $fromApi;
return $fromApi;
}
/**
* 单号精确匹配失败时尝试 TRIM(TrackingNumber)(历史数据首尾空格)。
*
@@ -1188,7 +1283,26 @@ class ExpressTrackingService
}
}
return max($a, $b, $c);
return max($a, $b, $c, self::signedTrackingHeadFallbackUnix($detail, $stateOk));
}
/**
* 已签收但 sign_time / 轨迹时间戳均未写入时,用主表 latest_trace_time 回填(甘草等同步路径常见)。
*
* @param array<string, mixed> $detail
*/
private static function signedTrackingHeadFallbackUnix(array $detail, bool $stateOk): int
{
if (!$stateOk) {
return 0;
}
$ltRaw = trim((string) ($detail['latest_trace_time'] ?? ''));
if ($ltRaw === '') {
return 0;
}
$parsed = strtotime($ltRaw);
return ($parsed !== false && $parsed > 0) ? (int) $parsed : 0;
}
/**