| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- <?php
- namespace App\Module\UrsPromotion\Commands;
- use App\Module\UrsPromotion\Logics\UrsRelationCacheLogic;
- use Illuminate\Console\Command;
- /**
- * URS用户关系缓存重建命令
- *
- * 用于批量重建URS用户关系缓存,提升查询性能
- *
- * 使用示例:
- * php artisan urs:rebuild-relation-cache # 重建所有用户缓存
- * php artisan urs:rebuild-relation-cache --check # 检查缓存完整性
- * php artisan urs:rebuild-relation-cache --fix # 修复发现的问题
- * php artisan urs:rebuild-relation-cache --user=123 # 重建指定用户缓存
- * php artisan urs:rebuild-relation-cache --users=123,456 # 重建多个用户缓存
- * php artisan urs:rebuild-relation-cache --user=123 --clear # 清除指定用户缓存
- */
- class UrsRebuildRelationCacheCommand extends Command
- {
- /**
- * 命令签名
- */
- protected $signature = 'urs:rebuild-relation-cache
- {--batch-size=100 : 批处理大小}
- {--check : 仅检查完整性,不重建}
- {--fix : 修复发现的问题}
- {--user= : 指定URS用户ID,仅处理该用户}
- {--users= : 指定多个URS用户ID,用逗号分隔}
- {--clear : 清除指定用户的缓存(需配合--user或--users使用)}';
- /**
- * 命令描述
- */
- protected $description = 'URS用户关系缓存重建命令,支持全量重建、指定用户处理、完整性检查和问题修复';
- /**
- * 执行命令
- */
- public function handle()
- {
- $logic = new UrsRelationCacheLogic();
- // 处理指定用户的缓存操作
- if ($this->option('user') || $this->option('users')) {
- return $this->handleSpecificUsers($logic);
- }
- // 仅检查完整性
- if ($this->option('check')) {
- $this->info('开始检查URS关系缓存完整性...');
- $result = $logic->checkRelationCacheIntegrity();
-
- if (isset($result['error'])) {
- $this->error('检查失败: ' . $result['error']);
- return 1;
- }
-
- $this->info('检查结果:');
- $this->table(['项目', '数量'], [
- ['总用户数', $result['total_users']],
- ['有缓存的用户数', $result['users_with_cache']],
- ['缺失缓存的用户数', $result['missing_users']],
- ['循环推荐关系数', $result['circular_relations']],
- ['孤立缓存数', $result['orphaned_caches']]
- ]);
-
- if ($result['missing_users'] > 0 || $result['orphaned_caches'] > 0) {
- $this->warn('发现问题,建议使用 --fix 参数修复');
- return 1;
- }
-
- $this->info('缓存完整性检查通过');
- return 0;
- }
-
- // 修复问题
- if ($this->option('fix')) {
- $this->info('开始修复URS关系缓存问题...');
- // 先检查需要修复的数量
- $integrity = $logic->checkRelationCacheIntegrity();
- $totalToFix = $integrity['missing_users'] + $integrity['orphaned_caches'];
- if ($totalToFix == 0) {
- $this->info('没有发现需要修复的问题');
- return 0;
- }
- $progressBar = $this->output->createProgressBar($totalToFix);
- $progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% - %message%');
- $progressBar->setMessage('准备修复...');
- $progressBar->start();
- $currentProgress = 0;
- // 定义进度回调函数
- $progressCallback = function($type, $ursUserId, $processed, $total, $fixed) use ($progressBar, &$currentProgress) {
- $currentProgress++;
- $typeText = $type === 'missing' ? '修复缺失缓存' : '清理孤立缓存';
- $progressBar->setMessage("{$typeText} - URS用户ID: {$ursUserId} (已修复: {$fixed})");
- $progressBar->setProgress($currentProgress);
- };
- $result = $logic->fixRelationCacheIssues($progressCallback);
- $progressBar->finish();
- $this->newLine();
- if (isset($result['error'])) {
- $this->error('修复失败: ' . $result['error']);
- return 1;
- }
- $this->info('修复结果:');
- $this->table(['项目', '修复数量'], [
- ['缺失用户缓存', $result['fixed']['missing_users']],
- ['孤立缓存清理', $result['fixed']['orphaned_caches']]
- ]);
- $this->info('问题修复完成');
- return 0;
- }
-
- // 重建所有缓存
- $batchSize = (int) $this->option('batch-size');
-
- if (!$this->confirm('确定要重建所有URS用户关系缓存吗?这将清空现有缓存并重新生成。')) {
- $this->info('操作已取消');
- return 0;
- }
-
- $this->info("开始重建URS关系缓存,批处理大小: {$batchSize}");
- // 先获取总用户数用于进度条初始化
- $totalUsers = \App\Module\UrsPromotion\Models\UrsUserReferral::where('status', \App\Module\UrsPromotion\Models\UrsUserReferral::STATUS_VALID)->count();
- $progressBar = $this->output->createProgressBar($totalUsers);
- $progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% - 当前用户ID: %message%');
- $progressBar->setMessage('准备开始...');
- $progressBar->start();
- // 定义进度回调函数
- $progressCallback = function($ursUserId, $processedCount, $totalUsers, $successCount, $failCount) use ($progressBar) {
- $progressBar->setMessage("URS用户ID: {$ursUserId} (成功: {$successCount}, 失败: {$failCount})");
- $progressBar->setProgress($processedCount);
- };
- $result = $logic->rebuildAllRelationCache($batchSize, $progressCallback);
- $progressBar->finish();
- $this->newLine();
-
- if (isset($result['error'])) {
- $this->error('重建失败: ' . $result['error']);
- return 1;
- }
-
- $this->info('重建完成:');
- $this->table(['项目', '数量'], [
- ['总用户数', $result['total']],
- ['成功数', $result['success']],
- ['失败数', $result['fail']]
- ]);
-
- if ($result['fail'] > 0) {
- $this->warn('部分用户缓存生成失败,请检查日志');
- return 1;
- }
-
- $this->info('所有URS用户关系缓存重建完成');
- return 0;
- }
- /**
- * 处理指定用户的缓存操作
- *
- * @param UrsRelationCacheLogic $logic
- * @return int
- */
- private function handleSpecificUsers(UrsRelationCacheLogic $logic): int
- {
- // 获取用户ID列表
- $userIds = $this->getSpecifiedUserIds();
- if (empty($userIds)) {
- $this->error('未指定有效的用户ID');
- return 1;
- }
- $this->info('指定处理的URS用户ID: ' . implode(', ', $userIds));
- // 验证用户ID是否存在
- $validUserIds = $this->validateUserIds($userIds);
- if (empty($validUserIds)) {
- $this->error('所有指定的用户ID都无效');
- return 1;
- }
- if (count($validUserIds) < count($userIds)) {
- $invalidIds = array_diff($userIds, $validUserIds);
- $this->warn('以下用户ID无效,将被跳过: ' . implode(', ', $invalidIds));
- }
- // 清除缓存操作
- if ($this->option('clear')) {
- return $this->clearSpecificUsersCache($logic, $validUserIds);
- }
- // 重建指定用户的缓存
- return $this->rebuildSpecificUsersCache($logic, $validUserIds);
- }
- /**
- * 获取指定的用户ID列表
- *
- * @return array
- */
- private function getSpecifiedUserIds(): array
- {
- $userIds = [];
- // 处理单个用户ID
- if ($this->option('user')) {
- $userId = (int) $this->option('user');
- if ($userId > 0) {
- $userIds[] = $userId;
- }
- }
- // 处理多个用户ID
- if ($this->option('users')) {
- $usersString = $this->option('users');
- $userIdStrings = explode(',', $usersString);
- foreach ($userIdStrings as $userIdString) {
- $userId = (int) trim($userIdString);
- if ($userId > 0 && !in_array($userId, $userIds)) {
- $userIds[] = $userId;
- }
- }
- }
- return $userIds;
- }
- /**
- * 验证用户ID是否存在于URS推荐关系中
- *
- * @param array $userIds
- * @return array
- */
- private function validateUserIds(array $userIds): array
- {
- return \App\Module\UrsPromotion\Models\UrsUserReferral::whereIn('urs_user_id', $userIds)
- ->where('status', \App\Module\UrsPromotion\Models\UrsUserReferral::STATUS_VALID)
- ->pluck('urs_user_id')
- ->toArray();
- }
- /**
- * 清除指定用户的缓存
- *
- * @param UrsRelationCacheLogic $logic
- * @param array $userIds
- * @return int
- */
- private function clearSpecificUsersCache(UrsRelationCacheLogic $logic, array $userIds): int
- {
- $this->info('开始清除指定用户的关系缓存...');
- $progressBar = $this->output->createProgressBar(count($userIds));
- $progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% - 当前用户ID: %message%');
- $progressBar->start();
- $successCount = 0;
- $failCount = 0;
- foreach ($userIds as $userId) {
- $progressBar->setMessage("URS用户ID: {$userId}");
- if ($logic->clearUserRelationCache($userId)) {
- $successCount++;
- } else {
- $failCount++;
- }
- $progressBar->advance();
- }
- $progressBar->finish();
- $this->newLine();
- $this->info('缓存清除完成:');
- $this->table(['项目', '数量'], [
- ['处理用户数', count($userIds)],
- ['成功数', $successCount],
- ['失败数', $failCount]
- ]);
- if ($failCount > 0) {
- $this->warn('部分用户缓存清除失败,请检查日志');
- return 1;
- }
- $this->info('指定用户关系缓存清除完成');
- return 0;
- }
- /**
- * 重建指定用户的缓存
- *
- * @param UrsRelationCacheLogic $logic
- * @param array $userIds
- * @return int
- */
- private function rebuildSpecificUsersCache(UrsRelationCacheLogic $logic, array $userIds): int
- {
- $this->info('开始重建指定用户的关系缓存...');
- $progressBar = $this->output->createProgressBar(count($userIds));
- $progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% - 当前用户ID: %message%');
- $progressBar->start();
- $successCount = 0;
- $failCount = 0;
- foreach ($userIds as $userId) {
- $progressBar->setMessage("URS用户ID: {$userId}");
- if ($logic->generateUserRelationCache($userId)) {
- $successCount++;
- } else {
- $failCount++;
- }
- $progressBar->advance();
- }
- $progressBar->finish();
- $this->newLine();
- $this->info('缓存重建完成:');
- $this->table(['项目', '数量'], [
- ['处理用户数', count($userIds)],
- ['成功数', $successCount],
- ['失败数', $failCount]
- ]);
- if ($failCount > 0) {
- $this->warn('部分用户缓存生成失败,请检查日志');
- return 1;
- }
- $this->info('指定用户关系缓存重建完成');
- return 0;
- }
- }
|