在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
相关产品推荐
相关产品推荐

