AutoStatisticsUserDailyTraffic.php 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Models\Node;
  4. use App\Models\User;
  5. use App\Models\UserDailyDataFlow;
  6. use App\Models\UserDataFlowLog;
  7. use Illuminate\Console\Command;
  8. use Log;
  9. class AutoStatisticsUserDailyTraffic extends Command
  10. {
  11. protected $signature = 'autoStatisticsUserDailyTraffic';
  12. protected $description = '自动统计用户每日流量';
  13. public function handle(): void
  14. {
  15. $jobStartTime = microtime(true);
  16. $today = date('Y-m-d');
  17. $startTime = strtotime($today);
  18. $endTime = time();
  19. try {
  20. // 缓存用户和节点存在性检查
  21. $checkedUsers = [];
  22. $checkedNodes = [];
  23. // 直接遍历 UserDataFlowLog 表
  24. UserDataFlowLog::whereBetween('log_time', [$startTime, $endTime])
  25. ->select('user_id', 'node_id')
  26. ->selectRaw('SUM(u) as total_u, SUM(d) as total_d')
  27. ->groupBy('user_id', 'node_id')
  28. ->chunk(100, function ($logs) use ($checkedUsers, $checkedNodes, $today) {
  29. foreach ($logs as $log) {
  30. try {
  31. // 检查用户是否存在
  32. if (!isset($checkedUsers[$log->user_id])) {
  33. $checkedUsers[$log->user_id] = User::where('id', $log->user_id)->exists();
  34. }
  35. if (!$checkedUsers[$log->user_id]) {
  36. Log::warning("跳过记录,用户不存在: user_id={$log->user_id}");
  37. continue;
  38. }
  39. // 检查节点是否存在(如果node_id不为null)
  40. if ($log->node_id !== null) {
  41. if (!isset($checkedNodes[$log->node_id])) {
  42. $checkedNodes[$log->node_id] = Node::where('id', $log->node_id)->exists();
  43. }
  44. if (!$checkedNodes[$log->node_id]) {
  45. Log::warning("跳过记录,节点不存在: node_id={$log->node_id}");
  46. continue;
  47. }
  48. }
  49. $total = $log->total_u + $log->total_d;
  50. if ($total > 0) {
  51. UserDailyDataFlow::updateOrCreate(
  52. [
  53. 'user_id' => $log->user_id,
  54. 'node_id' => $log->node_id,
  55. 'created_at' => $today
  56. ],
  57. [
  58. 'u' => $log->total_u,
  59. 'd' => $log->total_d,
  60. 'total' => $total,
  61. 'traffic' => flowAutoShow($total)
  62. ]
  63. );
  64. }
  65. } catch (\Exception $e) {
  66. Log::error('处理流量记录失败', [
  67. 'user_id' => $log->user_id,
  68. 'node_id' => $log->node_id,
  69. 'error' => $e->getMessage()
  70. ]);
  71. }
  72. }
  73. });
  74. $jobEndTime = microtime(true);
  75. $jobUsedTime = round(($jobEndTime - $jobStartTime), 4);
  76. Log::info('---【'.$this->description.'】完成---,耗时'.$jobUsedTime.'秒');
  77. } catch (\Exception $e) {
  78. Log::error('统计用户流量任务失败', [
  79. 'error' => $e->getMessage(),
  80. 'trace' => $e->getTraceAsString()
  81. ]);
  82. }
  83. }
  84. }