返回
WooCommerce批量定价: 不同分类商品总数分级定价
php
2025-03-18 16:42:05
WooCommerce 不同分类商品总数批量定价的解决方案
购物车中不同ID的商品,加起来满足特定数量范围就应用分级价格,这需求听起来有点复杂,别慌,咱们一步步拆解。
一、 问题拆解与原因分析
你想实现的是:将购物车里不同分类(或者更精确地说,不同产品ID)的商品数量加总,根据总数落入哪个区间,来应用不同的单价。
问题关键点 :
- 商品分组: 需要把不同类别的商品(根据ID区分)划分到不同的组(比如你例子中的List A和List B)。
- 数量统计: 要统计每个分组的商品总数量。
- 分级定价: 预先设定好每个分组的阶梯价格规则。
- 价格应用: 根据总数,应用相应的价格到对应分组的商品。
你之前代码的问题出在哪?
- 第一次尝试:
woocommerce_before_cart
这个钩子,时机太早了。它在购物车页面展示之前触发,这时候修改价格可能不稳定, 也容易和其他插件冲突, 导致无法完成订单。 - 第二种尝试:
woocommerce_before_calculate_totals
钩子时机对了,但是你获取的是get_sale_price()
(促销价), 你可能只想影响正常价格 (get_regular_price()
)。 而且用set_price
会同时影响正常价格与促销价,不严谨。
二、解决方案
咱直接上改进后的代码,然后在代码里详细讲解原理和步骤:
add_action( 'woocommerce_before_calculate_totals', 'custom_bulk_pricing', 20, 1 );
function custom_bulk_pricing( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// 防重复触发
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// 1. 定义分组和价格规则 (你可以根据需要修改)
$groups = array(
'group_a' => array(
'ids' => array( 351, 916, 825, 528, 527, 524, 192, 190, 188, 186, 184, 182, 180, 178, 70, 68, 66, 64 ),
'tiers' => array(
array( 'min' => 1, 'max' => 99, 'price' => 0.20 ),
array( 'min' => 100, 'max' => 199, 'price' => 0.18 ),
array( 'min' => 200, 'max' => 99999, 'price' => 0.14 ), // 假设一个很大的上限
),
),
'group_b' => array(
'ids' => array( 4, 5, 6 ), // 示例ID, 替换为你自己的
'tiers' => array(
array( 'min' => 1, 'max' => 99, 'price' => 0.30 ),
array( 'min' => 100, 'max' => 199, 'price' => 0.28 ),
array( 'min' => 200, 'max' => 99999, 'price' => 0.20 ),
),
),
// 还可以添加更多分组...
);
// 2. 遍历购物车,统计每个分组的总数量
$group_totals = array();
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
$quantity = $cart_item['quantity'];
foreach ( $groups as $group_key => $group ) {
if ( in_array( $product_id, $group['ids'] ) ) {
if ( ! isset( $group_totals[ $group_key ] ) ) {
$group_totals[ $group_key ] = 0;
}
$group_totals[ $group_key ] += $quantity;
break; // 找到分组就跳出内层循环
}
}
}
// 3. 再次遍历购物车, 应用价格.
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
//print_r($product_id);
foreach ( $groups as $group_key => $group ) {
if ( in_array( $product_id, $group['ids'] ) ) {
$total_quantity = $group_totals[ $group_key ];
$new_price = null;
//print_r($group);
// 查找对应的价格区间
foreach ( $group['tiers'] as $tier ) {
if ( $total_quantity >= $tier['min'] && $total_quantity <= $tier['max'] ) {
$new_price = $tier['price'];
break;
}
}
if ( $new_price !== null ) {
// 仅设置正常价格. 如果想修改其他,请更改 'regular' 到 'sale',或其他价格的key.
$cart_item['data']->set_price( $new_price);
//$cart_item['data']->set_regular_price($new_price );
//$cart_item['data']->set_sale_price($new_price );
}
break; // 找到分组就跳出内层循环
}
}
}
}
代码解释:
-
分组与规则定义(
$groups
):- 用一个数组来定义所有分组。
- 每个分组(如
group_a
、group_b
)包含:ids
: 该组包含的所有商品 ID。tiers
: 该组的价格阶梯。每个阶梯包含:min
(最小数量)、max
(最大数量)、price
(单价)。
-
统计分组总数(
$group_totals
):- 第一次遍历购物车:对每个商品,判断它属于哪个分组,累加到对应分组的总数。
- 如果找不到就什么也不做。
-
再次遍历并找到对应的组和价格信息
* 查找对一个的ID并且设置总价。 * 根据`$group_totals` 的总数找到合适的`$new_price` 。 * 检查 `$new_price` 是否有找到价格区间
-
应用价格
set_price
设置正常价格。- 如果有其他价格设置的需求,更换成其他的
set_
方法即可。 - 找到对应的id就设置一个对应的总价。
使用方法 & 步骤:
- 复制代码: 将上述代码复制到你的主题的
functions.php
文件中(或者通过Code Snippets插件添加)。 - 修改配置:
- 在
$groups
数组中,根据你的实际需求,修改分组的 ID (ids
) 和价格阶梯 (tiers
)。 - 可以根据需要,添加更多分组。
- 在
- 测试: 清空购物车,添加不同分组的商品,看看购物车和结账页面的价格是否正确。
额外建议与进阶技巧 :
- 性能优化: 如果你的商品和分组非常多,上述双重循环可能会影响性能。可以考虑用商品ID作为数组的键,直接查找,避免内层循环。
- 缓存: 如果分组和价格规则不经常变动, 可以考虑将
$groups
数组的结果缓存起来(比如用 WordPress 的 Transients API),减少每次计算的开销。 - 用户界面: 如果你希望这个功能更灵活,可以在后台添加一个设置页面,让管理员可以方便地配置分组和价格规则,不用每次都修改代码。
- 排除特定商品: 你可以在循环中添加额外的条件判断,排除某些特定商品(比如特价商品)不参与批量定价。
- 与促销活动结合 : 你可能需要考虑这个批量定价功能与 WooCommerce 其他促销活动(比如优惠券)的叠加规则。可以在应用价格之前,先获取商品的原始价格,根据需要进行一些计算。
错误处理与调试 :
如果发现没有效果,价格不对:
- 开启调试: 在
wp-config.php
文件中,将WP_DEBUG
设置为true
,开启调试模式,可能会显示错误信息。 - 检查代码: 仔细检查
$groups
数组中的 ID 和价格规则是否正确。 - 检查商品ID: 用
print_r($product_id)
语句,确保正确的判断每个商品的所属分组。
祝你顺利实现 WooCommerce 的批量定价功能!