setName('shopro_huifu:import-bank-branch') ->setDescription('Import nationwide CNAPS bank branch codes into shopro_huifu_bank_branch') ->addOption('file', 'f', Option::VALUE_OPTIONAL, 'CSV/JSON source file path') ->addOption('download', 'd', Option::VALUE_NONE, 'Download gweesin/CNAPS cnaps.csv then import') ->addOption('seed', null, Option::VALUE_NONE, 'Import bundled data/bank_branches.json seed only') ->addOption('truncate', 't', Option::VALUE_NONE, 'Clear table before import') ->addOption('limit', 'l', Option::VALUE_OPTIONAL, 'Max rows to import (0=all)', 0) ->addOption('batch', 'b', Option::VALUE_OPTIONAL, 'Batch size', 500) ->addOption('format', null, Option::VALUE_OPTIONAL, 'Force format: csv|json|auto', 'auto') ->addOption('dry-run', null, Option::VALUE_NONE, 'Parse only, do not write DB') ->addOption('export-json', null, Option::VALUE_OPTIONAL, 'Export DB rows to JSON file path') ->addOption('export-limit', null, Option::VALUE_OPTIONAL, 'Max rows when exporting JSON', 0); } protected function execute(Input $input, Output $output) { $exportJson = trim((string) $input->getOption('export-json')); if ($exportJson !== '') { return $this->exportJson($output, $exportJson, (int) $input->getOption('export-limit')); } try { Db::execute('SELECT 1 FROM `' . config('database.prefix') . 'shopro_huifu_bank_branch` LIMIT 1'); } catch (\Throwable $e) { $output->writeln('表 shopro_huifu_bank_branch 不存在,正在自动创建 ...'); try { Installer::ensureBankBranchTable($output); Db::execute('SELECT 1 FROM `' . config('database.prefix') . 'shopro_huifu_bank_branch` LIMIT 1'); } catch (\Throwable $inner) { $output->error('创建 shopro_huifu_bank_branch 失败: ' . $inner->getMessage()); $output->writeln('也可手动执行: php think shopro_huifu:repair-menu'); return 1; } } $file = trim((string) $input->getOption('file')); $download = (bool) $input->getOption('download'); $seed = (bool) $input->getOption('seed'); if ($seed) { $file = ADDON_PATH . 'shopro_huifu/data/bank_branches.json'; } elseif ($download) { $output->writeln('正在下载全国联行号 CSV(约 20MB,来源 gweesin/CNAPS)...'); try { $file = HuifuOnboardBankBranchImporter::downloadCnapsCsv(); $output->writeln('已保存: ' . $file); } catch (\Throwable $e) { $output->error($e->getMessage()); $output->writeln('手动下载: https://hf-mirror.com/datasets/gweesin/CNAPS/resolve/main/cnaps.csv'); $output->writeln('然后执行: php think shopro_huifu:import-bank-branch --file=addons/shopro_huifu/data/cnaps.csv'); return 1; } } elseif ($file === '') { $defaultCsv = ADDON_PATH . 'shopro_huifu/data/cnaps.csv'; if (is_file($defaultCsv)) { $file = $defaultCsv; } else { $output->error('请指定 --file、--download 或 --seed'); $output->writeln('示例:'); $output->writeln(' php think shopro_huifu:import-bank-branch --seed'); $output->writeln(' php think shopro_huifu:import-bank-branch --download'); $output->writeln(' php think shopro_huifu:import-bank-branch --file=addons/shopro_huifu/data/cnaps.csv'); return 1; } } $options = [ 'truncate' => (bool) $input->getOption('truncate'), 'limit' => (int) $input->getOption('limit'), 'batch' => (int) $input->getOption('batch'), 'format' => (string) $input->getOption('format'), 'dry_run' => (bool) $input->getOption('dry-run'), ]; $output->writeln('导入文件: ' . $file); if ($options['dry_run']) { $output->writeln('[dry-run] 仅解析,不写入数据库'); } if ($options['truncate']) { $output->writeln('[truncate] 导入前清空旧数据'); } try { $stats = HuifuOnboardBankBranchImporter::importFile($file, $options); } catch (\Throwable $e) { $output->error($e->getMessage()); return 1; } $output->writeln(sprintf( '完成: 新增 %d,更新 %d,跳过 %d,有效 %d', $stats['inserted'], $stats['updated'], $stats['skipped'], $stats['total'] )); $count = Db::name('shopro_huifu_bank_branch')->where('status', 1)->count(); $output->writeln('当前库内有效支行: ' . $count); return 0; } protected function exportJson(Output $output, $dest, $limit) { try { $count = HuifuOnboardBankBranchImporter::exportJson($dest, $limit); } catch (\Throwable $e) { $output->error($e->getMessage()); return 1; } $output->writeln('已导出 ' . $count . ' 条到 ' . $dest); return 0; } }