request->param('concurrency_id', 0); if ($concurrency_id > $this->concurrency) { $this->error('concurrency id error'); } $this->concurrencyId = $concurrency_id; $concurrency_count = $this->request->param('concurrency_count', 1); if ($concurrency_count > $this->concurrency) { $this->error('concurrency count error'); } $this->hostId = $this->request->param('host_id', ''); if (is_int($this->frequency)) { $this->protectVisit($this->frequency); } } protected function protectVisit(int $frequency) { $cache_tag = 'timer_protect'; $cache_key = 'timer_protect_' . md5($this->request->url()); $last_exec_time = Cache::get($cache_key, 0); if ($last_exec_time >= time() - $frequency) { return $this->error('请不要频繁请求'); } Cache::tag($cache_tag)->set($cache_key, time()); } public function logStart(string $taskName): int { $data = [ 'task_name' => $taskName, 'node_id' => $this->hostId, 'run_type' => '', 'start_time' => time(), 'end_time' => 0, 'duration' => 0, 'status' => 'running', 'error_message' => null, 'result' => null, 'concurrency_id' => $this->concurrencyId, 'create_time' => time(), ]; $log = SystemTimerLog::create($data); return $log->id; } public function logEnd(int $logId, string $status = 'success', ?string $errorMessage = null, ?string $result = null): void { $log = SystemTimerLog::find($logId); if ($log) { $endTime = time(); $log->end_time = $endTime; $log->duration = ($endTime - $log->start_time) * 1000; // ms $log->status = $status; $log->error_message = $errorMessage; $log->result = $result; $log->save(); } } /** * 日志包裹入口:自动记录 do() 的执行过程和返回值. * 子类仍实现 do(),URL 路由从 /do 改为 /execute 触发此方法. */ public function execute() { $taskName = $this->request->param('task_name', ''); $logId = $this->logStart($taskName); try { $result = $this->do(); $resultStr = is_string($result) ? $result : json_encode($result, JSON_UNESCAPED_UNICODE); $this->logEnd($logId, 'success', null, $resultStr); return $result; } catch (\Throwable $e) { $this->logEnd($logId, 'error', $e->getMessage()); throw $e; } } }