2 && (int) $decimal[2] >= 5 ? 1 : 0); } public function match(array $accessories, iterable $originals): array { $index = []; foreach ($originals as $original) { if (trim((string) ($original['warehouse_name'] ?? '')) === self::WAREHOUSE || trim((string) ($original['express_no'] ?? '')) === '') continue; $trade = trim((string) ($original['trade_no'] ?? '')); if ($trade === '') continue; foreach (explode(',', (string) ($original['barcode'] ?? '')) as $barcode) { $barcode = trim($barcode); if ($barcode === '') continue; $key = json_encode([$trade, $barcode]); $identity = json_encode([$original['express_no'], $original['express_name1'] ?? '', substr((string) $original['ship_time'], 0, 7)]); $index[$key][$identity] = [ 'express_no' => $original['express_no'], 'courier' => ($original['express_name1'] ?? '') ?: ($original['express_name2'] ?? ''), 'month' => substr((string) $original['ship_time'], 0, 7), ]; } } $result = []; foreach ($accessories as $row) { $barcode = self::barcode((string) ($row['barcode'] ?? '')); $trade = trim((string) ($row['trade_no'] ?? '')); $matches = ($barcode !== '' && $trade !== '') ? array_values($index[json_encode([$trade, $barcode])] ?? []) : []; $row['normalized_barcode'] = $barcode; $row['matches'] = $matches; $row['status'] = $matches === [] ? 'unmatched' : 'matched'; $row['freight_cents'] = self::cents($row['freight'] ?? null); // 多候选仍属于可扣款;保持一条补发记录,运费不随候选数量放大。 $row['deduction_cents'] = $matches === [] ? 0 : $row['freight_cents']; $result[] = $row; } return $result; } }