UrsUpdateActiveStatusCommand.php 8.1 KB

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