$materialCodes * @return array{ * unique:array, * ambiguous:array>, * missing:list, * source_rows:int * } */ public function resolve(array $materialCodes, ?UpstreamReadOnlyQuery $query = null): array { $normalized = []; foreach ($materialCodes as $code) { $materialCode = self::normalizeMaterialCode((string) $code); if ($materialCode !== null) { $normalized[$materialCode] = true; } } $materialCodes = array_keys($normalized); sort($materialCodes, SORT_STRING); if ($materialCodes === []) { return [ 'unique' => [], 'ambiguous' => [], 'missing' => [], 'source_rows' => 0, ]; } $query ??= new UpstreamReadOnlyQuery(self::SOURCE_KEY, 15); $candidates = []; $sourceRows = 0; try { foreach (array_chunk($materialCodes, 200) as $chunk) { $placeholders = implode(', ', array_fill(0, count($chunk), '?')); $rows = $query->select( 'WITH material_skus AS (' . 'SELECT DISTINCT ' . "TRIM(updates->>'materialNo') AS material_no, " . 'COALESCE(NULLIF(BTRIM("normalizedSku"), \'\'), NULLIF(BTRIM("skuCode"), \'\')) AS sku_code ' . 'FROM public."BarcodePrintImportRecord" ' . "WHERE TRIM(updates->>'materialNo') IN ({$placeholders}) " . 'AND COALESCE(NULLIF(BTRIM("normalizedSku"), \'\'), NULLIF(BTRIM("skuCode"), \'\')) IS NOT NULL' . '), barcode_matches AS (' . 'SELECT DISTINCT material_skus.material_no, ' . "NULLIF(BTRIM(product_rows.updates->>'barcode'), '') AS barcode " . 'FROM material_skus ' . 'JOIN public."BarcodePrintImportRecord" product_rows ' . 'ON COALESCE(NULLIF(BTRIM(product_rows."normalizedSku"), \'\'), ' . 'NULLIF(BTRIM(product_rows."skuCode"), \'\')) = material_skus.sku_code ' . "WHERE NULLIF(BTRIM(product_rows.updates->>'barcode'), '') IS NOT NULL" . ') ' . 'SELECT barcode_matches.material_no, barcode_matches.barcode AS mapped_sku ' . 'FROM barcode_matches ' . 'UNION ' . 'SELECT material_skus.material_no, material_skus.sku_code ' . 'FROM material_skus ' . 'WHERE NOT EXISTS (' . 'SELECT 1 FROM barcode_matches ' . 'WHERE barcode_matches.material_no = material_skus.material_no' . ')', $chunk, ); foreach ($rows as $row) { $sourceRows++; $materialCode = self::normalizeMaterialCode((string) ($row['material_no'] ?? '')); $mappedSku = mb_strtoupper(trim((string) ($row['mapped_sku'] ?? ''))); if ($materialCode === null || $mappedSku === '') { continue; } $candidates[$materialCode][$mappedSku] = true; } } } catch (Throwable $exception) { throw new RuntimeException( '91 基础料号条码映射读取失败,请检查商品条码映射库只读连接:' . $exception->getMessage(), 0, $exception, ); } $unique = []; $ambiguous = []; $missing = []; foreach ($materialCodes as $materialCode) { $mappedSkus = array_keys($candidates[$materialCode] ?? []); sort($mappedSkus, SORT_STRING); if (count($mappedSkus) === 1) { $unique[$materialCode] = $mappedSkus[0]; } elseif (count($mappedSkus) > 1) { $ambiguous[$materialCode] = $mappedSkus; } else { $missing[] = $materialCode; } } return [ 'unique' => $unique, 'ambiguous' => $ambiguous, 'missing' => $missing, 'source_rows' => $sourceRows, ]; } }