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

WooCommerce促销徽章折扣百分比无法取整问题修复请求

WooCommerce促销徽章折扣百分比取整问题修复

问题说明

开发WooCommerce单产品页面促销徽章功能时,徽章显示的折扣百分比为非整数(如40.2%),需要取整为整数(如40%)。现有代码已包含round()取整逻辑,但未生效。

问题定位

  1. 可变产品(Variable Product)折扣计算未取整:在add_percentage_to_sale_badge函数的可变产品分支中,计算百分比时未调用round(),直接将原始计算值存入数组,导致最终最大值包含小数。
  2. 产品变体折扣精度设置错误:custom_variation_price_saving_percentage函数中,round()的第二个参数设为1,会保留1位小数,而非整数。
  3. 函数嵌套错误:juvelyrine_meta_viewport函数被嵌套在custom_variation_price_saving_percentage内部,导致该函数无法正确注册执行,可能引发逻辑异常。

修复后的完整代码

// For simple products
add_filter( 'woocommerce_get_price_html', 'change_displayed_sale_price_html', 10, 2 );
function change_displayed_sale_price_html( $price, $product ) {
     // Only on sale products on frontend and excluding min/max price on variable products
    if( $product->is_on_sale() && ! is_admin() && $product->is_type('simple') ){
         // Get product prices
         $regular_price = (float) $product->get_regular_price(); // Regular price
         $sale_price = (float) $product->get_price(); // Active price (the "Sale price" when on-sale)

         // "Saving Percentage" calculation and formatting
         $precision = 0; // Max number of decimals
         $saving_percentage = round( 100 - ( $sale_price / $regular_price * 100 ), $precision ) . '%';

         // Append to the formated html price
         $price .= sprintf( __('<ins><p class="nuolaida">%s</p></ins>', 'woocommerce' ), $saving_percentage );
    }
    return $price;
}

// 修复嵌套函数问题,独立注册viewport钩子
function juvelyrine_meta_viewport() {
    echo '<!--<meta name="viewport" content="width=device-width, initial-scale=1">-->';
}
add_action( 'wp_head', 'juvelyrine_meta_viewport', 1 );

// For product variations
add_filter( 'woocommerce_available_variation', 'custom_variation_price_saving_percentage', 10, 3 );
function custom_variation_price_saving_percentage( $data, $product, $variation ) {
    $active_price  = $data['display_price'];
    $regular_price = $data['display_regular_price'];

    if( $active_price !== $regular_price ) {
        // 修改精度为0,取整为整数
        $saving_percentage = round( 100 - ( $active_price / $regular_price * 100 ), 0 ) . '%';
        $data['price_html'] .= sprintf( __('<p class="nuolaida2">%s</p>', 'woocommerce' ), $saving_percentage );
    }
    return $data;
}


add_filter( 'woocommerce_sale_flash', 'add_percentage_to_sale_badge', 20, 3 );
function add_percentage_to_sale_badge( $html, $post, $product ) {

  if( $product->is_type('variable')){
      $percentages = array();

      // Get all variation prices
      $prices = $product->get_variation_prices();

      // Loop through variation prices
      foreach( $prices['price'] as $key => $price ){
          // Only on sale variations
          if( $prices['regular_price'][$key] !== $price ){
              // 对每个变体的折扣百分比进行取整
              $percentage = round( ( floatval( $prices['regular_price'][ $key ] ) - floatval( $price ) ) / floatval( $prices['regular_price'][ $key ] ) * 100 );
              $percentages[] = $percentage;
          }
      }
      // We keep the highest value
      $percentage = max($percentages) . '%';

  } elseif( $product->is_type('grouped') ){
      $percentages = array();

      // Get all variation prices
      $children_ids = $product->get_children();

      // Loop through variation prices
      foreach( $children_ids as $child_id ){
          $child_product = wc_get_product($child_id);

          $regular_price = (float) $child_product->get_regular_price();
          $sale_price    = (float) $child_product->get_sale_price();

          if ( $sale_price != 0 || ! empty($sale_price) ) {
              // Calculate and set in the array the percentage for each child on sale
              $percentages[] = round(100 - ($sale_price / $regular_price * 100));
          }
      }
      // We keep the highest value
      $percentage = max($percentages) . '%';

  } else {
      $regular_price = (float) $product->get_regular_price();
      $sale_price    = (float) $product->get_sale_price();

      if ( $sale_price != 0 || ! empty($sale_price) ) {
          $percentage    = round(100 - ($sale_price / $regular_price * 100)) . '%';
      } else {
          return $html;
      }
  }
  return '<span class="onsale">' . esc_html__( 'SALE', 'woocommerce' ) . ' ' . $percentage . '</span>';
}

修复要点

  • 将嵌套的juvelyrine_meta_viewport函数移到外部,确保钩子能正确注册。
  • 在可变产品的折扣计算循环中,对每个变体的百分比执行round()取整后再存入数组。
  • 修改custom_variation_price_saving_percentage函数中round()的精度参数为0,确保变体的折扣显示为整数百分比。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:35:11