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

如何为特定用户角色的指定产品实现阶梯批量折扣及多规则配置?

问题分析与解决方案

一、当前代码存在的问题

  1. 折扣触发逻辑错误:仅当合格商品数量为10的倍数时才触发折扣,导致10-19、20-29等区间的订单无法享受前批次的折扣,完全不符合需求中的阶梯规则。
  2. 重复添加折扣费用:代码中两次调用$cart->add_fee(),会导致折扣金额被重复计算,最终显示的折扣是实际应得的两倍。
  3. 折扣计算范围错误:使用购物车总金额$subtotal计算折扣,而非仅针对符合条件的商品金额,会将非折扣商品的金额也纳入折扣计算,导致折扣金额不准确。
  4. 扩展性极差:硬编码了5%的折扣值,无法快速新增或修改折扣规则;克隆函数修改参数无效是因为重复注册了相同钩子,后注册的函数会覆盖前一个。

二、解决方案代码

以下代码实现了特定用户角色+指定商品的阶梯折扣,同时支持灵活配置多种折扣规则:

function apply_quantity_discounts($cart) {
    // 后台页面直接返回,不执行折扣逻辑
    if (is_admin() && !defined('DOING_AJAX')) return;

    // 配置参数
    $discount_roles = array('wholesale_customer'); // 可享受折扣的用户角色
    $discount_product_ids = array(383, 411, 412); // 可享受折扣的商品ID
    // 折扣规则:按优先级从高到低排序(优先级高的放在前面)
    $discount_rules = array(
        // 规则1:购买15件及以上,全部商品享7%折扣
        array(
            'min_qty' => 15,
            'max_qty' => PHP_INT_MAX,
            'discount_percent' => 7,
            'apply_scope' => 'all' // 应用范围:全部合格商品
        ),
        // 规则2:购买12-14件,全部商品享4%折扣
        array(
            'min_qty' => 12,
            'max_qty' => 14,
            'discount_percent' => 4,
            'apply_scope' => 'all'
        ),
        // 规则3:原需求阶梯折扣:每10件为一个批次,仅完整批次享5%折扣
        array(
            'min_qty' => 10,
            'max_qty' => PHP_INT_MAX,
            'discount_percent' => 5,
            'apply_scope' => 'batches' // 应用范围:每10件为一个批次
        )
    );

    // 获取当前用户角色
    $current_user = wp_get_current_user();
    $user_has_eligible_role = !empty(array_intersect($current_user->roles, $discount_roles));
    if (!$user_has_eligible_role) return;

    // 计算合格商品的总数量和总金额
    $eligible_total_qty = 0;
    $eligible_total_amount = 0;
    foreach ($cart->get_cart() as $item) {
        $product_id = $item['product_id'];
        if (in_array($product_id, $discount_product_ids)) {
            $qty = $item['quantity'];
            $price = $item['data']->get_price();
            $eligible_total_qty += $qty;
            $eligible_total_amount += $qty * $price;
        }
    }

    if ($eligible_total_qty <= 0) return;

    // 匹配最优折扣规则
    $applied_rule = null;
    foreach ($discount_rules as $rule) {
        if ($eligible_total_qty >= $rule['min_qty'] && $eligible_total_qty <= $rule['max_qty']) {
            $applied_rule = $rule;
            break; // 取第一个匹配的高优先级规则
        }
    }

    if (!$applied_rule) return;

    // 计算折扣金额
    $discount_amount = 0;
    switch ($applied_rule['apply_scope']) {
        case 'all':
            // 全部合格商品享受折扣
            $discount_amount = $eligible_total_amount * ($applied_rule['discount_percent'] / 100);
            break;
        case 'batches':
            // 按10件批次计算:仅完整批次享受折扣
            $batch_amount = 0;
            foreach ($cart->get_cart() as $item) {
                $product_id = $item['product_id'];
                if (in_array($product_id, $discount_product_ids)) {
                    $qty = $item['quantity'];
                    $price = $item['data']->get_price();
                    $item_batches = floor($qty / 10);
                    $batch_amount += $item_batches * 10 * $price;
                }
            }
            $discount_amount = $batch_amount * ($applied_rule['discount_percent'] / 100);
            break;
    }

    if ($discount_amount > 0) {
        // 添加折扣到购物车,只添加一次
        $cart->add_fee('Descuento por cantidad', -$discount_amount, true);
        // 第三个参数true表示该费用是含税的,根据需求调整
    }
}
add_action('woocommerce_cart_calculate_fees', 'apply_quantity_discounts');

三、代码说明

  1. 配置灵活性:

    • 支持配置多个用户角色、多个商品ID
    • 折扣规则采用数组配置,可自由新增/修改规则,按顺序优先级匹配(前面的规则优先级更高)
    • 规则支持两种应用范围:all(全部商品)和batches(按10件批次)
  2. 逻辑修复:

    • 仅针对合格商品的数量和金额计算折扣,避免非折扣商品干扰
    • 移除重复添加折扣的代码,确保折扣金额准确
    • 阶梯批次折扣逻辑:按每个商品的实际购买数量计算完整批次,再计算对应折扣,确保多商品混合购买时的准确性
  3. 扩展性优化:

    • 新增规则只需在$discount_rules数组中添加新的规则项即可,无需修改核心逻辑
    • 解决了克隆函数无效的问题:只需在同一个函数中配置所有规则,无需重复注册钩子

内容的提问来源于stack exchange,提问作者unity-student

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:42:46