Files
coruna-lab/app/Console/Commands/DailyStatsCommand.php
T
2026-09-14 01:09:01 +08:00

70 lines
2.0 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Services\DailyReportService;
use Carbon\Carbon;
use Illuminate\Console\Command;
class DailyStatsCommand extends Command
{
protected $signature = 'coruna:daily-stats
{--days=30 : Inclusive local days ending today (ignored when --all or --from is set)}
{--from= : Start date Y-m-d}
{--to= : End date Y-m-d (default today)}
{--all : From the earliest visit/device through --to}';
protected $description = 'Rebuild daily_stats and analytics_daily_dims rollups (UV / devices / version dims)';
public function handle(DailyReportService $reports): int
{
$to = $this->parseDay((string) $this->option('to')) ?? Carbon::now()->endOfDay();
$from = $this->resolveFrom($reports, $to);
if ($from->gt($to)) {
[$from, $to] = [$to->copy()->startOfDay(), $from->copy()->endOfDay()];
}
$result = $reports->rebuildAll($from, $to);
$this->info(sprintf(
'daily-stats rebuilt=%d agents=%d from=%s to=%s',
$result['days'],
$result['agents'],
$from->toDateString(),
$to->toDateString(),
));
return self::SUCCESS;
}
private function resolveFrom(DailyReportService $reports, Carbon $to): Carbon
{
if ((bool) $this->option('all')) {
return $reports->earliestDataDate() ?? $to->copy()->startOfDay();
}
$from = $this->parseDay((string) $this->option('from'));
if ($from !== null) {
return $from;
}
$days = max(1, (int) $this->option('days'));
return $to->copy()->subDays($days - 1)->startOfDay();
}
private function parseDay(string $raw): ?Carbon
{
$raw = trim($raw);
if ($raw === '') {
return null;
}
try {
return Carbon::parse($raw)->startOfDay();
} catch (\Throwable) {
$this->warn('ignored invalid date: '.$raw);
return null;
}
}
}