love_php/app/Jobs/CreateParticipantPacket.php
2026-04-02 09:20:51 +08:00

120 lines
3.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Models\ParticipantRedPacket;
class CreateParticipantPacket implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $min;
protected $max;
protected $num;
protected $total;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($data)
{
$this->min = $data['min'];
$this->max = $data['max'];
$this->num = $data['num'];
$this->total = $data['total'];
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$min = $this->min;
$max = $this->max;
$num = $this->num;
$total = $this->total;
if ($max) {
$packet_arr = $this->rand_section($min, $max, $num, $total);
}else{
$packet_arr = $this->demo($total, $num, $min);
}
ParticipantRedPacket::insert($packet_arr);
}
public function rand_section($min,$max,$num,$total){
$data = array();
if ($min * $num > $total) {
return array();
}
if($max*$num < $total){
return array();
}
while ($num >= 1) {
$num--;
$kmix = max($min, $total - $num * $max);
$kmax = min($max, $total - $num * $min);
$kAvg = $total / ($num + 1);
//获取最大值和最小值的距离之间的最小值
$kDis = min($kAvg - $kmix, $kmax - $kAvg);
//获取0到1之间的随机数与距离最小值相乘得出浮动区间这使得浮动区间不会超出范围
$r = ((float)(rand(1, 10000) / 10000) - 0.5) * $kDis * 2;
$k = sprintf("%.2f", $kAvg + $r);
$total -= $k;
// $data[] = $k;
$arr = [];
$arr['price'] = $k;
$arr['created_at']=date('Y-m-d H:i:s');
$arr['updated_at']=date('Y-m-d H:i:s');
$data[] = $arr;
}
return $data;
}
function demo($total, $num, $min = 0.01)
{
$overPlus = $total - $num * $min; // 剩余待发钱数
$base = 0; // 总基数
// 存放所有人数据
$container = array();
// 每个人保底
for ($i = 0; $i < $num; $i++) {
// 计算比重
$weight = round(lcg_value() * 1000);
$container[$i]['weight'] = $weight; // 权重
$container[$i]['money'] = $min; // 最小值都塞进去
$base += $weight; // 总基数
}
$len = $num - 1; // 下面要计算总人数-1的数据,
for ($i = 0; $i < $len; $i++) {
$money = floor($container[$i]['weight'] / $base * $overPlus * 100) / 100; // 向下取整,否则会超出
$container[$i]['money'] += $money;
}
// 弹出最后一个元素
array_pop($container);
$result = array_column($container, 'money');
$last_one = round($total - array_sum($result), 2);
array_push($result, $last_one);
$data = [];
foreach ($result as $res) {
$arr = [];
$arr['price'] = $res;
$arr['created_at']=date('Y-m-d H:i:s');
$arr['updated_at']=date('Y-m-d H:i:s');
$data[] = $arr;
}
return $data;
}
}