mMatchMoney = 0; $moneys = []; foreach ($rates_moneys as $rate => $money) { if($rate == self::match_rate) { $this->mMatchMoney += $money; } else { $val = []; $val['rate'] = $rate; $val['amount'] = $money; $moneys[] = $val; } } uasort($moneys,['\bonus\scaler','rate_desc']); //todo modify usort $this->mMoneys = []; foreach ($moneys as $item) { $this->mMoneys[] = $item; } } private function match_money() { return $this->mMatchMoney * 100 / self::match_rate; } public function calc() { $total = $this->match_money(); $count = count($this->mMoneys); if($count == 0) { return $this->format($total); } $max_rate = $this->mMoneys[0]['rate']; if($max_rate < self::match_rate) { return $this->format($total); } for($pos = $count - 1; $pos >= 0;) { $ret = $this->_calc($pos); if($ret == false) { $pos--; } else { $total += $ret; $total = intval($total * 100 + 0.5) / 100; return $this->format($total); } } return $this->format($total); } private function format($total) { $total = intval($total * 100 + 0.5); if($total == 0) { return false; } else { return $total / 100; } } private function _calc($pos) { $rate = $this->mMoneys[$pos]['rate']; $amount = $this->mMoneys[$pos]['amount']; $y = intval($amount * 100 + 0.5); if($rate > self::match_rate) { //满足条件,用0折扣红包抵扣 $this->_calc_AB($pos + 1,$A,$B); return $B + ($A* 100 - self::match_rate * $B) / (self::match_rate); } else { $this->_calc_AB($pos,$A,$B); $need_amount = ($A * 100 - self::match_rate * $B) * $rate / ((self::match_rate - $rate) * 100); $x = intval($need_amount * 100 + 0.5); if($x < 0) { //此时达不到匹配的折扣率 return false; } elseif($x == 0) { //前一个恰好抵扣 return $B; } else { if($x <= $y) { //当前不满足全部抵扣 return $B + ($x / $rate); } else { //当前还需要用0折扣红包抵扣 $this->_calc_AB($pos + 1,$A,$B); return $B + ($A * 100 - self::match_rate * $B) / (self::match_rate); } } } } private function _calc_AB($pos,&$A,&$B) { $A = 0; for ($i = 0; $i < $pos; $i++) { $amount = $this->mMoneys[$i]['amount']; $A += $amount; } $B = 0; for ($i = 0; $i < $pos; $i++) { $amount = $this->mMoneys[$i]['amount']; $rate = $this->mMoneys[$i]['rate']; $B += $amount * 100 / $rate; } } static public function rate_desc($left,$right) { $t_l = intval($left['rate']); $t_r = intval($right['rate']); if($t_l > $t_r) return -1; elseif($t_l < $t_r) return 1; else return 0; } }