PointsDailyStatsCommand.php 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Services\PointsStatsService;
  4. use Illuminate\Console\Command;
  5. class PointsDailyStatsCommand extends Command
  6. {
  7. protected $signature = 'stats:points-daily
  8. {--date= : 统计指定日期 Y-m-d,默认昨天}
  9. {--from= : 批量补跑起始日期 Y-m-d}
  10. {--to= : 批量补跑结束日期 Y-m-d,需与 --from 同用}';
  11. protected $description = '按日聚合积分消耗与token用量统计';
  12. public function handle(PointsStatsService $service)
  13. {
  14. $from = $this->option('from');
  15. $to = $this->option('to');
  16. $date = $this->option('date');
  17. dLog('command')->info('开始统计积分消耗与token用量', [
  18. 'date' => $date ?: null,
  19. 'from' => $from ?: null,
  20. 'to' => $to ?: null,
  21. ]);
  22. if ($from && $to) {
  23. $dates = $this->dateRange($from, $to);
  24. } elseif ($date) {
  25. $dates = [$date];
  26. } elseif ($from || $to) {
  27. dLog('command')->warning('--from 与 --to 必须同时提供', ['from' => $from, 'to' => $to]);
  28. $this->error('--from 与 --to 必须同时提供');
  29. return 1;
  30. } else {
  31. $dates = [date('Y-m-d', strtotime('-1 day'))];
  32. }
  33. $total = 0;
  34. try {
  35. foreach ($dates as $d) {
  36. if (!$this->validDate($d)) {
  37. dLog('command')->error('无效日期,终止统计', ['date' => $d]);
  38. $this->error("无效日期: {$d}");
  39. return 1;
  40. }
  41. $count = $service->statsForDate($d);
  42. $total += $count;
  43. dLog('command')->info('日期统计完成', ['date' => $d, 'rows' => $count]);
  44. $this->info("{$d} 写入 {$count} 行");
  45. }
  46. } catch (\Throwable $e) {
  47. dLog('command')->error('积分token日统计失败', [
  48. 'error' => $e->getMessage(),
  49. 'trace' => $e->getTraceAsString(),
  50. ]);
  51. $this->error('统计失败: ' . $e->getMessage());
  52. return 1;
  53. }
  54. dLog('command')->info('积分token日统计完成', ['dates' => count($dates), 'total_rows' => $total]);
  55. $this->info("完成,共写入 {$total} 行");
  56. return 0;
  57. }
  58. private function validDate(string $date): bool
  59. {
  60. $parts = explode('-', $date);
  61. if (count($parts) !== 3) {
  62. return false;
  63. }
  64. [$year, $month, $day] = array_map('intval', $parts);
  65. return checkdate($month, $day, $year);
  66. }
  67. private function dateRange(string $from, string $to): array
  68. {
  69. $dates = [];
  70. $cursor = strtotime($from);
  71. $end = strtotime($to);
  72. while ($cursor <= $end) {
  73. $dates[] = date('Y-m-d', $cursor);
  74. $cursor = strtotime('+1 day', $cursor);
  75. }
  76. return $dates;
  77. }
  78. }