argument('path'); if (! is_file($path)) { $this->error('文件不存在:' . $path); return self::FAILURE; } $companyId = (int) ($this->option('company') ?: (function_exists('company_id') && company_id() ? company_id() : 1)); if ($companyId <= 0) { $this->error('公司ID无效,请用 --company 指定。'); return self::FAILURE; } try { $rows = $this->readRows($path); } catch (Throwable $e) { $this->error('读取失败:' . $e->getMessage()); return self::FAILURE; } if ($rows === []) { $this->error('没有解析到有效数据(需要表头:标签 / 是否种菜订单)。'); return self::FAILURE; } $now = now(); DB::transaction(function () use ($rows, $now, $companyId): void { if ($this->option('replace')) { DB::table('jst_order_label_planting_rules')->where('company_id', $companyId)->delete(); } foreach (array_chunk($rows, 500) as $chunk) { DB::table('jst_order_label_planting_rules')->upsert( array_map(static fn (array $row): array => $row + [ 'company_id' => $companyId, 'created_at' => $now, 'updated_at' => $now, ], $chunk), ['company_id', 'label'], ['is_planting', 'updated_at'], ); } }); $rules->forget($companyId); $planting = count(array_filter($rows, static fn (array $row): bool => $row['is_planting'] === '是')); $this->info(sprintf('已导入 %d 条「是否种菜订单」映射(公司 %d):种菜 %d 条,非种菜 %d 条。', count($rows), $companyId, $planting, count($rows) - $planting)); return self::SUCCESS; } /** * @return list */ private function readRows(string $path): array { $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION)); $readerType = match ($extension) { 'xlsx' => 'Xlsx', 'xls' => 'Xls', 'csv' => 'Csv', default => throw new \InvalidArgumentException('只支持 xlsx / xls / csv 文件。'), }; $reader = IOFactory::createReader($readerType); $reader->setReadDataOnly(true); if ($readerType === 'Csv') { $reader->setInputEncoding('UTF-8'); } $book = $reader->load($path); $sheetOption = trim((string) $this->option('sheet')); if ($sheetOption !== '' && ctype_digit($sheetOption)) { $index = (int) $sheetOption - 1; if ($index < 0 || $index >= $book->getSheetCount()) { throw new \InvalidArgumentException('工作表序号超出范围:' . $sheetOption); } $sheet = $book->getSheet($index); } else { $sheet = $sheetOption === '' ? $book->getActiveSheet() : $book->getSheetByName($sheetOption); if ($sheet === null) { throw new \InvalidArgumentException('找不到工作表:' . $sheetOption); } } $rows = []; $header = null; foreach ($sheet->getRowIterator() as $row) { $cells = []; $cellIterator = $row->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(false); foreach ($cellIterator as $cell) { $cells[] = trim((string) $cell->getValue()); } if ($header === null) { $cells[0] = preg_replace('/^\xEF\xBB\xBF/', '', $cells[0] ?? ''); $header = $cells; continue; } $label = trim($cells[0] ?? ''); $flag = trim($cells[1] ?? ''); if ($label === '') { continue; } $rows[] = [ 'label' => mb_substr($label, 0, 191), 'is_planting' => in_array(mb_strtolower($flag), ['否', 'n', 'no', '0', 'false'], true) ? '否' : '是', ]; } return $rows; } }