UrsUpdateActiveStatusCommand.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. namespace App\Module\UrsPromotion\Commands;
  3. use App\Module\UrsPromotion\Services\UrsActiveUserService;
  4. use Illuminate\Console\Command;
  5. use Illuminate\Support\Facades\Log;
  6. /**
  7. * URS用户活跃状态更新命令
  8. *
  9. * 每日定时执行,更新所有URS用户的活跃状态
  10. */
  11. class UrsUpdateActiveStatusCommand extends Command
  12. {
  13. /**
  14. * 命令签名
  15. */
  16. protected $signature = 'urs:update-active-status
  17. {--limit=1000 : 每次处理的用户数量限制}
  18. {--reset : 重置所有用户活跃状态}
  19. {--dry-run : 仅显示统计信息,不执行更新}';
  20. /**
  21. * 命令描述
  22. */
  23. protected $description = 'Update URS users active status based on last activity time';
  24. /**
  25. * 执行命令
  26. */
  27. public function handle()
  28. {
  29. $this->info('开始执行URS用户活跃状态更新任务...');
  30. $startTime = microtime(true);
  31. try {
  32. // 检查是否为重置模式
  33. if ($this->option('reset')) {
  34. return $this->handleReset();
  35. }
  36. // 检查是否为试运行模式
  37. if ($this->option('dry-run')) {
  38. return $this->handleDryRun();
  39. }
  40. // 执行正常的活跃状态更新
  41. return $this->handleUpdate();
  42. } catch (\Exception $e) {
  43. $this->error('执行失败:' . $e->getMessage());
  44. Log::error('URS用户活跃状态更新命令执行失败', [
  45. 'error' => $e->getMessage(),
  46. 'trace' => $e->getTraceAsString()
  47. ]);
  48. return 1;
  49. } finally {
  50. $duration = round(microtime(true) - $startTime, 2);
  51. $this->info("任务执行完成,耗时:{$duration}秒");
  52. }
  53. }
  54. /**
  55. * 处理正常的活跃状态更新
  56. */
  57. protected function handleUpdate(): int
  58. {
  59. $limit = (int) $this->option('limit');
  60. $this->info("开始批量更新用户活跃状态(限制:{$limit})...");
  61. // 显示更新前的统计信息
  62. $beforeStats = UrsActiveUserService::getDetailedActiveStats();
  63. $this->displayStats('更新前统计', $beforeStats);
  64. // 执行批量更新
  65. $updateStats = UrsActiveUserService::batchUpdateActiveStatus($limit);
  66. $this->displayUpdateStats($updateStats);
  67. // 显示更新后的统计信息
  68. $afterStats = UrsActiveUserService::getDetailedActiveStats();
  69. $this->displayStats('更新后统计', $afterStats);
  70. // 记录执行日志
  71. Log::info('URS用户活跃状态更新任务完成', [
  72. 'before_stats' => $beforeStats,
  73. 'update_stats' => $updateStats,
  74. 'after_stats' => $afterStats
  75. ]);
  76. $this->info('✅ 活跃状态更新完成');
  77. return 0;
  78. }
  79. /**
  80. * 处理重置模式
  81. */
  82. protected function handleReset(): int
  83. {
  84. if (!$this->confirm('确定要重置所有用户的活跃状态吗?此操作不可逆!')) {
  85. $this->info('操作已取消');
  86. return 0;
  87. }
  88. $this->info('开始重置所有用户活跃状态...');
  89. $result = UrsActiveUserService::resetAllActiveStatus();
  90. if ($result['success']) {
  91. $this->info("✅ 重置完成,共更新 {$result['updated_count']} 个用户");
  92. Log::info('URS用户活跃状态重置完成', $result);
  93. } else {
  94. $this->error("❌ 重置失败:{$result['message']}");
  95. return 1;
  96. }
  97. return 0;
  98. }
  99. /**
  100. * 处理试运行模式
  101. */
  102. protected function handleDryRun(): int
  103. {
  104. $this->info('试运行模式:仅显示统计信息,不执行更新');
  105. $stats = UrsActiveUserService::getDetailedActiveStats();
  106. $this->displayStats('当前统计', $stats);
  107. // 显示需要检查的用户示例
  108. if ($stats['need_check_count'] > 0) {
  109. $this->info("\n需要检查活跃状态的用户示例:");
  110. $needCheckUsers = \App\Module\UrsPromotion\Models\UrsUserMapping::getUsersNeedActivityCheck(5);
  111. $headers = ['URS用户ID', '农场用户ID', '上次检查时间', '用户最后活动时间'];
  112. $rows = [];
  113. foreach ($needCheckUsers as $mapping) {
  114. $rows[] = [
  115. $mapping->urs_user_id,
  116. $mapping->user_id,
  117. $mapping->last_activity_check ? $mapping->last_activity_check->format('Y-m-d H:i:s') : '从未检查',
  118. $mapping->user && $mapping->user->last_activity_time
  119. ? $mapping->user->last_activity_time->format('Y-m-d H:i:s')
  120. : '无活动记录'
  121. ];
  122. }
  123. $this->table($headers, $rows);
  124. }
  125. return 0;
  126. }
  127. /**
  128. * 显示统计信息
  129. */
  130. protected function displayStats(string $title, array $stats): void
  131. {
  132. $this->info("\n📊 {$title}:");
  133. $this->line("总用户数:{$stats['total_users']}");
  134. $this->line("活跃用户:{$stats['active_users']}");
  135. $this->line("不活跃用户:{$stats['inactive_users']}");
  136. $this->line("活跃比例:{$stats['active_percentage']}%");
  137. if (isset($stats['recent_updates'])) {
  138. $this->line("最近24小时更新:{$stats['recent_updates']}");
  139. }
  140. if (isset($stats['need_check_count'])) {
  141. $this->line("需要检查的用户:{$stats['need_check_count']}");
  142. }
  143. if (isset($stats['last_update_time'])) {
  144. $lastUpdate = $stats['last_update_time']
  145. ? \Carbon\Carbon::parse($stats['last_update_time'])->format('Y-m-d H:i:s')
  146. : '从未更新';
  147. $this->line("最后更新时间:{$lastUpdate}");
  148. }
  149. }
  150. /**
  151. * 显示更新统计信息
  152. */
  153. protected function displayUpdateStats(array $stats): void
  154. {
  155. $this->info("\n🔄 更新统计:");
  156. $this->line("处理总数:{$stats['total_processed']}");
  157. $this->line("成功更新:{$stats['successful_updates']}");
  158. $this->line("失败数量:{$stats['failed_updates']}");
  159. $this->line("新增活跃:{$stats['active_users']}");
  160. $this->line("新增不活跃:{$stats['inactive_users']}");
  161. if ($stats['failed_updates'] > 0) {
  162. $this->warn("⚠️ 有 {$stats['failed_updates']} 个用户更新失败,请检查日志");
  163. }
  164. }
  165. /**
  166. * 获取命令帮助信息
  167. */
  168. public function getHelp(): string
  169. {
  170. return <<<HELP
  171. URS用户活跃状态更新命令
  172. 用法:
  173. php artisan urs:update-active-status [选项]
  174. 选项:
  175. --limit=1000 每次处理的用户数量限制(默认1000)
  176. --reset 重置所有用户活跃状态
  177. --dry-run 仅显示统计信息,不执行更新
  178. 示例:
  179. php artisan urs:update-active-status # 正常更新
  180. php artisan urs:update-active-status --limit=500 # 限制处理500个用户
  181. php artisan urs:update-active-status --dry-run # 试运行模式
  182. php artisan urs:update-active-status --reset # 重置所有状态
  183. 说明:
  184. - 活跃用户定义:最近15天有活动的用户
  185. - 建议每日凌晨执行此命令
  186. - 可以通过crontab设置定时任务:0 2 * * * php artisan urs:update-active-status
  187. HELP;
  188. }
  189. }