You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
2.7 KiB

<?php
namespace App\Console\Commands;
use App\Services\PeopleCounting\PeopleCountingSyncService;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Log;
use InvalidArgumentException;
use Throwable;
class PeopleCountingSyncHourlyCommand extends Command
{
use PeopleCountingDateRange;
protected $signature = 'people-counting:sync-hourly
{--date= : 单日 Y-m-d}
{--from= : 区间起始 Y-m-d}
{--to= : 区间结束 Y-m-d}
{--today : 拉今天(整点覆盖用);默认昨天}
{--include-empty : 即使全 0 且 dataSource=memory 也写入}';
protected $description = '从客流 HTTP 拉取场馆 24 小时桶,按 (venue_id, 日期, hour) 覆盖写入 people_counting_hourly';
public function handle(PeopleCountingSyncService $sync): int
{
$default = (bool) $this->option('today') ? Carbon::today() : Carbon::yesterday();
try {
$days = $this->peopleCountingDays(
$this->option('date'),
$this->option('from'),
$this->option('to'),
$default
);
} catch (InvalidArgumentException $e) {
$this->error($e->getMessage());
return self::FAILURE;
}
$skipIfAllZero = ! (bool) $this->option('include-empty');
$sleepMs = $this->peopleCountingSleepMs();
$today = Carbon::today()->toDateString();
$ok = 0;
$fail = 0;
foreach ($days as $i => $day) {
$d = $day->toDateString();
if ($d > $today) {
$this->warn("跳过未来日期 {$d}");
continue;
}
try {
$r = $sync->syncHourlyForDate($day, $skipIfAllZero);
$ok++;
$msg = $r['skipped']
? sprintf('%s skipped empty memory dataSource=%s venues=%d', $r['date'], $r['data_source'] ?? 'null', $r['venues'])
: sprintf('%s written=%d dataSource=%s venues=%d', $r['date'], $r['written'], $r['data_source'] ?? 'null', $r['venues']);
$this->info($msg);
Log::info('people-counting.sync-hourly', $r);
} catch (Throwable $e) {
$fail++;
$this->error("{$d} 失败: ".$e->getMessage());
Log::warning('people-counting.sync-hourly.failed', [
'date' => $d,
'error' => $e->getMessage(),
]);
}
if ($i < count($days) - 1 && $sleepMs > 0) {
usleep($sleepMs * 1000);
}
}
return $fail > 0 && $ok === 0 ? self::FAILURE : self::SUCCESS;
}
}