// +---------------------------------------------------------------------- declare(strict_types=1); namespace addon\haonav\controller; use ywxapp\controller\FrontendBase; use addon\haonav\model\Links as LinksModel; use addon\haonav\model\Configure as ConfigureModel; /** * 计划任务入口(可通过服务器 cron 调用) * * 示例:curl "https://你的域名/haonav/task/checklinks?token=你的检测令牌" * 令牌在「导航配置」中设置 check_token,为空则拒绝执行。 */ class Task extends FrontendBase { protected $noNeedLogin = ['*']; protected $noNeedVerify = ['*']; protected function initialize() { } /** * 死链检测(供 cron 调用) */ public function checkLinks() { $token = $this->request->param('token', ''); $realToken = ConfigureModel::getVal('check_token', ''); if ($realToken === '' || $token !== $realToken) { return $this->result->error('token 校验失败', 403); } $stats = LinksModel::checkAllLinks(); return $this->result->success($stats, '检测完成'); } /** * 惰性自动巡检(前台页面加载后异步 ping,无 cron 环境的兜底方案) * * - 需在「导航配置」开启 enable_auto_check * - 缓存锁限频:每小时最多执行一批(5 条,超时 5s),不影响页面渲染 */ public function autoCheck() { if ((int)ConfigureModel::getVal('enable_auto_check', '0') !== 1) { return $this->result->success(['skipped' => 'disabled']); } $lockKey = 'haonav_autocheck_lock'; if (\think\facade\Cache::get($lockKey)) { return $this->result->success(['skipped' => 'locked']); } \think\facade\Cache::set($lockKey, 1, 3600); ignore_user_abort(true); @set_time_limit(60); $stats = LinksModel::checkBatch(5, 5); return $this->result->success($stats, '巡检完成'); } }