PHP群:95885625 Hbuilder+MUI群:81989597 站长QQ:634381967
    您现在的位置: 首页 > 开发编程 > PHP教程 > 正文

    PHP 实现微信红包拆分算法

    作者:admin来源:网络浏览:时间:2018-04-07 20:47:32我要评论
    分享到
    导读:PHP 实现微信红包拆分算法<?php/***红包分配算法**example*$coupon=newCoupon(200,5);*$res=$coupon->handle();*print_r($res);**@authorF...
    PHP 实现微信红包拆分算法

    1. <?php 
    2. /** 
    3.  * 红包分配算法 
    4.  * 
    5.  * example 
    6.  *      $coupon = new Coupon(200, 5); 
    7.  *      $res = $coupon->handle(); 
    8.  *      print_r($res); 
    9.  * 
    10.  * @author Flc <2018-04-06 20:09:53> 
    11.  * @see http://flc.ren | http://flc.io | https://github.com/flc1125 
    12.  */ 
    13. class Coupon 
    14.     /** 
    15.      * 红包金额 
    16.      * 
    17.      * @var float 
    18.      */ 
    19.     protected $amount
    20.  
    21.     /** 
    22.      * 红包个数 
    23.      * 
    24.      * @var int 
    25.      */ 
    26.     protected $num
    27.  
    28.     /** 
    29.      * 领取的红包最小金额 
    30.      * 
    31.      * @var float 
    32.      */ 
    33.     protected $coupon_min
    34.  
    35.     /** 
    36.      * 红包分配结果 
    37.      * 
    38.      * @var array 
    39.      */ 
    40.     protected $items = []; 
    41.  
    42.     /** 
    43.      * 初始化 
    44.      * 
    45.      * @param float $amount     红包金额(单位:元)最多保留2位小数 
    46.      * @param int   $num        红包个数 
    47.      * @param float $coupon_min 每个至少领取的红包金额 
    48.      */ 
    49.     public function __construct($amount$num = 1, $coupon_min = 0.01) 
    50.     { 
    51.         $this->amount = $amount
    52.         $this->num = $num
    53.         $this->coupon_min = $coupon_min
    54.     } 
    55.  
    56.     /** 
    57.      * 处理返回 
    58.      * 
    59.      * @return array 
    60.      */ 
    61.     public function handle() 
    62.     { 
    63.         // A. 验证 
    64.         if ($this->amount < $validAmount = $this->coupon_min * $this->num) { 
    65.             throw new Exception('红包总金额必须≥'.$validAmount.'元'); 
    66.         } 
    67.  
    68.         // B. 分配红包 
    69.         $this->apportion(); 
    70.  
    71.         return [ 
    72.             'items' => $this->items, 
    73.         ]; 
    74.     } 
    75.  
    76.     /** 
    77.      * 分配红包 
    78.      */ 
    79.     protected function apportion() 
    80.     { 
    81.         $num = $this->num;  // 剩余可分配的红包个数 
    82.         $amount = $this->amount;  //剩余可领取的红包金额 
    83.  
    84.         while ($num >= 1) { 
    85.             // 剩余一个的时候,直接取剩余红包 
    86.             if ($num == 1) { 
    87.                 $coupon_amount = $this->decimal_number($amount); 
    88.             } else { 
    89.                 $avg_amount = $this->decimal_number($amount / $num);  // 剩余的红包的平均金额 
    90.  
    91.                 $coupon_amount = $this->decimal_number( 
    92.                     $this->calcCouponAmount($avg_amount$amount$num
    93.                 ); 
    94.             } 
    95.  
    96.             $this->items[] = $coupon_amount// 追加分配 
    97.  
    98.             $amount -= $coupon_amount
    99.             --$num
    100.         } 
    101.  
    102.         shuffle($this->items);  //随机打乱 
    103.     } 
    104.  
    105.     /** 
    106.      * 计算分配的红包金额 
    107.      * 
    108.      * @param float $avg_amount 每次计算的平均金额 
    109.      * @param float $amount     剩余可领取金额 
    110.      * @param int   $num        剩余可领取的红包个数 
    111.      * 
    112.      * @return float 
    113.      */ 
    114.     protected function calcCouponAmount($avg_amount$amount$num
    115.     { 
    116.         // 如果平均金额小于等于最低金额,则直接返回最低金额 
    117.         if ($avg_amount <= $this->coupon_min) { 
    118.             return $this->coupon_min; 
    119.         } 
    120.  
    121.         // 浮动计算 
    122.         $coupon_amount = $this->decimal_number($avg_amount * (1 + $this->apportionRandRatio())); 
    123.  
    124.         // 如果低于最低金额或超过可领取的最大金额,则重新获取 
    125.         if ($coupon_amount < $this->coupon_min 
    126.             || $coupon_amount > $this->calcCouponAmountMax($amount$num
    127.         ) { 
    128.             return $this->calcCouponAmount($avg_amount$amount$num); 
    129.         } 
    130.  
    131.         return $coupon_amount
    132.     } 
    133.  
    134.     /** 
    135.      * 计算分配的红包金额-可领取的最大金额 
    136.      * 
    137.      * @param float $amount 
    138.      * @param int   $num 
    139.      */ 
    140.     protected function calcCouponAmountMax($amount$num
    141.     { 
    142.         return $this->coupon_min + $amount - $num * $this->coupon_min; 
    143.     } 
    144.  
    145.     /** 
    146.      * 红包金额浮动比例 
    147.      */ 
    148.     protected function apportionRandRatio() 
    149.     { 
    150.         // 60%机率获取剩余平均值的大幅度红包(可能正数、可能负数) 
    151.         if (rand(1, 100) <= 60) { 
    152.             return rand(-70, 70) / 100; // 上下幅度70% 
    153.         } 
    154.  
    155.         return rand(-30, 30) / 100; // 其他情况,上下浮动30%; 
    156.     } 
    157.  
    158.     /** 
    159.      * 格式化金额,保留2位 
    160.      * 
    161.      * @param float $amount 
    162.      * 
    163.      * @return float 
    164.      */ 
    165.     protected function decimal_number($amount
    166.     { 
    167.         return sprintf('%01.2f'round($amount, 2)); 
    168.     } 
    169.  
    170. // 例子 
    171. $coupon = new Coupon(200, 5, 30); 
    172. $res = $coupon->handle(); 
    173. print_r($res); 

     

    转载请注明(B5教程网)原文链接:http://www.bcty365.com/content-10-6260-1.html
    相关热词搜索: 微信红包
    网友评论: