setName('ej-pharmacy:push-medicines') ->setDescription('非破坏性增量推送 ZYT 药材到恩济药房;保留双方已有药材') ->addOption('apply', null, Option::VALUE_NONE, '执行远端增量导入;缺省仅做 dry-run') ->addOption('confirm', null, Option::VALUE_OPTIONAL, '增量写入确认令牌:INCREMENTAL_NO_DELETE', '') ->addOption('batch-size', null, Option::VALUE_OPTIONAL, '每批药材数量(1-500)', 100) ->addOption('run-id', null, Option::VALUE_OPTIONAL, '幂等运行标识(缺省 zyt-incremental,最长 25 位)', ''); } protected function execute(Input $input, Output $output) { try { $apply = (bool) $input->getOption('apply'); $confirm = (string) $input->getOption('confirm'); $batchSize = (int) $input->getOption('batch-size'); EjMedicineIncrementalPushService::assertCommandGate($apply, $confirm, $batchSize); if (!$apply) { $plan = EjMedicineIncrementalPushService::plan($batchSize); $output->writeln(sprintf( 'dry-run source=%d candidates=%d batches=%d mapped=%d unmapped=%d ' . 'preserved_inactive=%d remote_delete=0 local_delete=0', $plan['source_count'], $plan['candidate_count'], $plan['batch_count'], $plan['mapped_count'], $plan['unmapped_count'], $plan['preserved_inactive'] )); return 0; } $result = EjMedicineIncrementalPushService::execute( $batchSize, (string) $input->getOption('run-id') ); $output->writeln(sprintf( 'incremental 完成 run_id=%s source=%d candidates=%d batches=%d ' . 'remote_created=%d remote_existing=%d preserved_inactive=%d ' . 'catalog_created=%d catalog_updated=%d mapping_created=%d mapping_updated=%d ' . 'mapping_unchanged=%d remote_delete=0 local_delete=0', $result['run_id'], $result['source_count'], $result['candidate_count'], $result['batch_count'], $result['remote_created'], $result['remote_existing'], $result['preserved_inactive'], $result['catalog_created'], $result['catalog_updated'], $result['mapping_created'], $result['mapping_updated'], $result['mapping_unchanged'] )); return 0; } catch (\Throwable $exception) { $output->error($exception->getMessage()); return 1; } } }