You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Action Scheduler实现WooCommerce订单定时克隆与启停

正确实现WooCommerce定时订单克隆与停止功能

一、核心代码实现步骤

1. 注册定时克隆动作

先把你的克隆函数绑定到Action Scheduler的自定义钩子,再写一个函数来创建定时任务(避免重复添加):

// 绑定克隆函数到定时钩子
add_action('mutiara_scheduled_order_clone', 'mutiara_woocommerce_order_clone', 10, 1);

// 创建定时任务
function mutiara_schedule_order_clone($order_id, $interval) {
    // 先查有没有同订单的活跃任务,防止重复
    $existing_actions = as_get_scheduled_actions(array(
        'hook' => 'mutiara_scheduled_order_clone',
        'args' => array($order_id),
        'status' => array('pending', 'in-progress', 'scheduled')
    ));
    
    if (!empty($existing_actions)) return;

    // 转换周期为Action Scheduler支持的格式
    switch($interval) {
        case 'weekly':
            $schedule = 'weekly';
            break;
        case 'biweekly':
            // 注册每两周的自定义周期(14天=1209600秒)
            add_filter('cron_schedules', function($schedules) {
                $schedules['biweekly'] = array(
                    'interval' => 1209600,
                    'display' => __('每两周')
                );
                return $schedules;
            });
            $schedule = 'biweekly';
            break;
        case 'monthly':
            $schedule = 'monthly';
            break;
        default:
            return;
    }

    // 添加循环定时任务
    as_schedule_recurring_action(time(), $schedule, 'mutiara_scheduled_order_clone', array($order_id));
}

2. 订单详情页添加操作按钮

在订单侧边栏加一个 metabox,包含周期选择、启动按钮,以及停止按钮(有活跃任务时显示):

// 注册 metabox
add_action('add_meta_boxes', 'mutiara_order_clone_meta_box');
function mutiara_order_clone_meta_box() {
    add_meta_box(
        'mutiara-order-clone-scheduler',
        '定时克隆订单',
        'mutiara_order_clone_meta_box_content',
        'shop_order',
        'side',
        'default'
    );
}

// 渲染 metabox 内容
function mutiara_order_clone_meta_box_content($post) {
    $order_id = $post->ID;
    // 检查是否有活跃定时任务
    $has_scheduled = !empty(as_get_scheduled_actions(array(
        'hook' => 'mutiara_scheduled_order_clone',
        'args' => array($order_id),
        'status' => array('pending', 'scheduled')
    )));
    ?>
    <div class="inside">
        <?php if (!$has_scheduled) : ?>
            <p>选择克隆周期:</p>
            <select id="clone-interval" name="clone-interval">
                <option value="weekly">每周</option>
                <option value="biweekly">每两周</option>
                <option value="monthly">每月</option>
            </select>
            <p><button type="button" id="schedule-clone" class="button button-primary" data-order-id="<?php echo $order_id; ?>">启动定时克隆</button></p>
        <?php else : ?>
            <p>当前已有定时克隆任务运行</p>
            <p><button type="button" id="stop-clone" class="button button-secondary" data-order-id="<?php echo $order_id; ?>">停止定时克隆</button></p>
        <?php endif; ?>
    </div>
    <?php
}

// AJAX处理启动/停止请求
add_action('wp_ajax_schedule_order_clone', 'mutiara_ajax_schedule_order_clone');
add_action('wp_ajax_stop_order_clone', 'mutiara_ajax_stop_order_clone');

function mutiara_ajax_schedule_order_clone() {
    if (!current_user_can('edit_shop_orders')) {
        wp_send_json_error('无权限操作');
    }
    $order_id = intval($_POST['order_id']);
    $interval = sanitize_text_field($_POST['interval']);
    mutiara_schedule_order_clone($order_id, $interval);
    wp_send_json_success('定时克隆已启动');
}

function mutiara_ajax_stop_order_clone() {
    if (!current_user_can('edit_shop_orders')) {
        wp_send_json_error('无权限操作');
    }
    $order_id = intval($_POST['order_id']);
    // 取消所有相关任务
    $actions = as_get_scheduled_actions(array(
        'hook' => 'mutiara_scheduled_order_clone',
        'args' => array($order_id),
        'status' => array('pending', 'scheduled')
    ));
    foreach ($actions as $action) {
        as_unschedule_action($action->hook, $action->args, $action->group);
    }
    wp_send_json_success('定时克隆已停止');
}

// 加载前端交互JS
add_action('admin_footer', 'mutiara_clone_scheduler_js');
function mutiara_clone_scheduler_js() {
    global $post_type;
    if ($post_type !== 'shop_order') return;
    ?>
    <script>
        jQuery(document).ready(function($) {
            $('#schedule-clone').click(function() {
                const orderId = $(this).data('order-id');
                const interval = $('#clone-interval').val();
                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'schedule_order_clone',
                        order_id: orderId,
                        interval: interval
                    },
                    success: res => {
                        alert(res.data);
                        location.reload();
                    },
                    error: () => alert('操作失败')
                });
            });

            $('#stop-clone').click(function() {
                const orderId = $(this).data('order-id');
                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'stop_order_clone',
                        order_id: orderId
                    },
                    success: res => {
                        alert(res.data);
                        location.reload();
                    },
                    error: () => alert('操作失败')
                });
            });
        });
    </script>
    <?php
}

二、常见错误排查方案

1. 致命错误定位

先开启WP debug模式,在wp-config.php里加这段代码:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

然后看wp-content/debug.log里的报错信息,常见问题:

  • Action Scheduler未激活:确认插件已启用,且调用的函数(比如as_schedule_recurring_action)存在
  • 克隆函数参数错误:检查mutiara_woocommerce_order_clone是否正确接收$order_id,且内部有没有未处理的空订单情况

2. 定时任务不执行

  • 看Action Scheduler后台:WP后台工具 → Action Scheduler里查看任务状态,有没有失败或未调度的任务
  • 检查WP Cron:访问你的域名/wp-cron.php?doing_wp_cron手动触发,看任务是否执行
  • 自定义周期失效:每两周的周期要确保cron_schedules过滤器在添加任务前已注册

3. 重复克隆问题

每次添加任务前必须检查已有任务,代码里已经加了as_get_scheduled_actions的判断,不要跳过这步,否则会出现一个订单被多次克隆的情况。

三、额外注意事项

  • 权限控制:代码里用current_user_can('edit_shop_orders')限制了操作权限,不要去掉
  • 订单状态过滤:在你的克隆函数里加个判断,只克隆有效状态的订单,比如:
function mutiara_woocommerce_order_clone($order_id) {
    $order = wc_get_order($order_id);
    if (!$order || !in_array($order->get_status(), array('completed', 'processing'))) {
        // 订单无效就取消后续任务
        as_unschedule_action('mutiara_scheduled_order_clone', array($order_id));
        return;
    }
    // 你的克隆逻辑...
}
  • 性能考量:如果定时任务太多,会影响服务器性能,建议限制可定时克隆的订单数量

内容的提问来源于stack exchange,提问作者iv444

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 03:43:14