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; } }