This commit is contained in:
Your Name
2026-06-01 16:30:25 +08:00
parent 01bc355bed
commit 7aec1a9713
6 changed files with 925 additions and 261 deletions
File diff suppressed because it is too large Load Diff
@@ -1291,4 +1291,121 @@ class ExpressTrackingService
return false;
}
/**
* 提成结算 overview 等大批量场景:按订单批量从库表推导签收时间(不调用快递100)。
* 语义与 YejiStatsLogic 物流子查询 / effectiveSignUnixFromTrackingDetail 对齐。
*
* @param list<array{order_id: int, tracking_number?: string}> $items
*
* @return array<int, int> order_id => sign unix
*/
public static function batchResolveSignUnixFromDbForOrders(array $items): array
{
if ($items === []) {
return [];
}
$orderIds = [];
$tnByOrder = [];
$trackingNums = [];
foreach ($items as $it) {
if (!is_array($it)) {
continue;
}
$oid = (int) ($it['order_id'] ?? 0);
if ($oid <= 0) {
continue;
}
$orderIds[$oid] = true;
$tn = trim((string) ($it['tracking_number'] ?? ''));
$tnByOrder[$oid] = $tn;
if ($tn !== '') {
$trackingNums[$tn] = true;
}
}
$orderIds = array_keys($orderIds);
if ($orderIds === []) {
return [];
}
$trackingById = [];
$orderToTrackingIds = [];
$tnToTrackingIds = [];
$attachTrackingRow = static function (array $etRow) use (&$trackingById, &$orderToTrackingIds, &$tnToTrackingIds): void {
$tid = (int) ($etRow['id'] ?? 0);
if ($tid <= 0) {
return;
}
$trackingById[$tid] = $etRow;
$oid = (int) ($etRow['order_id'] ?? 0);
if ($oid > 0) {
$orderToTrackingIds[$oid][$tid] = true;
}
$tn = trim((string) ($etRow['tracking_number'] ?? ''));
if ($tn !== '') {
$tnToTrackingIds[$tn][$tid] = true;
}
};
foreach (array_chunk($orderIds, 800) as $chunk) {
$byOrderId = ExpressTracking::with(['traces' => static function ($query): void {
$query->order('trace_time_stamp', 'desc');
}])
->whereIn('order_id', $chunk)
->whereNull('delete_time')
->select();
foreach ($byOrderId as $tracking) {
$row = $tracking->toArray();
$row['traces'] = $tracking->traces ? $tracking->traces->toArray() : [];
$attachTrackingRow($row);
}
}
$trackingNumList = array_keys($trackingNums);
if ($trackingNumList !== []) {
foreach (array_chunk($trackingNumList, 400) as $chunk) {
$byTn = ExpressTracking::with(['traces' => static function ($query): void {
$query->order('trace_time_stamp', 'desc');
}])
->whereRaw('TRIM(`tracking_number`) IN (' . implode(',', array_fill(0, count($chunk), '?')) . ')', $chunk)
->whereNull('delete_time')
->select();
foreach ($byTn as $tracking) {
$row = $tracking->toArray();
$row['traces'] = $tracking->traces ? $tracking->traces->toArray() : [];
$attachTrackingRow($row);
}
}
}
$out = [];
foreach ($orderIds as $oid) {
$oid = (int) $oid;
$candidateIds = [];
foreach (array_keys($orderToTrackingIds[$oid] ?? []) as $tid) {
$candidateIds[(int) $tid] = true;
}
$tn = $tnByOrder[$oid] ?? '';
if ($tn !== '') {
foreach (array_keys($tnToTrackingIds[$tn] ?? []) as $tid) {
$candidateIds[(int) $tid] = true;
}
}
$best = 0;
foreach (array_keys($candidateIds) as $tid) {
$detail = $trackingById[(int) $tid] ?? null;
if (!is_array($detail)) {
continue;
}
$best = max($best, self::effectiveSignUnixFromTrackingDetail($detail));
}
if ($best > 0) {
$out[$oid] = $best;
}
}
return $out;
}
}