فهرست منبع

增加反推红包可购买商品的最大价格

stanley-king 8 سال پیش
والد
کامیت
e4c2f82043

+ 147 - 0
helper/bonus/scaler.php

@@ -0,0 +1,147 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/4/20
+ * Time: 下午5:12
+ */
+
+namespace bonus;
+
+
+class scaler
+{
+    const match_rate = 30;
+
+    private $mMoneys;
+    private $mMatchMoney;
+
+    public function __construct($rates_moneys)
+    {
+        $this->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']);
+
+        $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;
+    }
+}

+ 8 - 0
helper/bonus_helper.php

@@ -22,6 +22,7 @@ require_once (BASE_ROOT_PATH . '/helper/bonus/shaker.php');
 require_once (BASE_ROOT_PATH . '/helper/bonus/allocator.php');
 require_once (BASE_ROOT_PATH . '/helper/bonus/witholder.php');
 require_once (BASE_ROOT_PATH . '/helper/bonus/open_sharer.php');
+require_once (BASE_ROOT_PATH . '/helper/bonus/scaler.php');
 
 
 class bonus_helper
@@ -324,4 +325,11 @@ class bonus_helper
             return (empty($items) == true);
         }
     }
+
+    static public function match_price($rate_moneys)
+    {
+        if(empty($rate_moneys)) return false;
+        $scaler = new \bonus\scaler($rate_moneys);
+        return $scaler->calc();
+    }
 }

+ 7 - 0
helper/search/processor.php

@@ -20,6 +20,8 @@ class processor implements IProcessor
 {
     const GetRelatedWord = 1;
     const SearchReasult  = 2;
+    const MatchPrice     = 3;
+
     const ValidateArea   = 20;
 
     public function handle_input($body)
@@ -43,6 +45,11 @@ class processor implements IProcessor
             $result = searcher::instance()->get_result($params);
             return serialize($result);
         }
