Przeglądaj źródła

feat: 新增cron_job_log模型

runphp 1 tydzień temu
rodzic
commit
a5f0dce953

+ 38 - 0
database/migrations/20260710140000_create_cron_job_log.php

@@ -0,0 +1,38 @@
+<?php
+
+declare(strict_types=1);
+
+use Phinx\Migration\AbstractMigration;
+
+class CreateCronJobLog extends AbstractMigration
+{
+    public function change(): void
+    {
+        $table = $this->table('cron_job_log', [
+            'comment' => '定时任务执行日志',
+            'engine' => 'InnoDB',
+            'collation' => 'utf8mb4_general_ci',
+        ]);
+
+        $table->addColumn('name', 'string', [
+            'limit' => 100,
+            'null' => false,
+            'comment' => '任务名称'
+        ])->addColumn('rule', 'string', [
+            'limit' => 50,
+            'null' => false,
+            'comment' => 'cron规则'
+        ])->addColumn('duration', 'decimal', [
+            'precision' => 10,
+            'scale' => 4,
+            'default' => 0,
+            'comment' => '执行耗时(秒)'
+        ])->addColumn('success', 'boolean', [
+            'default' => true,
+            'comment' => '是否成功'
+        ])->addTimestamps('create_time', false)
+            ->addIndex(['name', 'id'], [
+            'name' => 'idx_name_id'
+        ])->create();
+    }
+}

+ 39 - 0
src/Entity/CronJobLogEntity.php

@@ -0,0 +1,39 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SixShop\System\Entity;
+
+use SixShop\Core\Entity\BaseEntity;
+use SixShop\System\Model\CronJobLogModel;
+
+/**
+ * @mixin CronJobLogModel
+ */
+class CronJobLogEntity extends BaseEntity
+{
+    /**
+     * 获取每个任务的最新一次执行记录
+     */
+    public function getLatestPerJob(): array
+    {
+        $subQuery = $this->field('MAX(id) as max_id')
+            ->group('name')
+            ->buildSql();
+
+        $records = $this->where('id IN ' . $subQuery)
+            ->order('id', 'desc')
+            ->select()
+            ->toArray();
+
+        return array_map(function (array $record): array {
+            return [
+                'name' => $record['name'],
+                'rule' => $record['rule'],
+                'last_time' => $record['create_time'],
+                'duration' => $record['duration'],
+                'success' => $record['success'],
+            ];
+        }, $records);
+    }
+}

+ 5 - 12
src/Hook/CronJobHook.php

@@ -5,33 +5,26 @@ declare(strict_types=1);
 namespace SixShop\System\Hook;
 
 use SixShop\Core\Attribute\Hook;
+use SixShop\System\Entity\CronJobLogEntity;
 use SixShop\System\Event\CronJobAfterEvent;
-use think\Cache;
 
 class CronJobHook
 {
-    private const CACHE_KEY = 'crontab_list';
-
-    public function __construct(private Cache $cache)
+    public function __construct(private CronJobLogEntity $cronJobLogEntity)
     {
-        // 清空上次运行的缓存数据
-        $this->cache->delete(self::CACHE_KEY);
     }
 
     /**
-     * 每次任务执行后更新最后执行时间和运行状态
+     * 每次任务执行后记录执行日志到数据库
      */
     #[Hook(CronJobAfterEvent::class)]
     public function onJobExecuted(CronJobAfterEvent $event): void
     {
-        $crontabList = $this->cache->get(self::CACHE_KEY, []);
-        $crontabList[$event->name] = [
+        $this->cronJobLogEntity->save([
             'name' => $event->name,
             'rule' => $event->rule,
-            'last_time' => date('Y-m-d H:i:s'),
             'duration' => $event->duration,
             'success' => $event->isSuccessful(),
-        ];
-        $this->cache->set(self::CACHE_KEY, $crontabList);
+        ]);
     }
 }

+ 24 - 0
src/Model/CronJobLogModel.php

@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+namespace SixShop\System\Model;
+
+use think\Model;
+
+class CronJobLogModel extends Model
+{
+    protected function getOptions(): array
+    {
+        return [
+            'name' => 'cron_job_log',
+            'autoWriteTimestamp' => true,
+            'createTime' => 'create_time',
+            'updateTime' => false,
+            'type' => [
+                'success' => 'bool',
+                'duration' => 'float',
+            ],
+        ];
+    }
+}