Files
dafuweng-saiadmin6.x/server/plugin/saiadmin/app/logic/tool/CrontabLogic.php

248 lines
7.5 KiB
PHP

<?php
// +----------------------------------------------------------------------
// | saiadmin [ saiadmin快速开发框架 ]
// +----------------------------------------------------------------------
// | Author: sai <1430792918@qq.com>
// +----------------------------------------------------------------------
namespace plugin\saiadmin\app\logic\tool;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Webman\Channel\Client as ChannelClient;
use plugin\saiadmin\app\model\tool\Crontab;
use plugin\saiadmin\app\model\tool\CrontabLog;
use plugin\saiadmin\basic\think\BaseLogic;
use plugin\saiadmin\exception\ApiException;
/**
* 定时任务逻辑层
*/
class CrontabLogic extends BaseLogic
{
/**
* 构造函数
*/
public function __construct()
{
$this->model = new Crontab();
}
/**
* 添加任务
*/
public function add($data): bool
{
$second = $data['second'];
$minute = $data['minute'];
$hour = $data['hour'];
$week = $data['week'];
$day = $data['day'];
$month = $data['month'];
// 规则处理
$rule = match ($data['task_style']) {
1 => "0 {$minute} {$hour} * * *",
2 => "0 {$minute} * * * *",
3 => "0 {$minute} */{$hour} * * *",
4 => "0 */{$minute} * * * *",
5 => "*/{$second} * * * * *",
6 => "0 {$minute} {$hour} * * {$week}",
7 => "0 {$minute} {$hour} {$day} * *",
8 => "0 {$minute} {$hour} {$day} {$month} *",
default => throw new ApiException('Invalid task type'),
};
// 定时任务模型新增
$model = Crontab::create([
'name' => $data['name'],
'type' => $data['type'],
'task_style' => $data['task_style'],
'rule' => $rule,
'target' => $data['target'],
'parameter' => $data['parameter'],
'status' => $data['status'],
'remark' => $data['remark'],
]);
$id = $model->getKey();
// 连接到Channel服务
ChannelClient::connect();
ChannelClient::publish('crontab', ['args' => $id]);
return true;
}
/**
* 修改任务
*/
public function edit($id, $data): bool
{
$second = $data['second'];
$minute = $data['minute'];
$hour = $data['hour'];
$week = $data['week'];
$day = $data['day'];
$month = $data['month'];
// 规则处理
$rule = match ($data['task_style']) {
1 => "0 {$minute} {$hour} * * *",
2 => "0 {$minute} * * * *",
3 => "0 {$minute} */{$hour} * * *",
4 => "0 */{$minute} * * * *",
5 => "*/{$second} * * * * *",
6 => "0 {$minute} {$hour} * * {$week}",
7 => "0 {$minute} {$hour} {$day} * *",
8 => "0 {$minute} {$hour} {$day} {$month} *",
default => throw new ApiException('Invalid task type'),
};
// 查询任务数据
$model = $this->model->findOrEmpty($id);
if ($model->isEmpty()) {
throw new ApiException('Data not found');
}
$result = $model->save([
'name' => $data['name'],
'type' => $data['type'],
'task_style' => $data['task_style'],
'rule' => $rule,
'target' => $data['target'],
'parameter' => $data['parameter'],
'status' => $data['status'],
'remark' => $data['remark'],
]);
if ($result) {
// 连接到Channel服务
ChannelClient::connect();
ChannelClient::publish('crontab', ['args' => $id]);
}
// 修改任务数据
return $result;
}
/**
* 删除定时任务
* @param $ids
* @return bool
* @throws Exception
*/
public function destroy($ids): bool
{
if (is_array($ids)) {
if (count($ids) > 1) {
throw new ApiException('Batch delete is not allowed');
}
$ids = $ids[0];
}
$result = parent::destroy($ids);
if ($result) {
// 连接到Channel服务
ChannelClient::connect();
ChannelClient::publish('crontab', ['args' => $ids]);
}
return $result;
}
/**
* 修改状态
* @param $id
* @param $status
* @return bool
*/
public function changeStatus($id, $status): bool
{
$model = $this->model->findOrEmpty($id);
if ($model->isEmpty()) {
throw new ApiException('Data not found');
}
$result = $model->save(['status' => $status]);
if ($result) {
// 连接到Channel服务
ChannelClient::connect();
ChannelClient::publish('crontab', ['args' => $id]);
}
return $result;
}
/**
* 执行定时任务
* @param $id
* @return bool
*/
public function run($id): bool
{
$info = $this->model->where('status', 1)->findOrEmpty($id);
if ($info->isEmpty()) {
return false;
}
$data['crontab_id'] = $info->id;
$data['name'] = $info->name;
$data['target'] = $info->target;
$data['parameter'] = $info->parameter;
switch ($info->type) {
case 1:
// URL任务GET
$httpClient = new Client([
'timeout' => 5,
'verify' => false,
]);
try {
$httpClient->request('GET', $info->target);
$data['status'] = 1;
CrontabLog::create($data);
return true;
} catch (GuzzleException $e) {
$data['status'] = 2;
$data['exception_info'] = $e->getMessage();
CrontabLog::create($data);
return false;
}
case 2:
// URL任务POST
$httpClient = new Client([
'timeout' => 5,
'verify' => false,
]);
try {
$res = $httpClient->request('POST', $info->target, [
'form_params' => json_decode($info->parameter ?? '', true)
]);
$data['status'] = 1;
$data['exception_info'] = $res->getBody();
CrontabLog::create($data);
return true;
} catch (GuzzleException $e) {
$data['status'] = 2;
$data['exception_info'] = $e->getMessage();
CrontabLog::create($data);
return false;
}
case 3:
// 类任务
$class_name = $info->target;
$method_name = 'run';
$class = new $class_name;
if (method_exists($class, $method_name)) {
$return = $class->$method_name($info->parameter);
$data['status'] = 1;
$data['exception_info'] = $return;
CrontabLog::create($data);
return true;
} else {
$data['status'] = 2;
$data['exception_info'] = '类:' . $class_name . ',方法:run,未找到';
CrontabLog::create($data);
return false;
}
default:
return false;
}
}
}