+        elseif($type == self::MatchPrice) {
+            $params = $body['params'];
+            $result = searcher::instance()->match_price($params);
+            return serialize($result);
+        }
         elseif ($type == self::ValidateArea) {
             $params = $body['params'];
             $area_id = $params['area_id'];

+ 11 - 3
helper/search/searcher.php

@@ -676,10 +676,18 @@ class searcher
     public function match_price($params)
     {
         $price = $params['price'];
-        $page_no = $params['page_no'];
-        $page_size = $params['page_size'];
+        $page_no   = intval($params['page_no']);
+        $page_size = intval($params['page_size']);
 
-        return $this->price_cids->findless(intval($price * 100 + 0.5),$page_no,$page_size);
+        if($page_no <= 0 || $page_size <= 0) {
+            return false;
+        }
+        $start = ($page_no - 1) * $page_size;
+
+        $result = $this->price_cids->findless(intval($price * 100 + 0.5),$start,$page_size);
+        $result['page_count'] = intval($result['total'] / $page_size) + ($result['total'] % $page_size == 0 ? 0 : 1);
+
+        return $result;
     }
 
     private function get_ids($dict, $words)

+ 26 - 40
helper/search/tcp_client.php

@@ -14,6 +14,7 @@ class tcp_client
 {
     const GetRelatedWord = 1;
     const SearchReasult  = 2;
+    const MatchPrice     = 3;
 
     const ValidateArea   = 20;
 
@@ -44,6 +45,29 @@ class tcp_client
 
     public function get_words($word)
     {
+        $param = array("type" => self::GetRelatedWord, "keyword" => $word);
+        return $this->request($param);
+    }
+
+    public function get_result($params)
+    {
+        $param = array("type" => self::SearchReasult, "params" => $params);
+        return $this->request($param);
+    }
+    public function match_price($params)
+    {
+        $param = array("type" => self::MatchPrice, "params" => $params);
+        return $this->request($param);
+    }
+
+    public function get_area($area_id)
+    {
+        $param = array("type" => self::ValidateArea, "params" => array('area_id' => $area_id));
+        return $this->request($param);
+    }
+
+    private function request($param)
+    {
         $times = 0;
         do
         {
@@ -51,7 +75,6 @@ class tcp_client
                 return false;
             }
 
-            $param = array("type" => self::GetRelatedWord, "keyword" => $word);
             $ret = $this->write_param($param);
             if($ret === false) {
                 $this->fini_socket();
@@ -65,48 +88,11 @@ class tcp_client
                 return unserialize($body);
             }
         }
-        $this->fini_socket();
-        return false;
-    }
-
-    public function get_result($params)
-    {
-        if($this->init_socket() == false) {
-            return false;
-        }
-
-        $param = array("type" => self::SearchReasult, "params" => $params);
-        $ret = $this->write_param($param);
-
-        if($ret == true)
+        else
         {
-            $body = $this->read_body();
-            if($body != false) {
-                return unserialize($body);
-            }
-        }
-        $this->fini_socket();
-        return false;
-    }
-
-    public function get_area($area_id)
-    {
-        if($this->init_socket() == false) {
+            $this->fini_socket();
             return false;
         }
-
-        $param = array("type" => self::ValidateArea, "params" => array('area_id' => $area_id));
-        $ret = $this->write_param($param);
-
-        if($ret == true)
-        {
-            $body = $this->read_body();
-            if($body != false) {
-                return unserialize($body);
-            }
-        }
-        $this->fini_socket();
-        return false;
     }
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+ 4 - 1
helper/search/util.php

@@ -265,9 +265,12 @@ class valtokey
     {
         $pos = algorithm::upper_bound($this->mValMap,$val);
         $pos = $pos - $start;
-        if($pos < 0 || $pos >= $this->mCount) {
+        if($pos < 0) {
             return false;
         }
+        elseif ($pos >= $this->mCount) {
+            $pos = $this->mCount - 1;
+        }
 
         $result = [];
         for ($i = $pos; $i >= 0 && $length > 0; $i--,$length--) {

+ 83 - 0
mobile/control/member_bonus.php

@@ -13,6 +13,11 @@ require_once (BASE_ROOT_PATH . '/helper/shaker_helper.php');
 require_once (BASE_ROOT_PATH . '/helper/ranklist_helper.php');
 require_once (BASE_ROOT_PATH . '/helper/special_helper.php');
 require_once (BASE_ROOT_PATH . '/helper/util_helper.php');
+require_once (BASE_ROOT_PATH . '/helper/search/tcp_client.php');
+require_once (BASE_ROOT_PATH . '/helper/search/util.php');
+require_once (BASE_ROOT_PATH . '/helper/search_param.php');
+require_once (BASE_ROOT_PATH . '/helper/goods_helper.php');
+
 
 class member_bonusControl extends mbMemberControl
 {
@@ -115,6 +120,82 @@ class member_bonusControl extends mbMemberControl
         }
     }
 
+    public function match_goodsOp()
+    {
+        $bonus_rate = $this->mPred->bonus_rate();
+        $rate_moneys = $bonus_rate->format();
+        $price = bonus_helper::match_price($rate_moneys);
+
+        if($price == false)
+        {
+            return self::outsuccess(array('special_list' => null,
+                'summary'  => null,
+                'groupbuy' => null,
+                'limitime' => null,
+                'bundling' => null,
+                'mobile_page' => mobile_page(0)));
+        }
+        else
+        {
+            $params = ['price' => $price,'page_no' => $this->page_no(),'page_size' => $this->page_size()];
+            $result = search\tcp_client::instance()->match_price($params);
+
+            $cids = $result['cids'];
+            $model_goods = Model('goods');
+            $items = $model_goods->getGoodsListByColorDistinct(array('goods_commonid' => array('in',$cids)),goods_helper::fieldstr,'','');
+            $page_count = $result['page_count'];
+
+            if(empty($items))
+            {
+                return self::outsuccess(array('special_list' => null,
+                    'summary'  => null,
+                    'groupbuy' => null,
+                    'limitime' => null,
+                    'bundling' => null,
+                    'mobile_page' => mobile_page($page_count)));
+            }
+            else
+            {
+                $tmp =[];
+                foreach ($items as $item) {
+                    $commonid = intval($item['goods_commonid']);
+                    $tmp[$commonid] = $item;
+                }
+
+                $goods_list = [];
+                foreach ($cids as $cid)
+                {
+                    if(array_key_exists($cid,$tmp)) {
+                        $goods_list[] = $tmp[$cid];
+                    }
+                }
+
+                $blocks = [];
+                if($this->page_no() == 1)
+                {
+                }
+
+                foreach ($goods_list as $goods) {
+                    $goods_id = intval($goods['goods_id']);
+                    $goods_ids[] = $goods_id;
+                }
+
+                $helper = new goods_helper();
+                $ret = $helper->get_summaryex($goods_list,$related_goods);
+
+                $block = special_formater::format_goods($goods_ids,"",$ret['sort_summary']);
+                $blocks[] = $block;
+
+                return self::outsuccess(array('special_list' => $blocks,
+                    'summary'  => $ret['summary'],
+                    'groupbuy' => $ret['groupbuy'],
+                    'limitime' => $ret['limitime'],
+                    'bundling' => $ret['bundling'],
+                    'mobile_page' => mobile_page($page_count)));
+            }
+        }
+    }
+
     public function makeby_bonusOp()
     {
         if(!isset($_GET['bonus_sn']) || empty($_GET['bonus_sn'])) {
@@ -793,6 +874,8 @@ class member_bonusControl extends mbMemberControl
         $pages = $this->pages($count);
         return $type_infos;
     }
+
+
 }
 
 class tpl_invite

+ 8 - 8
test/TestSearch.php

@@ -52,18 +52,18 @@ class TestSearch extends PHPUnit_Framework_TestCase
         $result = $searcher->get_result(array('keyword' => '妮维雅','order' =>'price','sort' => 'desc','page_no' => 1,'page_size' => 10));
 
 
-        $result = $searcher->match_price(array('price' => 50,'page_no' => 1,'page_size' => 10));
+        $result = $searcher->match_price(array('price' => 1303020.97,'page_no' => 1,'page_size' => 10));
         $x = 100;
     }
 
 
-//    public function testRequest()
-//    {
-//        for($i = 0; $i < 1000; ++$i) {
-//            $result = search\tcp_client::instance()->get_result(array('keyword' => '相宜本草'));
-//            //Log::record("testRequest {$i}",Log::DEBUG);
-//        }
-//    }
+    public function testRequest()
+    {
+        for($i = 0; $i < 1000; ++$i) {
+            $result = search\tcp_client::instance()->get_result(array('keyword' => '相宜本草'));
+            //Log::record("testRequest {$i}",Log::DEBUG);
+        }
+    }
 
     public function testBrandSpecia()
     {

+ 6 - 0
test/bonus_helperTest.php

@@ -23,6 +23,12 @@ class bonus_helperTest extends PHPUnit_Framework_TestCase
         Base::run_util();
     }
 
+    public function testScaler()
+    {
+        $scaler = new \bonus\scaler([10 => 10,100 => 100,50 => 50, 30 => 30]);
+        //$scaler = new \bonus\scaler([10 => 10,50 => 50, 20 => 60,100 => 100]);
+        $ret = $scaler->calc();
+    }
     public function testModel()
     {
         $item = Model('user_bonus')->field('*')->where(array('type_id' => 105,'bonus_id' => 2491))->select();