118 lines
3.5 KiB
PHP
118 lines
3.5 KiB
PHP
|
|
<?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 CreateNewYearPacket implements ShouldQueue
|
|||
|
|
{
|
|||
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|||
|
|
protected $count;
|
|||
|
|
protected $total_packet;
|
|||
|
|
public $tries = 1;
|
|||
|
|
/**
|
|||
|
|
* Create a new job instance.
|
|||
|
|
*
|
|||
|
|
* @return void
|
|||
|
|
*/
|
|||
|
|
public function __construct($array)
|
|||
|
|
{
|
|||
|
|
$this->count = $array['count'];
|
|||
|
|
$this->total_packet = $array['total_packet'];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Execute the job.
|
|||
|
|
*
|
|||
|
|
* @return void
|
|||
|
|
*/
|
|||
|
|
public function handle()
|
|||
|
|
{
|
|||
|
|
//红包数
|
|||
|
|
$count = $this->count;
|
|||
|
|
//红包总金额
|
|||
|
|
$total_packet = $this->total_packet;
|
|||
|
|
$max_price = 0.3;
|
|||
|
|
$min_price = 0.3;
|
|||
|
|
$packet_arr = $this->rand_section($min_price, $max_price, $count, $total_packet);
|
|||
|
|
// $packet_arr = $this->redpack($total_packet, $count, $min_price, $max_price);
|
|||
|
|
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;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
public function redpack($total_money, $total_people, $min_money, $max_money)
|
|||
|
|
{
|
|||
|
|
$ret = array();
|
|||
|
|
$new_ret = array();
|
|||
|
|
$total_real_money = $total_money - $total_people * $min_money;
|
|||
|
|
$ret[0] = 0;
|
|||
|
|
for ($i = 1; $i < $total_people; $i++) {
|
|||
|
|
$ret[$i] = $this->get_rand($ret[$i - 1], $total_real_money, ($max_money - $min_money));
|
|||
|
|
}
|
|||
|
|
sort($ret);
|
|||
|
|
for ($j = 0; $j < count($ret); $j++) {
|
|||
|
|
if ($j == count($ret) - 1) {
|
|||
|
|
$new_ret[count($ret) - 1] = $total_real_money - $ret[count($ret) - 1] + $min_money;
|
|||
|
|
} else {
|
|||
|
|
$new_ret[] = $ret[$j + 1] - $ret[$j] + $min_money;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
shuffle($new_ret);
|
|||
|
|
$data = [];
|
|||
|
|
foreach ($new_ret as $ret) {
|
|||
|
|
$arr = [];
|
|||
|
|
$arr['price'] = $ret;
|
|||
|
|
$arr['created_at']=date('Y-m-d H:i:s');
|
|||
|
|
$arr['updated_at']=date('Y-m-d H:i:s');
|
|||
|
|
$data[] = $arr;
|
|||
|
|
}
|
|||
|
|
return $data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
public function get_rand($start, $end, $max)
|
|||
|
|
{
|
|||
|
|
$tmp = rand($start, $end);
|
|||
|
|
$total_max = $start + $max;
|
|||
|
|
if ($tmp > ($total_max) || empty($tmp)) {
|
|||
|
|
return $this->get_rand($start, $end, $max);
|
|||
|
|
} else {
|
|||
|
|
return $tmp;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|