setName('assistant-service:alert')->setDescription('扫描员工聊天和通话转写并写入行为预警;不调用模型或发送消息') ->addOption('once', null, Option::VALUE_NONE, '只检查一轮') ->addOption('sleep', null, Option::VALUE_REQUIRED, '检查轮询间隔秒数', '60'); } protected function execute(Input $input, Output $output): int { $running = true; if (function_exists('pcntl_async_signals')) { pcntl_async_signals(true); pcntl_signal(SIGTERM, static function () use (&$running): void { $running = false; }); pcntl_signal(SIGINT, static function () use (&$running): void { $running = false; }); } $pause = max(1, min(60, (int) $input->getOption('sleep'))); $scanner = new AlertScanner(); do { $result = $scanner->tick(); $output->writeln('ASSISTANT_SERVICE_ALERT state=' . $result['state'] . ' scanned=' . $result['scanned'] . ' created=' . $result['created']); if (in_array($result['state'], ['error', 'unavailable'], true)) { try { Db::connect()->close(); } catch (\Throwable $ignored) {} if ($input->getOption('once')) { return 1; } } if (!$input->getOption('once') && $running) { sleep($pause); } } while (!$input->getOption('once') && $running); return 0; } }