/**
* Class RedPacket
* 根据总金额生成指定个人的随机红包数量:
* 1.最小金额0.01元;
* 2.每份红包的最大上限;
* 3.总金额不一定发放完毕,会存在剩余金额,按照业务流程自己处理。
*/
class RedPacket
{
//总金额
private $total = 0;
//红包数量
private $amount = 0;
//最小红包金额
private $min = 0.01;
//最大红包金额
private $max = 0.01;
public function __construct(float $total, int $amount, float $min = 0.01, float $max = 0.01)
{
$this->total = $total;
$this->amount = $amount;
$this->min = $min;
if ( $this->amount * $this->min > $total ) {
throw new \Exception('发放红包的总额超过了总金额!');
}
$this->max = $max;
}
/**
* 生成随机红包组
*
* @return array
* @throws \Exception
*/
public function getPacket() : array
{
$total = $this->total;
if ( $this->amount * $this->min > $total ) {
throw new \Exception('发放红包的总额超过了总金额!');
}
$redPacket = [];
for ($i = 1; $i < $this->amount; $i++) {
// 随机安全上限
$safe_total = ($total - ($this->amount - $i) * $this->min) / ($this->amount - $i);
if ( $this->min < $safe_total ) {
// 生成区间随机整数
$money = mt_rand($this->min * 100, $safe_total * 100) / 100;
} else {
$money = $this->min;
}
// 每份金额的最大额度上限限制
if ( $money > $this->max ) {
$money = $this->max;
}
$total = floatval($total - $money);
$redPacket[] = [
'money' => $money,
'surplus' => $total,
];
}
$surplus = 0;
// 每份金额的最大额度上限限制
if ( $total > $this->max ) {
$surplus = floatval($total - $this->max);
$total = $this->max;
}
// 最后一份红包数据
$redPacket[] = [
'money' => $total,
'surplus' => $surplus,
];
return $redPacket;
}
}
评论/回复