> */ public function shipmentsFor(array $rows): array { if ($rows === []) return []; $db = DB::connection((string) config('jushuitan.connection', 'jushuitan_local')); if (!Schema::connection($db->getName())->hasTable('jst_oms_shipping')) { throw new RuntimeException('发货数据尚未就绪'); } $from = null; $to = null; $tracking = []; $orders = []; foreach ($rows as $row) { [$start, $end] = self::window($row); $from = $from === null || $start < $from ? $start : $from; $to = $to === null || $end > $to ? $end : $to; $numbers = self::numbers($row['tracking_no'] ?? ''); if ($numbers !== []) { array_push($tracking, ...$numbers); } else { array_push($orders, ...self::numbers($row['online_order_no'] ?? '')); } } $found = []; // 使用现有快递单号/交易单号索引分批定点读取,不扫描六个月全量发货数据。 foreach (['express_no' => $tracking, 'trade_no' => $orders] as $column => $values) { foreach (array_chunk(array_values(array_unique($values)), 150) as $chunk) { $query = $db->table('jst_oms_shipping')->whereIn($column, $chunk) ->where('ship_time', '>=', $from)->where('ship_time', '<', $to) ->select(['id', 'source_id', 'express_no', 'trade_no', 'barcode', 'qty', 'freight', 'ship_time']) ->orderBy('id'); foreach ($query->lazyById(500) as $record) { $found[$record->id] = (array) $record; } } } return array_values($found); } /** @return array 规范化 SKU => 当前商品资料成本单价 */ public function costsFor(array $skus): array { if ($skus === []) return []; $dataset = $this->datasets->get(ProductCatalogMirrorRepository::DATASET_KEY); if (!$this->mirror->ready($dataset)) { throw new RuntimeException('商品资料尚未完成首次同步'); } $db = $this->mirror->connection(); $table = $dataset->targetTable(); $values = []; foreach ($skus as $sku) { $normalized = self::sku($sku); foreach ([$normalized, mb_strtolower($normalized), str_replace('+', '_X002B_', $normalized)] as $value) { if ($value !== '') $values[$value] = true; } } $result = []; $latest = []; $exclusions = Schema::connection($db->getName())->hasTable('product_catalog_exclusions'); foreach (array_chunk(array_keys($values), 150) as $chunk) { $query = $db->table($table)->where('sku_type', 'normal')->whereIn('sku_id', $chunk); if ($exclusions) { $query->whereNotExists(static function ($q) use ($table): void { $q->selectRaw('1')->from('product_catalog_exclusions AS e') ->whereColumn('e.mirror_key', $table . '._mirror_key') ->whereRaw("e.sku_id_normalized = REPLACE(UPPER(TRIM({$table}.sku_id)), '_X002B_', '+')"); }); } foreach ($query->orderByDesc('autoid')->get(['autoid', 'sku_id', 'cost_price']) as $record) { $key = self::sku($record->sku_id); if (!isset($latest[$key]) || (int) $record->autoid > $latest[$key]) { $latest[$key] = (int) $record->autoid; $result[$key] = $record->cost_price === null ? null : (string) $record->cost_price; } } } return $result; } /** 记账所在月份及前五个月,右端为下月1日(不含)。 */ public static function window(array $row): array { $month = Carbon::parse((string) $row['started_at'])->startOfMonth(); return [$month->copy()->subMonthsNoOverflow(5)->format('Y-m-d H:i:s'), $month->addMonth()->format('Y-m-d H:i:s')]; } public static function numbers(mixed $value): array { return array_values(array_unique(array_filter(array_map('trim', preg_split('/[\r\n,,、;;]+/u', (string) $value) ?: []), static fn ($v) => $v !== ''))); } public static function sku(mixed $value): string { return str_replace('_X002B_', '+', mb_strtoupper(trim((string) $value))); } }