ThinkPHP+redis 实现延迟任务 实现自动取消订单,自动完成订单

发布于:2024-09-18 ⋅ 阅读:(131) ⋅ 点赞:(0)

在 ThinkPHP 中结合 Redis 实现延迟任务,可以用于自动处理订单取消、自动完成等功能。Redis 的 ZSET(有序集合)功能非常适合实现延迟任务队列。以下是详细的实现步骤:

1. 准备工作

确保你的环境中已安装 Redis,并在 ThinkPHP 中配置 Redis 连接。

配置 Redis(假设使用 Redis 扩展):

config/database.php 中配置 Redis 连接:

return [
    // ...
    'redis' => [
        'type'   => 'redis',
        'host'   => '127.0.0.1',
        'port'   => 6379,
        'password' => '',
        'select' => 0,
        'timeout' => 0,
        'persistent' => false,
    ],
];

2. 添加延迟任务

通过 Redis 的有序集合(Sorted Set)来实现延迟任务。任务会在指定的时间戳后执行。

任务添加函数:

namespace app\index\model;

use think\Model;
use think\facade\Cache;

class TaskModel extends Model
{
    // 添加延迟任务
    public function addDelayedTask($taskId, $delaySeconds, $taskData)
    {
        $redis = Cache::store('redis')->handler();
        $timestamp = time() + $delaySeconds;
        $redis->zAdd('delayed_tasks', $timestamp, json_encode([
            'task_id' => $taskId,
            'task_data' => $taskData
        ]));
    }
}

3. 执行延迟任务

创建一个定时任务脚本,定期检查 Redis 队列并执行到期的任务。

任务执行脚本(命令行):

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Cache;

class ProcessDelayedTasks extends Command
{
    protected function configure()
    {
        $this->setName('process:delayed-tasks')
            ->setDescription('Process delayed tasks from Redis.');
    }

    protected function execute(Input $input, Output $output)
    {
        $redis = Cache::store('redis')->handler();
        $now = time();

        // 获取当前时间之前的所有任务
        $tasks = $redis->zRangeByScore('delayed_tasks', '-inf', $now);

        foreach ($tasks as $taskJson) {
            $task = json_decode($taskJson, true);
            $taskId = $task['task_id'];
            $taskData = $task['task_data'];

            // 执行任务
            $this->processTask($taskId, $taskData);

            // 从 Redis 中删除已处理的任务
            $redis->zRem('delayed_tasks', $taskJson);
        }
    }

    private function processTask($taskId, $taskData)
    {
        // 根据 taskId 和 taskData 处理任务
        // 例如:自动取消订单、自动完成订单等
        // 这里可以调用其他模型或服务来处理具体逻辑
        $output->writeln("Processing task ID: $taskId");
        // 实现你的任务处理逻辑
    }
}

定时任务配置:

在服务器上使用 Cron 或类似的定时任务工具定期运行 process:delayed-tasks 命令。例如,每分钟运行一次:

* * * * * /usr/bin/php /path/to/your/project/think process:delayed-tasks

4. 处理具体任务

你可以根据具体需求实现任务处理逻辑。例如,实现自动取消订单和自动完成订单功能:

自动取消订单:

public function autoCancelOrder($orderId)
{
    // 根据订单 ID 查询订单状态并进行取消操作
    $order = OrderModel::find($orderId);

    if ($order && $order->status === 'pending') {
        $order->status = 'canceled';
        $order->save();
        // 可能需要发送通知等
    }
}

自动完成订单:

public function autoCompleteOrder($orderId)
{
    // 根据订单 ID 查询订单状态并进行完成操作
    $order = OrderModel::find($orderId);

    if ($order && $order->status === 'shipped') {
        $order->status = 'completed';
        $order->save();
        // 可能需要发送通知等
    }
}

总结

  1. 添加延迟任务:使用 Redis 的有序集合将任务添加到 Redis 队列中,指定延迟时间。
  2. 执行延迟任务:创建定时任务脚本定期检查 Redis 队列并执行到期的任务。
  3. 处理具体任务:根据任务类型实现具体的业务逻辑,比如自动取消订单或自动完成订单。

网站公告

今日签到

点亮在社区的每一天
去签到