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

在JavaScript中处理WooCommerce商品变体自定义元字段与价格计算

WooCommerce变体价格转换需求与解决方案

需求概述

  • 部分商品变体价格按吨存储,需转换为千克计价:当自定义元字段num_sal值为1000时,执行(原价 ÷ 1000) × 变体重量(kg)的价格计算;num_sal为其他值时保持原价
  • 要求修正后的价格在单品页面、购物车、结账环节同步生效

当前问题

  • 已通过JavaScript监听found_variation事件处理单品页价格显示,逻辑正常,但缺少num_sal字段的判断条件
  • 直接修改数据库元值不可行:无法标记是否已完成单位转换,且后续价格更新仍会按吨传入

当前使用的JavaScript代码

wc_enqueue_js( "     
   $(document).on('found_variation', 'form.cart', function( event, variation ) {
     if(variation.price_html)
     var variationprice = variation.display_price * 1.2;
     console.log(variation.display_price * 1.2);
     const formatter = new Intl.NumberFormat('fr-FR', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,            
      });

     var variationpriceTTC = formatter.format(variation.display_price * 1.2);
     console.log(variationpriceTTC);
     var variationpriceHT = formatter.format(variation.display_price);
     $('p.price').html(variationpriceHT + ' € HT - <span class=\"prixTTC\">' + variationpriceTTC + ' € TTC</span>');
     $('.woocommerce-variation-price').hide();
  });
  $(document).on('hide_variation', 'form.cart', function( event, variation ) {   
     $('p.price').html('" . $price . "');
  });
" );

完整解决方案

1. 将自定义元字段传入前端变体数据

默认WooCommerce不会把自定义元字段num_sal传递给前端的variation对象,需要通过PHP钩子添加:

add_filter( 'woocommerce_available_variation', 'add_custom_variation_meta_to_frontend', 10, 3 );
function add_custom_variation_meta_to_frontend( $variation_data, $product, $variation ) {
    // 把num_sal元字段加入变体数据
    $variation_data['num_sal'] = get_post_meta( $variation->get_id(), 'num_sal', true );
    // 确保变体重量也在数据中(默认可能已有,冗余处理避免异常)
    $variation_data['weight'] = $variation->get_weight();
    return $variation_data;
}

2. 修改JavaScript代码添加判断逻辑

在found_variation事件中加入num_sal的判断,仅当值为1000且重量有效时执行价格转换:

wc_enqueue_js( "     
   $(document).on('found_variation', 'form.cart', function( event, variation ) {
     // 初始化基础价格为原价
     let basePrice = variation.display_price;
     
     // 判断是否满足转换条件:num_sal=1000且重量大于0
     if (variation.num_sal == 1000 && variation.weight > 0) {
         basePrice = (variation.display_price / 1000) * variation.weight;
     }
     
     const formatter = new Intl.NumberFormat('fr-FR', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,            
      });

     var variationpriceTTC = formatter.format(basePrice * 1.2);
     var variationpriceHT = formatter.format(basePrice);
     $('p.price').html(variationpriceHT + ' € HT - <span class=\"prixTTC\">' + variationpriceTTC + ' € TTC</span>');
     $('.woocommerce-variation-price').hide();
  });
  $(document).on('hide_variation', 'form.cart', function( event, variation ) {   
     $('p.price').html('" . $price . "');
  });
" );

3. 同步购物车与结账价格

仅修改前端显示会导致后台价格不一致,需要通过PHP钩子修正购物车中的实际价格:

add_action( 'woocommerce_before_calculate_totals', 'adjust_cart_price_for_weight_conversion', 10, 1 );
function adjust_cart_price_for_weight_conversion( $cart ) {
    // 后台非AJAX请求直接返回
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $variation = $cart_item['data'];
        // 仅处理商品变体
        if ( ! $variation instanceof WC_Product_Variation ) continue;

        $num_sal = get_post_meta( $variation->get_id(), 'num_sal', true );
        $weight = $variation->get_weight();

        // 满足条件时调整价格
        if ( $num_sal == 1000 && $weight > 0 ) {
            $original_price = $variation->get_price();
            $adjusted_price = ( $original_price / 1000 ) * $weight;
            $variation->set_price( $adjusted_price );
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 03:58:14