setName('user:generate-api-key') ->setDescription('批量为 ck_users 用户生成对外 API Key') ->addOption('force', 'f', Option::VALUE_NONE, '强制覆盖所有用户(包括已有 apiKey 的用户),危险!') ->addOption('dry-run', null, Option::VALUE_NONE, '预览模式,不实际写入数据库'); } protected function execute(Input $input, Output $output) { $force = (bool)$input->getOption('force'); $dryRun = (bool)$input->getOption('dry-run'); $output->writeln('========================================'); $output->writeln(' 批量生成用户 API Key'); $output->writeln('========================================'); if ($dryRun) { $output->writeln('[预览模式] 不会实际写入数据库'); } if ($force) { $output->writeln('[FORCE] 将覆盖已有 apiKey 的用户'); } $output->writeln(''); // 查询目标用户 $query = Db::name('users') ->where('deleteTime', 0) ->field('id, account, phone, apiKey'); if (!$force) { // 默认只处理 apiKey 为空或 NULL 的记录 $query->where(function ($q) { $q->where('apiKey', null) ->whereOr('apiKey', ''); }); } $users = $query->select(); $total = count($users); $success = 0; $skip = 0; $output->writeln("共找到 {$total} 个需要处理的用户"); $output->writeln(''); if ($total === 0) { $output->writeln('所有用户均已有 API Key,无需处理。'); return true; } foreach ($users as $user) { $uid = (int)$user['id']; $label = "用户 #{$uid} ({$user['account']}/{$user['phone']})"; try { if ($dryRun) { $output->writeln("[预览] 将为 {$label} 生成 apiKey"); $success++; continue; } if ($force) { $apiKey = UserApiKeyService::forceGenerate($uid); } else { $apiKey = UserApiKeyService::bindOrGet($uid); } $output->writeln("√ {$label} => {$apiKey}"); $success++; } catch (\Exception $e) { $output->writeln("✗ {$label} 失败:{$e->getMessage()}"); $skip++; } } $output->writeln(''); $output->writeln('========================================'); $output->writeln(" 完成:成功 {$success} 个,跳过/失败 {$skip} 个"); $output->writeln('========================================'); if ($dryRun) { $output->writeln('预览模式:未实际写入任何数据'); } return true; } }