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

WooCommerce技术问询:如何获取订单被标记为已取消的日期?

获取WooCommerce订单取消日期的更优方案

你的当前方法通过遍历所有订单备注筛选取消状态变更记录,虽然可行,但可以通过以下几种方式优化,提升效率和准确性:

一、优化订单备注查询(减少数据读取)

不需要获取所有订单备注,直接通过wc_get_order_notes的参数过滤出仅包含状态变更的系统备注,缩小内容匹配范围,减少遍历的数据量:

function get_cancellation_date_with_timezone($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return false;

    // 仅获取系统生成的、包含取消状态变更的备注
    $notes = wc_get_order_notes([
        'order_id' => $order_id,
        'type'     => 'system', // 排除用户自定义备注
        'search'   => 'to Cancelled' // 精准缩小查询范围
    ]);

    foreach ($notes as $note) {
        // 确认是状态变更到Cancelled的备注
        if (strpos($note->content, 'Order status changed from') !== false) {
            // 直接返回WC自带的日期对象,无需重新实例化
            return $note->date_created;
        }
    }

    return false;
}

// 使用示例
$cancellation_date = get_cancellation_date_with_timezone(1234);
if ($cancellation_date) {
    echo $cancellation_date->format('Y-m-d\TH:i:sP');
}

二、直接查询数据库(极致性能)

如果涉及大量订单批量处理,直接查询存储订单备注的数据库表,避免WooCommerce函数的额外开销:

function get_cancellation_date_db($order_id) {
    global $wpdb;

    $date = $wpdb->get_var($wpdb->prepare(
        "SELECT comment_date_gmt FROM {$wpdb->comments}
         WHERE comment_post_ID = %d
           AND comment_type = 'order_note'
           AND comment_content LIKE %s
           AND comment_content LIKE %s
         ORDER BY comment_date_gmt ASC
         LIMIT 1",
        $order_id,
        '%Order status changed from%',
        '%to Cancelled%'
    ));

    if ($date) {
        // 转换为带站点时区的WC日期对象
        $wc_date = new WC_DateTime($date, new DateTimeZone('UTC'));
        $wc_date->setTimezone(wc_timezone());
        return $wc_date;
    }

    return false;
}

// 使用示例
$cancellation_date = get_cancellation_date_db(1234);
if ($cancellation_date) {
    echo $cancellation_date->format('Y-m-d\TH:i:sP');
}

三、利用订单状态过渡记录(简洁方案)

部分WooCommerce版本支持直接读取状态变更历史,代码最简洁,但需注意版本兼容性:

function get_cancellation_date_transition($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return false;

    // 获取所有状态变更记录
    $transitions = $order->get_status_transitions();
    foreach ($transitions as $transition) {
        if ($transition['to'] === 'cancelled') {
            return new WC_DateTime($transition['date_created'], new DateTimeZone('UTC'));
        }
    }

    return false;
}

方案对比

  • 优化后的订单备注查询:兼顾效率与代码简洁,适合绝大多数常规场景
  • 直接数据库查询:性能最优,适合批量处理大量订单的场景
  • 状态过渡记录:代码最简洁,但依赖WooCommerce版本,兼容性稍弱

注意:所有方案都建议先判断订单当前状态是否为cancelled,避免无效查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 02:17:07