option('notify'); $dryRun = (bool) $this->option('dry-run'); if ($this->option('user')) { $user = $this->resolveUser((string) $this->option('user')); if (! $user) { $this->error('未找到指定用户。'); return self::FAILURE; } $result = $this->achievementService->scanUser($user, $notify, $dryRun); $this->info("已扫描用户 {$user->username}:检查 {$result['checked']} 项,解锁 {$result['unlocked']} 项,更新 {$result['updated']} 项。"); return self::SUCCESS; } $query = User::query()->orderBy('id'); if (! $this->option('all')) { // 默认只扫最近活跃用户,避免定时任务每次全表扫描。 $query->where('updated_at', '>=', now()->subDay())->limit(200); } $summary = ['users' => 0, 'checked' => 0, 'unlocked' => 0, 'updated' => 0, 'dry_run' => $dryRun]; $query->chunkById(100, function ($users) use (&$summary, $notify, $dryRun): void { $chunkSummary = $this->achievementService->scanUsers($users, $notify, $dryRun); $summary['users'] += $chunkSummary['users']; $summary['checked'] += $chunkSummary['checked']; $summary['unlocked'] += $chunkSummary['unlocked']; $summary['updated'] += $chunkSummary['updated']; }); $this->info("成就扫描完成:用户 {$summary['users']} 人,检查 {$summary['checked']} 项,解锁 {$summary['unlocked']} 项,更新 {$summary['updated']} 项。"); return self::SUCCESS; } /** * 根据 ID 或用户名解析用户。 */ private function resolveUser(string $value): ?User { return User::query() ->when(is_numeric($value), fn ($query) => $query->where('id', (int) $value), fn ($query) => $query->where('username', $value)) ->first(); } }