= $lowest_cent) { return ($bonus_cent - $lowest_cent) / 100; } else { return 0; } } public function order_cash($goods_price, $goods_lowest_price) { return $goods_price; } public function bonus_amount($goods_amount,$goods_lowest_amount) { return 0.00; } public function hold_bonus($user_bonus) { } public function bonus_way($bonus_amount) { return []; } public function bonus_detail($bonus_amount,$room_id) { return []; } } class account implements IPriceCalculate { private $member_id; private $mPayRates; private $mShareRates; private $mBonusState; private $mRateVersion; //用来记录,红包过期带来的红包变化 private $mFromSession; private $mRoomBonus; private $mDirty; public function __construct($member_id, $from_session = false) { $this->mDirty = false; $this->member_id = $member_id; $this->mFromSession = $from_session; $pd_array = Model('member')->getMemberPdInfo($this->member_id); $this->mRateVersion = intval($pd_array['rate_version']); $this->init_rate(); $this->init_roombonus(); } public function __destruct() { if ($this->mDirty) { if ($this->mFromSession) { $this->del_rates(); } $this->inc_rate_version(); } } public function room_bonus() { return $this->mRoomBonus; } private function init_roombonus() { $this->mRoomBonus = []; $items = room_helper::user_rooms($this->member_id); foreach ($items as $item) { $amount = $item['shared_bonus']; $room_id= $item['room_id']; $name = $item['name']; $avatar = $item['avatar']; $this->mRoomBonus[] = ['room_id' => $room_id,'amount' => $amount,'shared_bonus'=> $amount ,'name' => $name,'avatar' => $avatar]; } if(!empty($this->mRoomBonus)) { usort($this->mRoomBonus,['bonus\account','sort_room_bonus']); } } private function find_room($amount) { $result = []; $amount = intval(100 * $amount); foreach ($this->mRoomBonus as $item) { $cent = intval($item['amount'] * 100 + 0.5); if($amount <= $cent) { $result[] = $item; } } if(empty($result)) { if(!empty($this->mRoomBonus)) { $result[] = $this->mRoomBonus[0]; } } return $result; } static public function sort_room_bonus($l,$r) { $l_val = intval($l['amount'] * 100 + 0.5); $r_val = intval($r['amount'] * 100 + 0.5); if($l_val > $r_val) return -1; elseif($l_val < $r_val) return 1; else return 0; } public function member_id() { return $this->member_id; } private function init_rate() { if ($this->mFromSession) { $fUpdate = false; if (!isset($_SESSION['bonus_rate_version'])) { $fUpdate = true; } else { $version = $_SESSION['bonus_rate_version']; if ($version != $this->mRateVersion) { $fUpdate = true; } else { if (isset($_SESSION['bonus_rate']) && isset($_SESSION['bonus_state']) && isset($_SESSION['share_bonus_rate'])) { $this->mPayRates = self::create_moneycalc($_SESSION['bonus_rate']); $this->mShareRates = self::create_moneycalc($_SESSION['share_bonus_rate']); $this->mBonusState = $_SESSION['bonus_state']; } else { $fUpdate = true; } } } } else { $fUpdate = true; } if ($fUpdate || $this->need_update()) { $mod_bonus = Model('user_bonus'); $this->mPayRates = self::create_moneycalc(array()); $pay_items = $mod_bonus->getUsableBonus($this->member_id); $this->mPayRates->add_bonuses($pay_items); $pay_bonus_rate = $this->mPayRates->format(); $this->mShareRates = self::create_moneycalc(array()); $share_items = $mod_bonus->getShareableBonus($this->member_id); $this->mShareRates->add_bonuses($share_items); $share_bonus_rate = $this->mShareRates->format(); $this->mBonusState = []; $querys = array('usable', 'expiring', 'used', 'expired'); foreach ($querys as $state) { $cond = $this->query_cond($state); if ($state == 'used') { $sum = $mod_bonus->getSum($cond, 'bonus_value'); } else { $sum = $mod_bonus->getSum($cond); } $this->mBonusState[$state] = doubleval($sum); } $this->write_rates($this->mBonusState, $pay_bonus_rate, $share_bonus_rate); $this->mPayRates->clean(); $this->mShareRates->clean(); if ($this->mFromSession) { $_SESSION['bonus_update_time'] = time(); } } } private function need_update() { if ($this->mFromSession) { if (!isset($_SESSION['bonus_update_time'])) return true; $time = intval($_SESSION['bonus_update_time']); if (time() - $time > 86400) { return true; } else { return false; } } else { return true; } } public function pay_bonus_rates() { return $this->mPayRates; } public function total_bonus() { return $this->mPayRates->total(); } public function usable_bonus() { if(empty($this->mRoomBonus)) { return $this->total_bonus(); } else { $ramount = $this->mRoomBonus[0]['amount']; return ($ramount + $this->total_bonus()); } } public function share_bonus_rates() { return $this->mShareRates; } public function share_total_bonus() { return $this->mShareRates->total(); } public function bonus_state() { return $this->mBonusState; } private function query_cond($query_state) { static $stQuerys = ['usable', 'expiring', 'used', 'expired']; static $day_secs = 24 * 3600; $cond = ['user_id' => $this->member_id, 'bonus_status' => 3]; if (!empty($query_state) && in_array($query_state, $stQuerys)) { if ($query_state == 'usable') { $cond['remain_amount'] = ['gt', '0.00']; $cond['usable_time'] = ['gt', time()]; $cond['expired'] = 0; } elseif ($query_state == 'expiring') { $cond['usable_time&usable_time'] = ['_multi' => true, ['gt', time()], ['elt', time() + 5 * $day_secs]]; $cond['remain_amount'] = ['gt', '0.00']; $cond['expired'] = 0; } elseif ($query_state == 'used') { $cond['remain_amount'] = '0.00'; $cond['expired'] = 0; } elseif ($query_state == 'expired') { $cond['usable_time'] = ['lt', time()]; $cond['expired'] = 1; $cond['remain_amount'] = ['gt', '0.00']; } else { } } return $cond; } private function write_rates($bonus_state, $pay_bonus_rate, $share_bonus_rate) { if ($this->mFromSession) { $_SESSION['bonus_state'] = $bonus_state; $_SESSION['bonus_rate'] = $pay_bonus_rate; $_SESSION['share_bonus_rate'] = $share_bonus_rate; $_SESSION['bonus_rate_version'] = $this->mRateVersion; } } private function del_rates() { if ($this->mFromSession) { if (isset($_SESSION['bonus_state'])) { unset($_SESSION['bonus_state']); } if (isset($_SESSION['bonus_rate'])) { unset($_SESSION['bonus_rate']); } if (isset($_SESSION['share_bonus_rate'])) { unset($_SESSION['share_bonus_rate']); } if (isset($_SESSION['bonus_rate_version'])) { unset($_SESSION['bonus_rate_version']); } } } public function topup_bonus($mobile) { $mod_bonus = Model('user_bonus'); $items = $mod_bonus->getBinded($this->member_id(), $mobile); if (empty($items)) return false; $bonuses = []; $manager = new bonus\manager(); foreach ($items as $val) { try { $type_id = $val['type_id']; $type = bonus\type::create_by_id($type_id); $bonus = bonus\user_bonus::create_by_param($val); if ($manager->topup($type, $mod_bonus, $val) == true) { $bonuses[] = $val; ranklist_helper::add_money($this->member_id(), $bonus->bonus_value()); $logger = new recorder($this->member_id); $logger->add_bonus($bonus, $type); } } catch (Exception $ex) { Log::record(__METHOD__ . " {$ex->getMessage()}", Log::ERR); } } if (empty($bonuses)) { return false; } else { $this->mDirty = true; return $bonuses; } } public function is_enough($money) { return intval($this->total_bonus() * 100) >= intval($money * 100); } public function share_enough($money, &$bonus_rate) { if ($this->mPayRates == null) return false; return $this->mShareRates->is_enough($bonus_rate, $money); } public function rates() { return $this->mPayRates == null ? false : $this->mPayRates; } public function makeby_bonus($param, $rate_moneys, $bonus_sn) { $result = bonus_helper::make_bonus($param, $rate_moneys); if ($result == false) return false; $this->mDirty = true; foreach ($rate_moneys as $item) { $rate = intval($item['rate']); $val = $item['hold_amount']; bonus_helper::withold_bonus($this->member_id, $bonus_sn, $rate, $val, bonus_helper::send_bonus_withold); } $type_sn = $result['type_sn']; $money = $result['money']; $logger = new recorder($this->member_id); $logger->handout_bonus($money, $type_sn, session_helper::nickname(), "发送了{$money}元的红包.", bonus\type::MakeSendType); foreach ($rate_moneys as $item) { $this->mPayRates->with_hold($item['rate'], $item['amount']); } return $result; } public function make_bonus($param, $rate_moneys) { $result = bonus_helper::make_bonus($param, $rate_moneys); if ($result == false) return false; $this->mDirty = true; $rates = []; foreach ($rate_moneys as $item) { $rate = intval($item['rate']); $val = $item['hold_amount']; $rates[$rate] = $val; } bonus_helper::withold($this->member_id, $rates, bonus_helper::send_bonus_withold); $type_sn = $result['type_sn']; $money = $result['money']; $logger = new recorder($this->member_id); $logger->handout_bonus($money, $type_sn, session_helper::nickname(), "发送了{$money}元的红包.", bonus\type::MakeSendType); foreach ($rate_moneys as $item) { $this->mPayRates->with_hold($item['rate'], $item['amount']); } return $result; } public function make_vote_type($param, $rate_moneys) { $result = bonus_helper::make_vote_type($param, $rate_moneys); if ($result == false) return false; $this->mDirty = true; $rates = []; foreach ($rate_moneys as $item) { $rate = intval($item['rate']); $val = $item['hold_amount']; $rates[$rate] = $val; } bonus_helper::withold($this->member_id, $rates, bonus_helper::send_bonus_withold); $type_sn = $result['type_sn']; $money = $result['money']; $logger = new recorder($this->member_id); $logger->handout_bonus($money, $type_sn, session_helper::nickname(), "发送了{$money}元的红包.", bonus\type::MakeSendType); foreach ($rate_moneys as $item) { $this->mPayRates->with_hold($item['rate'], $item['amount']); } return $result; } private function base_param($amount, $total_num) { $param = []; $param['total_amount'] = $amount; $param['total_num'] = $total_num; $param['send_type'] = 1; return $param; } public function share_bonus($bonus_sn, &$msg) { $bonus = bonus\user_bonus::create_by_sn($bonus_sn); if ($bonus->spend_over()) { $msg = "该红包现金已经花光了~"; return false; } $amount = $bonus->remain_amount(); $param = $this->base_param($amount, 1); $minfo = new member_info($this->member_id); $param['sender_id'] = $this->member_id; $param['sender_mobile'] = $minfo->mobile(); $param['sender_name'] = $minfo->nickname(); $param['make_type'] = bonus\type::MakeSendType; $name = $minfo->nickname(); $param['type_name'] = "{$name}"; $type = bonus\type::create_by_input($param); $rate_moneys = []; $item['amount'] = $type->getTotal_amount(); $item['num'] = $type->getTotal_num(); $item['rate'] = $bonus->bonus_rate(); $rate_moneys[] = $item; $result = bonus_helper::make_bonus($param, $rate_moneys); if ($result == false) { return false; } else { $this->mDirty = true; if (bonus_helper::withold_bonus($this->member_id, $bonus->bonus_rate(), $bonus_sn, $type->getTotal_amount(), bonus_helper::send_bonus_withold)) { $type_sn = $result['type_sn']; $money = $result['money']; $logger = new recorder($this->member_id); $logger->handout_bonus($money, $type_sn, session_helper::nickname(), "发送了{$money}元的红包.", \bonus\type::MakeSendType); } return $result; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // public function calc_rates($order_pd_amount) // { // $rates = $this->mPayRates->calc_rates($order_pd_amount); // return $rates; // } // public function calc_pred($order_info, $pd_amount, &$no_cash, &$rates) // { // $order_id = intval($order_info['order_id']); // $mod_order = Model('order'); // // $pred_amount = 0.00; // $goods_list = $mod_order->getOrderGoodsList(array('order_id' => $order_id)); // foreach ($goods_list as $goods) { // $goods_type = intval($goods['goods_type']); // if ($goods_type == 1) { // $pred_amount += doubleval($goods['goods_pay_price']); // } // } // // $pred_amount = $pred_amount - $this->mPayRates->calc_money($pred_amount, $rates); // $cur_used = intval($pred_amount * 100 + 0.5); // $cur_used = $cur_used > $pd_amount ? $pd_amount : $cur_used; // // $order_amount = intval($order_info['order_amount'] * 100 + 0.5); // $order_pd_amount = intval($order_info['pd_amount'] * 100 + 0.5); // // if ($order_amount == $cur_used) { // $no_cash = true; // } else { // $no_cash = false; // } // // return $cur_used - $order_pd_amount; // } // public function pay_bonus($rates) // { // $ret = bonus_helper::withold($this->member_id, $rates, bonus_helper::pay_order_withold); // foreach ($rates as $rate => $amount) { // $this->mPayRates->with_hold($rate, $amount); // } // $this->mDirty = true; // // return $ret; // } public function find_share_bonus($amount) { $bonus_rate = $this->share_bonus_rates(); return $bonus_rate->find_rate($amount); } private function inc_rate_version() { $mod_member = Model('member'); $mod_member->editMember(['member_id' => $this->member_id], ['rate_version' => ['exp', "rate_version+1"]]); } public function bonus_price($goods_price, $lowest_price) { $can_use = $goods_price - $lowest_price; $can_use_cent = intval($can_use * 100 + 0.5); $usable_cent = intval($this->usable_bonus() * 100 + 0.5); if ($usable_cent >= $can_use_cent) { return $lowest_price; } else { return intval($goods_price * 100 - $usable_cent + 0.5) / 100; } } public function order_cash($goods_amount, $lowest_amount) { return $this->bonus_price($goods_amount,$lowest_amount); } public function discount_gap($bonus_price, $goods_lowest_price) { $bonus_cent = intval($bonus_price * 100 + 0.5); $lowest_cent = intval($goods_lowest_price * 100 + 0.5); if($bonus_cent >= $lowest_cent) { return ($bonus_cent - $lowest_cent) / 100; } else { return 0; } } public function bonus_amount($goods_amount,$goods_lowest_amount) { $can_use = $goods_amount - $goods_lowest_amount; $can_use_cent = intval($can_use * 100 + 0.5); $usable_cent = intval($this->usable_bonus() * 100 + 0.5); if ($usable_cent >= $can_use_cent) { return ($can_use_cent / 100); } else { return $usable_cent/ 100; } } public function bonus_way($bonus_amount) { $result = []; $need_cent = intval($bonus_amount * 100 + 0.5); $mine_cent = intval($this->total_bonus() * 100 + 0.5); if($mine_cent >= $need_cent) { $result['user_bonus'] = $need_cent / 100; $result['show_room'] = false; $result['room_bonus'] = 0; $result['rooms'] = []; } else { $result['user_bonus'] = $mine_cent / 100; $room_bonus = ($need_cent - $mine_cent) / 100; $rooms = $this->find_room($room_bonus); if(empty($rooms)) { $result['show_room'] = false; $result['room_bonus'] = 0; $result['rooms'] = []; } else { $result['show_room'] = true; $result['room_bonus'] = $room_bonus; $result['rooms'] = $rooms; } } return $result; } public function bonus_detail($bonus_amount,$roomid) { $ways = $this->bonus_way($bonus_amount); if($ways['show_room'] == false || $roomid <= 0) { return ['user_bonus' => $ways['user_bonus']]; } $room_val = 0; $roomid = intval($roomid); if($roomid > 0) { foreach ($ways['rooms'] as $room) { if($roomid == $room['room_id']) { $room_val = $ways['room_bonus']; break; } } } else { foreach ($ways['rooms'] as $room) { $roomid = $room['room_id']; $room_val = $ways['room_bonus']; break; } } return ['user_bonus' => $ways['user_bonus'],'room_bonus' => $room_val,'room_id' => $roomid]; } public function hold_bonus($user_bonus) { if(intval($user_bonus * 100 + 0.5) > 0) { bonus_helper::withold($this->member_id, [30 => $user_bonus], bonus_helper::pay_order_withold); $this->mPayRates->with_hold(30, $user_bonus); $this->mDirty = true; } } static private function create_moneycalc($rate_moneys) { if (noBonusRate()) { return new bonus\BonusAmount($rate_moneys); } else { return new bonus\RateMoney($rate_moneys); } } }