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

WooCommerce基于自定义字段数组实现数量阶梯定价代码调试需求

问题描述

每个产品都有一个名为prices的自定义字段,存储数量阶梯定价的JSON数组,示例如下:

{"USD":[{"unit_break":3000,"unit_price":"0.0850"},{"unit_break":6000,"unit_price":"0.0819"},{"unit_break":12000,"unit_price":"0.0795"},{"unit_break":18000,"unit_price":"0.0771"},{"unit_break":24000,"unit_price":"0.0742"},{"unit_break":30000,"unit_price":"0.0731"},{"unit_break":300000,"unit_price":"0.0719"}]}

需求逻辑:

当购物车商品数量小于等于某个unit_break值时,对应使用该数组项的unit_price作为商品价格,逻辑示例:

if cartquantity <= unit_break[0] {
  product price = unit_price[0]
} else if cartquantity <= unit_break[1] {
  product price = unit_price[1]
}

每个产品的阶梯数量不固定,需动态适配。现有代码仅能读取数组首个unit_break/unit_price项,无法处理后续阶梯,代码如下:

add_action( 'woocommerce_before_calculate_totals', 'quantity_based_bulk_pricing', 9999, 1 );
function quantity_based_bulk_pricing( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) 
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) 
        return;


    // Loop through cart items
    foreach( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // Get the bulk price from product custom field
        $prices = get_post_meta( $cart_item['product_id'], 'prices', true);
        $prices = json_decode($prices, true);

        $s = 0;

        foreach($prices as $price) {
            foreach($price as $unit) {
                $bulk_price = $unit['unit_break'];
                $qty_threshold = $unit['unit_price'];
            }
            $bulk_price = $price[$s]['unit_price'];
            $qty_threshold = $price[$s]['unit_break'];

            // Check if  item quantity has reached the defined threshold
            if( $cart_item['quantity'] <= $qty_threshold) {
                // Set the bulk price
                $cart_item['data']->set_price( $bulk_price );
            }


            //echo $qty_threshold.'<br>';
            //echo $bulk_price;
        }

    }
}
问题分析与修复

原代码核心问题:

  • 嵌套循环逻辑混乱,外层遍历货币组后,未正确遍历所有阶梯定价,反而用固定索引s=0仅取第一个阶梯
  • 阈值判断逻辑缺失,没有按顺序匹配符合条件的阶梯后终止遍历

修正后的代码:

add_action( 'woocommerce_before_calculate_totals', 'quantity_based_bulk_pricing', 9999, 1 );
function quantity_based_bulk_pricing( $cart ) {
    // 后台非AJAX请求直接返回
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) 
        return;
    // 避免重复执行钩子
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) 
        return;

    // 遍历购物车所有商品
    foreach( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $product_id = $cart_item['product_id'];
        $cart_qty = $cart_item['quantity'];
        
        // 获取并解析自定义定价字段
        $prices_json = get_post_meta( $product_id, 'prices', true );
        if ( empty($prices_json) ) continue;
        
        $prices = json_decode($prices_json, true);
        if ( empty($prices) || !is_array($prices) ) continue;

        $target_price = null;
        // 遍历货币组(默认取第一个有效货币组)
        foreach( $prices as $currency_prices ) {
            if ( !is_array($currency_prices) ) continue;
            
            // 按顺序遍历阶梯定价,匹配符合条件的价格
            foreach( $currency_prices as $tier ) {
                $unit_break = (int)$tier['unit_break'];
                $unit_price = (float)$tier['unit_price'];
                
                // 购物车数量小于等于当前阶梯阈值时,记录价格并终止遍历
                if ( $cart_qty <= $unit_break ) {
                    $target_price = $unit_price;
                    break 2; // 跳出两层循环,避免后续无效遍历
                }
            }
        }

        // 成功匹配到阶梯价格时,设置商品单价
        if ( $target_price !== null ) {
            $cart_item['data']->set_price( $target_price );
        }
    }
}

修复说明:

  • 增加空值校验,避免JSON解析失败或字段为空引发报错
  • 阶梯遍历逻辑优化:找到第一个符合条件的阶梯后立即终止循环,符合需求的顺序匹配逻辑
  • 对unit_break和unit_price做类型转换,避免字符串类型导致的比较错误
  • 代码结构更清晰,逻辑分层明确,适配不同数量的阶梯定价

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:55:30