| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- <?php
- namespace App\Console\Commands;
- use App\Services\QuestionBulkImportService;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\File;
- class QuestionsImportCommand extends Command
- {
- protected $signature = 'questions:import
- {file : JSON 文件路径(UTF-8,支持整段数组或 NDJSON 每行一题)}
- {--dry-run : 仅校验与统计,不写 MySQL}
- {--sql-only : 只生成 SQL 脚本,不写入本地 questions 表}
- {--output= : SQL 输出路径;默认 storage/app/exports/questions_import_YYYYMMDDHHmmss.sql}
- {--with-id : SQL 中含 id 列(需目标表结构与 id 不冲突;默认不含 id,按 question_code 去重)}';
- protected $description = '从 JSON 批量导入 questions,并生成可复制到服务器 MySQL 的 INSERT…ON DUPLICATE KEY UPDATE 脚本';
- public function handle(QuestionBulkImportService $service): int
- {
- $path = $this->argument('file');
- if (! is_string($path) || ! File::isFile($path)) {
- $this->error('文件不存在:'.$path);
- return self::FAILURE;
- }
- try {
- $rawRows = $service->loadRowsFromFile($path);
- } catch (\Throwable $e) {
- $this->error($e->getMessage());
- return self::FAILURE;
- }
- if ($rawRows === []) {
- $this->warn('未解析到任何题目行。');
- return self::FAILURE;
- }
- $rows = [];
- foreach ($rawRows as $i => $raw) {
- if (! is_array($raw)) {
- continue;
- }
- $rows[] = $service->normalizeImportRow($raw, $i + 1);
- }
- $includeId = (bool) $this->option('with-id');
- $sql = $service->renderMysqlScript($rows, $includeId);
- $outPath = $this->option('output');
- if (! is_string($outPath) || $outPath === '') {
- $outPath = storage_path('app/exports/questions_import_'.date('YmdHis').'.sql');
- }
- File::ensureDirectoryExists(dirname($outPath));
- File::put($outPath, $sql);
- $this->info('SQL 已写入:'.$outPath);
- $dryRun = (bool) $this->option('dry-run');
- $sqlOnly = (bool) $this->option('sql-only');
- if ($sqlOnly) {
- $this->line('已使用 --sql-only,未写入本地 questions 表。');
- return self::SUCCESS;
- }
- $result = $service->importToDatabase($rows, $dryRun);
- $this->info(sprintf(
- '本地库:新建 %d 条,更新 %d 条,跳过 %d 条(dry-run=%s)',
- $result['created'],
- $result['updated'],
- $result['skipped'],
- $dryRun ? 'true' : 'false'
- ));
- foreach ($result['errors'] as $err) {
- $this->warn($err);
- }
- return self::SUCCESS;
- }
- }
|