where('role', 'venue_admin') ->orderBy('id') ->get(['id', 'username', 'name']); if ($users->isEmpty()) { $this->warn('没有 role=venue_admin 的账号。'); return self::SUCCESS; } $this->info('将处理 '.$users->count().' 个场馆管理员账号。'); $dryRun = (bool) $this->option('dry-run'); if ($dryRun) { foreach ($users as $user) { $this->line($user->id."\t".$user->username); } $this->warn('当前为 --dry-run:未改密码、未失效 token、未导出。去掉 --dry-run 才会写入。'); return self::SUCCESS; } $rows = []; DB::transaction(function () use ($users, &$rows) { foreach ($users as $user) { $plainPassword = VenueAdminCredentials::randomPassword(); $user->password = $plainPassword; $user->save(); $user->tokens()->delete(); $rows[] = [ 'id' => $user->id, 'name' => (string) $user->name, 'username' => (string) $user->username, 'password_plain' => $plainPassword, ]; } }); $defaultDir = storage_path('app/exports'); if (! is_dir($defaultDir)) { mkdir($defaultDir, 0755, true); } $outPath = $this->option('output'); if (! $outPath) { $outPath = $defaultDir.'/venue_admin_password_reset_'.now()->format('Ymd_His').'.xlsx'; } elseif (! str_starts_with((string) $outPath, '/')) { $outPath = base_path($outPath); } $this->writeXlsx((string) $outPath, $rows); $this->info('已重置 '.$users->count().' 个场馆管理员密码,并作废其现有 token。'); $this->info('Excel 已生成(请安全交给运营,不要提交到 git):'.$outPath); return self::SUCCESS; } /** * @param array $rows */ private function writeXlsx(string $path, array $rows): void { $sheetRows = [ ['用户ID', '姓名', '用户名', '新密码(明文)'], ]; foreach ($rows as $r) { $sheetRows[] = [ $r['id'], $r['name'], $r['username'], $r['password_plain'], ]; } $spreadsheet = new Spreadsheet; $sheet = $spreadsheet->getActiveSheet(); $sheet->setTitle('场馆管理员新密码'); $sheet->fromArray($sheetRows, null, 'A1'); $writer = new Xlsx($spreadsheet); $writer->save($path); } }