tp crontab

https://www.likeshop.cn/doc/13/67
tp5 composer require
"psr/http-message": "^2.0",
"dragonmantank/cron-expression": "^3.4"

<?php


namespace app\common\command;

use app\enum\CrontabEnum;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use Cron\CronExpression;
use think\console;
use app\common\model\Crontab as CrontabModel;

/**
 * 定时任务
 * Class Crontab
 * @package app\command
 *
 * 配置说明
 * 在linux终端配置执行crontab -e,设置脚本内容如下:
 * /1 * * * * php /www/wwwroot/xxxxx.com/system/think crontab
 *
 */
class Crontab extends Command
{
    protected function configure()
    {
        $this->setName('crontab')
            ->setDescription('定时任务');
    }

    protected function execute(Input $input, Output $output)
    {
        $lists = CrontabModel::where('status', CrontabEnum::START)->select();
        if (empty($lists)) {
            return false;
        }
        $time =  time();
        foreach ($lists as $item) {
            if (empty($item['last_time'])) {
                $lastTime = (new CronExpression($item['expression']))
                    ->getNextRunDate()
                    ->getTimestamp();
                CrontabModel::where('id', $item['id'])->update([
                    'last_time' => $lastTime,
                ]);
                continue;
            }

            $nextTime = (new CronExpression($item['expression']))
                ->getNextRunDate($item['last_time'])
                ->getTimestamp();
//            if ($nextTime > $time) {
//                // 未到时间,不执行
//                continue;
//            }
            // 开始执行
            self::start($item);
        }
    }

    public static function start($item)
    {
        // 开始执行
        $startTime = microtime(true);
        $console = new Console();
        try {
            $params = explode(' ', $item['params']);
            if (is_array($params) && !empty($item['params'])) {
                $console->call($item['command'], $params);
            } else {
                $console->call($item['command']);
            }
            // 清除错误信息
            CrontabModel::where('id', $item['id'])->update(['error' => '']);
        } catch (\Exception $e) {
            // 记录错误信息
            CrontabModel::where('id', $item['id'])->update([
                'error' => $e->getMessage(),
                'status' => CrontabEnum::ERROR
            ]);
        } finally {
            $endTime = microtime(true);
            // 本次执行时间
            $useTime = round(($endTime - $startTime), 2);
            // 最大执行时间
            $maxTime = max($useTime, $item['max_time']);
            // 更新最后执行时间
            CrontabModel::where('id', $item['id'])->update([
                'last_time' => time(),
                'last_time_formate' => date('Y-m-d H:i:s', time()),
                'time' => $useTime,
                'max_time' => $maxTime
            ]);
        }
    }
}


tp8

<?php

// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------

namespace app\common\command;

use app\common\enum\CrontabEnum;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use Cron\CronExpression;
use think\facade\Console;
use app\common\model\Crontab as CrontabModel;

/**
 * 定时任务
 * Class Crontab
 * @package app\command
 */
class Crontab extends Command
{
    protected function configure()
    {
        $this->setName('crontab')
            ->setDescription('定时任务');
    }

    protected function execute(Input $input, Output $output)
    {
        $lists = CrontabModel::where('status', CrontabEnum::START)->select()->toArray();
        if (empty($lists)) {
            return false;
        }
        $time =  time();
        foreach ($lists as $item) {
            if (empty($item['last_time'])) {
                $lastTime = (new CronExpression($item['expression']))
                    ->getNextRunDate()
                    ->getTimestamp();
                CrontabModel::where('id', $item['id'])->update([
                    'last_time' => $lastTime,
                ]);
                continue;
            }

            $nextTime = (new CronExpression($item['expression']))
                ->getNextRunDate($item['last_time'])
                ->getTimestamp();
            if ($nextTime > $time) {
                // 未到时间,不执行
                continue;
            }
            // 开始执行
            self::start($item);
        }
    }

    public static function start($item)
    {
        // 开始执行
        $startTime = microtime(true);
        try {
            $params = explode(' ', $item['params']);
            if (is_array($params) && !empty($item['params'])) {
                Console::call($item['command'], $params);
            } else {
                Console::call($item['command']);
            }
            // 清除错误信息
            CrontabModel::where('id', $item['id'])->update(['error' => '']);
        } catch (\Exception $e) {
            // 记录错误信息
            CrontabModel::where('id', $item['id'])->update([
                'error' => $e->getMessage(),
                'status' => CrontabEnum::ERROR
            ]);
        } finally {
            $endTime = microtime(true);
            // 本次执行时间
            $useTime = round(($endTime - $startTime), 2);
            // 最大执行时间
            $maxTime = max($useTime, $item['max_time']);
            // 更新最后执行时间
            CrontabModel::where('id', $item['id'])->update([
                'last_time' => time(),
                'time' => $useTime,
                'max_time' => $maxTime
            ]);
        }
    }
}

