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

WooCommerce:限制用户指定时间内购2件商品并调整错误提示位置

WooCommerce 实现指定类别商品限时限购2件(仅购物车页提示)

需求说明

  • 为指定商品类别设置限购规则:用户在指定时间范围内最多可购买2件该类别商品(包含已支付订单和当前购物车中的数量)
  • 允许商品正常加入购物车,仅在购物车页面展示限购错误提示

完整实现代码

// 计算用户在指定时间内已购买的指定类别商品总数量
function get_user_purchased_category_qty( $category_slugs, $time_range_days = 1 ) {
    if ( ! is_user_logged_in() && empty( WC()->customer->get_billing_email() ) ) {
        return 0;
    }

    global $wpdb;
    $time_threshold = strtotime( "-{$time_range_days} days" );

    // 识别用户:登录用户用ID,访客用邮箱
    if ( is_user_logged_in() ) {
        $meta_key = '_customer_user';
        $meta_value = get_current_user_id();
    } else {
        $meta_key = '_billing_email';
        $meta_value = sanitize_email( WC()->customer->get_billing_email() );
    }

    $paid_statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() );
    $statuses_in = "'wc-" . implode( "','wc-", $paid_statuses ) . "'";

    // 查询已购买的指定类别商品数量
    $purchased_qty = $wpdb->get_var( $wpdb->prepare( "
        SELECT SUM(oi.quantity)
        FROM {$wpdb->prefix}posts p
        INNER JOIN {$wpdb->prefix}postmeta pm ON p.ID = pm.post_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON p.ID = oi.order_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
        INNER JOIN {$wpdb->prefix}term_relationships tr ON oim.meta_value = tr.object_id
        INNER JOIN {$wpdb->prefix}term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
        INNER JOIN {$wpdb->prefix}terms t ON tt.term_id = t.term_id
        WHERE p.post_status IN ({$statuses_in})
        AND p.post_type = 'shop_order'
        AND pm.meta_key = %s
        AND pm.meta_value = %s
        AND p.post_date >= %s
        AND oim.meta_key = '_product_id'
        AND tt.taxonomy = 'product_cat'
        AND t.slug IN ('" . implode( "','", array_map( 'esc_sql', $category_slugs ) ) . "')
    ", $meta_key, $meta_value, date( 'Y-m-d H:i:s', $time_threshold ) ) );

    return empty( $purchased_qty ) ? 0 : (int)$purchased_qty;
}

// 计算购物车中指定类别商品的数量
function get_cart_category_qty( $category_slugs ) {
    $cart_qty = 0;
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( has_term( $category_slugs, 'product_cat', $cart_item['product_id'] ) ) {
            $cart_qty += $cart_item['quantity'];
        }
    }
    return $cart_qty;
}

// 在购物车页面检查限购规则并显示提示
function check_category_limit_on_cart() {
    if ( ! is_cart() ) return;

    // 配置参数:指定类别slug、限购数量、时间范围(天)
    $target_categories = array( 'kitchen' );
    $max_allowed = 2;
    $time_range = 1; // 1天内

    $purchased_qty = get_user_purchased_category_qty( $target_categories, $time_range );
    $cart_qty = get_cart_category_qty( $target_categories );
    $total_qty = $purchased_qty + $cart_qty;

    if ( $total_qty > $max_allowed ) {
        wc_add_notice( sprintf( '您在%s天内最多可购买%d件该类别商品,当前已选购%d件', $time_range, $max_allowed, $total_qty ), 'error' );
        
        // 可选:阻止结账按钮(如果需要)
        // add_filter( 'woocommerce_proceed_to_checkout_button', '__return_false' );
    }
}
add_action( 'woocommerce_before_cart', 'check_category_limit_on_cart' );

// 可选:在结账页面也检查(防止用户直接跳转结账)
function check_category_limit_on_checkout() {
    if ( ! is_checkout() || is_wc_endpoint_url( 'order-received' ) ) return;

    $target_categories = array( 'kitchen' );
    $max_allowed = 2;
    $time_range = 1;

    $purchased_qty = get_user_purchased_category_qty( $target_categories, $time_range );
    $cart_qty = get_cart_category_qty( $target_categories );
    $total_qty = $purchased_qty + $cart_qty;

    if ( $total_qty > $max_allowed ) {
        wc_add_notice( sprintf( '您在%s天内最多可购买%d件该类别商品,当前已选购%d件', $time_range, $max_allowed, $total_qty ), 'error' );
    }
}
add_action( 'woocommerce_before_checkout_form', 'check_category_limit_on_checkout' );

代码关键说明

  1. 数量统计逻辑

    • get_user_purchased_category_qty:查询用户在指定时间内已支付订单中指定类别的商品总数量,支持登录用户(用ID识别)和访客(用账单邮箱识别)
    • get_cart_category_qty:统计当前购物车中指定类别的商品数量
  2. 提示触发时机

    • 在woocommerce_before_cart钩子中检查,仅在购物车页面显示错误提示,不拦截商品加入购物车的操作
    • 可选添加结账页面检查,防止用户绕过购物车直接结账
  3. 可配置参数

    • 修改$target_categories数组设置需要限购的商品类别slug
    • 修改$max_allowed设置限购数量
    • 修改$time_range设置时间范围(单位:天)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:30:50