158 lines
5.0 KiB
PHP
158 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Console\Scheduling\Schedule;
|
|
|
|
class ScheduledTaskService
|
|
{
|
|
private const CONFIG_KEY = 'scheduled_tasks';
|
|
|
|
private static ?ConfigService $configServiceInstance = null;
|
|
|
|
public function __construct(
|
|
private ConfigService $configService,
|
|
private Schedule $schedule
|
|
) {}
|
|
|
|
/**
|
|
* 静态方法:检查任务是否启用(供 console.php 中的 when() 回调使用)
|
|
*/
|
|
public static function isEnabled(string $name): bool
|
|
{
|
|
try {
|
|
self::$configServiceInstance ??= app(ConfigService::class);
|
|
$enabled = self::$configServiceInstance->get(self::CONFIG_KEY, []);
|
|
return $enabled[$name] ?? false;
|
|
} catch (\Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取所有任务(从 Schedule 实例动态获取)
|
|
*/
|
|
public function getAllTasks(): array
|
|
{
|
|
$this->ensureTasksLoaded();
|
|
|
|
$enabledTasks = $this->configService->get(self::CONFIG_KEY, []);
|
|
$tasks = [];
|
|
|
|
foreach ($this->schedule->events() as $event) {
|
|
$name = $this->getEventName($event);
|
|
$tasks[] = [
|
|
'name' => $name,
|
|
'command' => $this->getEventCommand($event),
|
|
'description' => $this->getTaskDescription($name),
|
|
'frequency' => $this->getFrequencyLabel($event->expression),
|
|
'cron' => $event->expression,
|
|
'enabled' => $enabledTasks[$name] ?? false,
|
|
];
|
|
}
|
|
|
|
return $tasks;
|
|
}
|
|
|
|
/**
|
|
* 设置任务启用状态
|
|
*/
|
|
public function setTaskEnabled(string $name, bool $enabled): void
|
|
{
|
|
$this->ensureTasksLoaded();
|
|
|
|
// 验证任务是否存在
|
|
$exists = false;
|
|
foreach ($this->schedule->events() as $event) {
|
|
if ($this->getEventName($event) === $name) {
|
|
$exists = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$exists) {
|
|
throw new \InvalidArgumentException("未知任务: {$name}");
|
|
}
|
|
|
|
$tasks = $this->configService->get(self::CONFIG_KEY, []);
|
|
$tasks[$name] = $enabled;
|
|
|
|
$this->configService->set(self::CONFIG_KEY, $tasks, '定时任务启用状态');
|
|
}
|
|
|
|
/**
|
|
* 确保 console.php 中的任务已加载
|
|
*/
|
|
private function ensureTasksLoaded(): void
|
|
{
|
|
if (count($this->schedule->events()) === 0) {
|
|
require_once base_path('routes/console.php');
|
|
}
|
|
}
|
|
|
|
private function getEventName($event): string
|
|
{
|
|
// Laravel Schedule 事件的 description 属性存储任务名称
|
|
// 我们在 routes/console.php 中通过 ->description() 设置
|
|
|
|
// 1. 优先使用 description (我们设置的任务标识符)
|
|
if (property_exists($event, 'description') && $event->description) {
|
|
return $event->description;
|
|
}
|
|
|
|
// 2. 最后使用命令作为名称
|
|
return $this->getEventCommand($event);
|
|
}
|
|
|
|
private function getEventCommand($event): string
|
|
{
|
|
if (property_exists($event, 'command') && $event->command) {
|
|
$command = $event->command;
|
|
if (str_contains($command, 'artisan')) {
|
|
$command = preg_replace('/^.*artisan\s+/', '', $command);
|
|
}
|
|
return trim(str_replace("'", '', $command));
|
|
}
|
|
return 'closure';
|
|
}
|
|
|
|
private function getFrequencyLabel(string $expression): string
|
|
{
|
|
$map = [
|
|
'* * * * *' => '每分钟',
|
|
'*/5 * * * *' => '每 5 分钟',
|
|
'*/10 * * * *' => '每 10 分钟',
|
|
'*/15 * * * *' => '每 15 分钟',
|
|
'*/30 * * * *' => '每 30 分钟',
|
|
'0 * * * *' => '每小时',
|
|
'0 */2 * * *' => '每 2 小时',
|
|
'0 */4 * * *' => '每 4 小时',
|
|
'0 */6 * * *' => '每 6 小时',
|
|
'0 */12 * * *' => '每 12 小时',
|
|
'0 0 * * *' => '每天凌晨 0:00',
|
|
'0 2 * * *' => '每天凌晨 2:00',
|
|
'0 3 * * *' => '每天凌晨 3:00',
|
|
'0 0 * * 0' => '每周日凌晨',
|
|
'0 0 1 * *' => '每月 1 日凌晨',
|
|
];
|
|
return $map[$expression] ?? $expression;
|
|
}
|
|
|
|
/**
|
|
* 获取任务的友好描述文本
|
|
*/
|
|
private function getTaskDescription(string $name): string
|
|
{
|
|
$descriptions = [
|
|
'git-monitor-check' => 'Git 监控 - 检查 release 分支变化',
|
|
'git-monitor-cache' => 'Git 监控 - 刷新 release 缓存',
|
|
'daily-log-analysis' => 'SLS 日志分析 - 每日分析过去 24 小时日志',
|
|
'frequent-log-analysis' => 'SLS 日志分析 - 定期分析过去 6 小时日志',
|
|
'jenkins-monitor' => 'Jenkins 发布监控 - 检查新构建并发送通知',
|
|
'scheduled-task-refresh' => '定时任务管理 - 刷新定时任务列表',
|
|
'logs-cleanup' => '日志清理 - 自动删除 7 天前的定时任务日志',
|
|
];
|
|
return $descriptions[$name] ?? $name;
|
|
}
|
|
}
|