sql

CREATE TABLE `sp_dev_crontab` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL COMMENT '定时任务名称',
  `type` tinyint(1) NOT NULL COMMENT '类型 1-定时任务',
  `system` tinyint(4) DEFAULT '0' COMMENT '是否系统任务 0-否 1-是',
  `remark` varchar(255) DEFAULT '' COMMENT '备注',
  `command` varchar(64) NOT NULL COMMENT '命令内容',
  `params` varchar(64) DEFAULT '' COMMENT '参数',
  `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态 1-运行 2-停止 3-错误',
  `expression` varchar(64) NOT NULL COMMENT '运行规则',
  `error` varchar(256) DEFAULT NULL COMMENT '运行失败原因',
  `last_time` int(11) DEFAULT NULL COMMENT '最后执行时间',
  `last_time_formate` datetime DEFAULT NULL COMMENT '最后执行时间',
  `time` varchar(64) DEFAULT '0' COMMENT '实时执行时长',
  `max_time` varchar(64) DEFAULT '0' COMMENT '最大执行时长',
  `create_time` int(11) DEFAULT NULL COMMENT '创建时间',
  `update_time` int(11) DEFAULT NULL COMMENT '更新时间',
  `delete_time` int(11) DEFAULT NULL COMMENT '删除时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='计划任务表';

INSERT INTO `znz-pc-xcx`.`sp_dev_crontab` (`id`, `name`, `type`, `system`, `remark`, `command`, `params`, `status`, `expression`, `error`, `last_time`, `last_time_formate`, `time`, `max_time`, `create_time`, `update_time`, `delete_time`) VALUES (1, '订单推送信息', 1, 0, 'order push message', 'orderpush', NULL, 1, '*/1 * * * *', '', 1754027821, '2025-08-01 13:57:01', '0.02', '74.65', 1753671211, 1753671211, NULL);

然后随便写个command

<?php

namespace app\common\command;

use app\service\crontab\OrderService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Argument;
use think\console\input\Option;


/*
 * 订单推送短信 wx 站内
 */
class OrderPush extends Command
{
    protected function configure()
    {
        $this->setName('orderpush')
//            ->addArgument('page', Argument::REQUIRED, '页码')
//            ->addOption('city', null, Option::VALUE_REQUIRED, 'city name')
            ->setDescription('拉数据');
    }

    protected function execute(Input $input, Output $output)
    {




        write_admin_log('orderpush..... api ..........start.....');

        OrderService::pushMsgOrder();


        write_admin_log('orderpush..... api ..........end.....');
        return 0;
    }
}


function write_admin_log($message, $logName = 'contab_log')
{
    $yearMonth = date('Ym');
    $day = date('d');

    $logDir = LOG_PATH . $yearMonth . '/';
    if (!is_dir($logDir)) {
        mkdir($logDir, 0777, true);
    }
    $logPath = $logDir . $day . '_' . $logName . '.log';
    $logContent = '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL;
   file_put_contents($logPath, $logContent, FILE_APPEND);
}


然后随便写个实现 方法

class OrderService
{


    public static function pushMsgOrder(){
        $redis =  Config::get('database')['redis'];
//        $tmp = [
//            'id' => 2,
//            'order_id' => 27978,
//            'store_id' => 3,
//        ];


        Redis::init($redis);


//        Redis::rpush('list_msg_queue', json_encode($tmp));
//return true;



        $number = 10;
        $queue_data = Redis::lrange("list_msg_queue", 0, $number);
        if(empty($queue_data)){
            write_admin_log('0推送失败,没有redis数据');
            return 0;
        }
        Redis::ltrim("list_msg_queue", count($queue_data ), -1);

        foreach ($queue_data as $k=>$val){
            $queue_one = json_decode($val,true);
            $store = Db::name('store')
                ->where('id',$queue_one['store_id'])->field('telephone,memberid,id')->find();
            if(!$store){
                write_admin_log('1推送失败,查询不到store,queue id为'.$queue_one['id']);
                continue;
            }

posted @ 2025-08-01 14:04  Bashuslovakia  阅读(10)  评论(0)    收藏  举报