请问一下,这种返利有什么好的写法吗?

/**
*      {
            "amount": "1000.0000",
            "percent": 12
        },
        {
            "amount": "1500.0000",
            "percent": 15
        },
        {
            "amount": "2000.0000",
            "percent": 24
        }
*
*/
//假如有以上配置,例如:充值1000元返利12%,1500元返利15%,2000元返利24%,若用户充值4500元,2000*24%+1500*15%+1000*12%
//假如充值8000,计算规则就是,8000 * 24%,假如是9500,计算规则就是:8000*24% + 1500*15%

请问一下,计算通过配置计算得到具体的返利金额是多少,应该这么写呢?(配置是灵活可变的)

心之所向,素履以往。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 14
laravel_peng

不知道你说的是不是这种?

file

  • 表字段使用 json 格式的。
  • form 表单中使用多组 key => val 的表单组件。(这个需要写一些 js )。
  • 可以参考这个在 Dcat Admin 中有对应的使用 JSON表单

如果是计算的话,那就这种了。

public function getRebate($chargePrice)
{
  // 此配置写死了,正常应该查询获取
  $config = [
      [
          "amount" => "1000.0000",
          "percent" =>12
      ],
      [
          "amount" => "1500.0000",
          "percent" =>15
      ],
      [
          "amount" => "2000.0000",
          "percent" =>24
      ],
  ];
  // 如果配置为空返回 0 
  if (empty($config)) {
       return 0;
  }
  // 尽量走这一步,让配置按 amount 金额升序
  $amountArr = array_column($config,'amount');
  array_multisort($amountArr, SORT_ASC, $config);
  $rebateMoney = 0;
  foreach ($config as $key => $val) {
    if ($chargePrice < $val['amount']) {
      break;
    }
    $rebateMoney += bcmul($val['amount'], $val['percent']*0.01, 4);
    unset($config[$k]);
  }

  return $rebateMoney;
}
2年前 评论
lmdfx (楼主) 2年前
giao哥

4500 给前面一样配置, 计算出返利比例。

2年前 评论

如果是充值4800,怎么计算

2年前 评论
lmdfx (楼主) 2年前

是每个配置在充值金额上都只会享受一次?

// 充值金额
$amount = 4500;

// 返利金额
$percent = 0;

// 假设如下配置
$config = [
    [
        'amount' => 1000,
        'percent' => 12,
    ],
    [
        'amount' => 1500,
        'percent' => 15,
    ],
    [
        'amount' => 2000,
        'percent' => 24,
    ]
];

while(count($config))
{
    // 从下往上只匹配一次
    $configItem = array_pop($config);

    // 如果满足金额
    if($amount >= $configItem['amount']) {
        // 累加返利
        $percent += $configItem['amount'] * ($configItem['percent'] / 100);
        // 减掉本次返利匹配金额
        $amount -= $configItem['amount'];
    }
}

var_dump($percent);
2年前 评论
畅畅 (作者) 2年前
AloneUtopia

写个计算当前金额所满足最大档返利的方法,然后递归

2年前 评论

这就写个 for 循环处理呗,还有啥好办法

<?php 
$bonus_list = [
    [
        "amount" => "1000.0000",
        "percent" => 12
    ],
    [
        "amount" => "1500.0000",
        "percent" => 15
    ],
    [
        "amount" => "2000.0000",
        "percent" => 24,
    ]
];
$recharge_num = 4500;
$sum = 0;
foreach($bonus_list as $v)
{
    if($v['amount'] <= $recharge_num)
    {
        $sum = bcadd($sum, bcmul($v["amount"], bcdiv($v["percent"], 100, 2), 2));
    }
}
echo $sum;

奖金列表就存个 json 字段就行了。

2年前 评论

读取配置,foreach循环配置,循环内计算金额。 :joy:

2年前 评论
/**
*      {
            "amount": "1000.0000",
            "percent": 14
        },
        {
            "amount": "1500.0000",
            "percent": 15
        },
        {
            "amount": "2000.0000",
            "percent": 16
        }
        假如以上配置,用户充值2500,那有一下两种规则:
        1、大额原则:2000x0.16=320
        2、优惠原则:1500x0.15+1000x0.14=365
        你的需求是哪个呢?
*/
2年前 评论

:joy:看到4位小数,有点慌,之前被精度丢失搞的焦头烂额!

2年前 评论

感觉要倒序一下,鬼知道运营会不会乱写

$datas = [
    ['amount' => 1000, 'percent' => 12],
    ['amount' => 800, 'percent' => 2],
    ['amount' => 2000, 'percent' => 50],
];

$inputNum = 3000;
$result = 0;

$query = collect($datas);
$sortData = $query->sortBy('amount', SORT_ASC);


foreach ($sortData as $key => $val) {
    if ($val['amount'] > $inputNum) break;
    $result += bcmul($val['amount'] / 100, $val['percent'], 2);
    echo $val['amount'] . '*' . $val['percent'] . '%+';
}

echo '等于' . $result;

Laravel

2年前 评论
/**
     * Desc: 充值返利按照规则计算:例如:充值3000元返利24%(720),1500元返利15%(225),1000元返利12%(120)
     * @param $input
     * @param $config
     * @return float|int|string
     */
    protected function calcMoney($input, $config): float|int|string
    {
        //8000   6000 * 0.24 + 2000 * 0.15 = 300+1440
        //7000   6000 * 0.24 + 1000 * 0.12 = 120+1440
        $money = 0.0000;
        $numConfig = array_column($config, 'amount');//$config在进来之前进行了按照amount倒序处理
        foreach ($config as $k=>$value) {
            if($input >= $value['amount']) {
                $calcAmountRemaining = $input % $value['amount'];
                //判断剩余金额是否还可能参加剩余所有阶段返利
                $is = false;
                if(!empty($config[$k+1]['amount'])) {
                    unset($numConfig[$k]);
                    foreach ($numConfig as $itemConfig) {
                        if($calcAmountRemaining >=$itemConfig) {
                            $is = true;
                            break;
                        }
                    }
                }
                if($is) {
                    //获取该阶梯最大计算金额
                    $maxCalcAmount = $input - $calcAmountRemaining;
                } else {
                    $maxCalcAmount = $input;
                }
                var_dump($maxCalcAmount, $value['percent']);
                $add = bcmul((string)$maxCalcAmount,(string)($value['percent']/100),4);
                $money = bcadd((string)$money, $add,4);
                $input = $calcAmountRemaining;
            }
        }

        return $money;
    }

应该是这样写,但是不知道有没有什么问题 :joy:

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!