stanley-king 3 yıl önce
ebeveyn
işleme
30d11d396a

+ 1 - 1
helper/refill/LZRefillFactory.php

@@ -19,7 +19,7 @@ require_once(BASE_HELPER_PATH . '/refill/policy/merchant_price.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/mgroup.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/lingzh/PolicyUtil.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/lingzh/quality_ploy.php');
-
+require_once(BASE_HELPER_PATH . '/refill/policy/channel_filter.php');
 
 use Log;
 use StatesHelper;

+ 6 - 13
helper/refill/RefillBase.php

@@ -131,7 +131,6 @@ class RefillBase
             }
             elseif ($can_try)
             {
-                util::add_exclude_channel($mchid,$mch_order,$card_type,$chname);
                 util::incr_notify($chname, $card_type, $spec, $quality, false);
                 util::incr_amount_lock($mchid,$card_type,$spec);
 
@@ -161,8 +160,6 @@ class RefillBase
         $mod_refill->edit($order_id, ['notify_time' => time(), 'is_retrying' => 0,'notify_state' => 1]);
         util::pop_queue_order($mchid,$mch_order);
         QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => false]);
-        util::del_exclude_channel($mchid,$mch_order,$card_type);
-
         return true;
     }
 
@@ -286,6 +283,8 @@ class RefillBase
 
         Log::record("RefillBase::add regin_no={$regin_no}",Log::DEBUG);
         [$providers, $overload] = $this->mPolicy->find_providers($mchid, $amount, $card_type, $org_quality, $quality, $regin_no, $pcode, $order_time, $commit_times);
+        $chfilters = new channel_filter($mchid,$mch_order,$quality,$card_type);
+        $providers = $chfilters->getProviders($providers);
 
         if (empty($providers))
         {
@@ -327,21 +326,15 @@ class RefillBase
         $refill_state = false;
         $order_success = false;
         $net_errno = 0;
-        $exclude_channels = util::get_exclude_channel($mchid,$mch_order,$card_type);
+
         foreach ($providers as $provider)
         {
             $channel_name = $provider->name();
-            if(in_array($channel_name,$exclude_channels)) {
-                Log::record("{$channel_name} channel in exclude",Log::DEBUG);
-                continue;
-            }
 
-            //通道价格大于客户价格,换通道.
             [$goods_id, $price] = $provider->goods($quality,$amount,$card_type,$third_params);
             if ($goods_id <= 0) continue;
-
             if(PolicyUtil::mixed_quality($org_quality) == false && $price > $mch_price) {
-                //组合通道,以原始质量算价格.
+                //组合通道,以原始质量算价格. //通道价格大于客户价格,换通道.
                 continue;
             }
 
@@ -468,6 +461,7 @@ class RefillBase
 
             if ($state)
             {
+                $chfilters->add_channel($channel_name,true);
                 //提交成功
                 util::incr_commit($channel_name,$card_type,$amount,$quality,true);
                 $trade_no = $errmsg;
@@ -489,6 +483,7 @@ class RefillBase
             }
             else
             {
+                $chfilters->add_channel($channel_name,false);
                 if(!empty($neterr) && util::need_check($net_errno)) {
                     $mod_refill->edit($order_id, ['commit_time' => time(),'neterr' => 1,'err_msg' => "neterr={$net_errno}"]);
                     break;
@@ -498,7 +493,6 @@ class RefillBase
                 $commit_times += 1;
                 util::incr_commit($channel_name,$card_type,$amount,$quality,false);
                 util::incr_amount_lock($mchid,$card_type,$amount);
-                util::add_exclude_channel($mchid,$mch_order,$card_type,$channel_name);
 
                 Log::record("channel:{$channel_name} err:{$errmsg}");
                 $logic_vr_order = Logic("vr_order");
@@ -679,7 +673,6 @@ class RefillBase
                 $mod_refill->edit($order_id, ['notify_time' => time(), 'notify_state' => 1]);
                 util::pop_queue_order($mchid,$mch_order);
                 QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => false]);
-                util::del_exclude_channel($mchid,$mch_order,$card_type);
             }
             else {
                 QueueClient::async_push("QueryOrderNeterr",['order_id' => $order_id],30);

+ 1 - 0
helper/refill/XYZRefillFactory.php

@@ -21,6 +21,7 @@ require_once(BASE_HELPER_PATH . '/refill/policy/rstorage.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/lingzh/PolicyUtil.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/xyz/quality_ploy.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/mgroup.php');
+require_once(BASE_HELPER_PATH . '/refill/policy/channel_filter.php');
 
 
 use Log;

+ 159 - 1
helper/refill/policy/channel_filter.php

@@ -1,9 +1,167 @@
 <?php
 
 namespace refill;
+use mtopcard;
 
 class channel_filter
 {
-    
+    private $mMchid;
+    private $mMchOrder;
+    private $mQuality;
+    private $mCardType;
 
+    private $mDatas;
+    public function __construct($mchid,$mch_order,$quality,$card_type)
+    {
+        $this->mMchid = $mchid;
+        $this->mMchOrder = $mch_order;
+        $this->mQuality = $quality;
+        $this->mCardType = $card_type;
+
+        if($this->mCardType != mtopcard\ThirdRefillCard) {
+            $this->mDatas = util::get_order_channels($mchid,$mch_order);
+        }
+    }
+
+    public function __destruct()
+    {
+        if($this->mCardType != mtopcard\ThirdRefillCard) {
+            util::set_order_channels($this->mMchid,$this->mMchOrder,$this->mDatas);
+        }
+    }
+
+    public function add_channel($name,$succ)
+    {
+        if ($this->mCardType == mtopcard\ThirdRefillCard) {
+            return;
+        }
+
+        if (!array_key_exists($this->mQuality, $this->mDatas)) {
+            $this->mDatas[$this->mQuality] = [];
+        }
+
+        $items = &$this->mDatas[$this->mQuality];
+        if ($this->mCardType == mtopcard\SinopecCard || $this->mCardType == mtopcard\PetroChinaCard) {
+            $items[] = $name;
+        }
+        elseif (array_key_exists($name,$items))
+        {
+            if($succ) {
+                $items[$name]['succ'] += 1;
+            } else {
+                $items[$name]['fail'] += 1;
+            }
+        }
+        else
+        {
+            $items[$name] = ['succ' => 0,'fail' => 0];
+            if($succ) {
+                $items[$name]['succ'] += 1;
+            } else {
+                $items[$name]['fail'] += 1;
+            }
+        }
+    }
+
+    public function getProviders($inProviders)
+    {
+        if ($this->mCardType == mtopcard\SinopecCard || $this->mCardType == mtopcard\PetroChinaCard) {
+            return $this->diff($inProviders);
+        } elseif ($this->mCardType == mtopcard\ThirdRefillCard) {
+            return $inProviders;
+        } elseif ($this->mQuality == Quality::Normal) {
+            return $this->asc($inProviders,1,10);
+        } else{
+            return $this->asc($inProviders,1,1);
+        }
+    }
+
+    private function asc($inProviders,$fails,$succs)
+    {
+        if(array_key_exists($this->mQuality,$this->mDatas)) {
+            $name_counts = $this->mDatas[$this->mQuality];
+        } else {
+            $name_counts = [];
+        }
+
+        $filter = function ($name_counts,$fails,$succs)
+        {
+            $fail = [];
+            $good = [];
+            $enough = [];
+
+            foreach ($name_counts as $name => $item)
+            {
+                if($item['fail'] >= $fails) {
+                    $fail[] = $name;
+                }
+                elseif($item['succ'] >= $succs) {
+                    $enough[] = $name;
+                }
+                else {
+                    $good[] = $name;
+                }
+            }
+
+            return [$good,$enough,$fail];
+        };
+
+        [$good,$enough,$fail] = $filter($name_counts,$fails,$succs);
+
+        $fail_providers = [];
+        $enough_providers = [];
+        $good_providers = [];
+
+        foreach ($inProviders as $provider)
+        {
+            $name = $provider->name();
+            if(in_array($name,$fail)) {
+                $fail_providers[] = $provider;
+            }
+            elseif(in_array($name,$enough)) {
+                $enough_providers[] = $provider;
+            }
+            else {
+                $good_providers[] = $provider;
+            }
+        }
+        $result = array_merge($good_providers,$enough_providers);
+        return $result;
+    }
+
+    private function diff($inProviders)
+    {
+        $names_getter = function ($providers)
+        {
+            $result = [];
+            foreach ($providers as $provider) {
+                $result[] = $provider->name();
+            }
+            return $result;
+        };
+
+        $provider_getter = function ($providers,$names)
+        {
+            $result = [];
+            foreach ($providers as $provider)
+            {
+                $name = $provider->name();
+                if(in_array($name,$names)) {
+                    $result[] = $provider;
+                }
+            }
+            return $result;
+        };
+
+        if(array_key_exists($this->mQuality,$this->mDatas)) {
+            $channels = $this->mDatas[$this->mQuality];
+        } else {
+            $channels = [];
+        }
+
+        $names = $names_getter($inProviders);
+        $names = array_diff($names,$channels);
+        $result = $provider_getter($inProviders,$names);
+        return $result;
+    }
 }

+ 22 - 42
helper/refill/util.php

@@ -444,60 +444,39 @@ class util
         }
     }
 
-    public static function add_exclude_channel($mchid,$mchorder,$card_type,$chname)
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public static function set_order_channels($mchid,$mchorder,$datas)
     {
-        if($card_type == mtopcard\SinopecCard || $card_type == mtopcard\PetroChinaCard)
-        {
-            $ins = Cache::getInstance('cacheredis');
-            $name = 'oil_exclude_channels';
-            $key = "{$mchid}-{$mchorder}";
-
-            $chnames = $ins->hget($name, '', $key);
-            $chnames = unserialize($chnames);
-            if(empty($chnames)) {
-                $chnames = [];
-            }
-
-
-            if(!in_array($chname,$chnames)) {
-                $chnames[] = $chname;
-                $ins->hset($name,'',[$key => serialize($chnames)]);
-            }
-        }
+        $ins = Cache::getInstance('cacheredis');
+        $name = 'order_channels';
+        $key = "{$mchid}-{$mchorder}";
+        $ins->hset($name, '', [$key => serialize($datas)]);
     }
 
-    public static function get_exclude_channel($mchid,$mchorder,$card_type)
+    public static function get_order_channels($mchid, $mchorder)
     {
-        if($card_type == mtopcard\SinopecCard || $card_type == mtopcard\PetroChinaCard)
-        {
-            $ins = Cache::getInstance('cacheredis');
-            $name = 'oil_exclude_channels';
-            $key = "{$mchid}-{$mchorder}";
+        //old-name oil_exclude_channels
+        $ins = Cache::getInstance('cacheredis');
+        $name = 'order_channels';
+        $key = "{$mchid}-{$mchorder}";
 
-            $chnames = $ins->hget($name, '', $key);
-            $chnames = unserialize($chnames);
+        $chnames = $ins->hget($name, '', $key);
+        $chnames = unserialize($chnames);
 
-            if(is_array($chnames)) {
-                return $chnames;
-            } else {
-                return [];
-            }
-        }
-        else {
+        if(is_array($chnames)) {
+            return $chnames;
+        } else {
             return [];
         }
     }
 
-    public static function del_exclude_channel($mchid,$mchorder,$card_type)
+    public static function del_order_channels($mchid, $mchorder)
     {
-        if($card_type == mtopcard\SinopecCard || $card_type == mtopcard\PetroChinaCard)
-        {
-            $ins = Cache::getInstance('cacheredis');
-            $name = 'oil_exclude_channels';
-            $key = "{$mchid}-{$mchorder}";
+        $ins = Cache::getInstance('cacheredis');
+        $name = 'order_channels';
+        $key = "{$mchid}-{$mchorder}";
 
-            $ins->hdel($name, '', $key);
-        }
+        $ins->hdel($name, '', $key);
     }
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -513,6 +492,7 @@ class util
 
     public static function pop_queue_order($mchid,$mch_order)
     {
+        util::del_order_channels($mchid,$mch_order);
         Model('refill_order')->edit_detail($mchid,$mch_order,['order_state' => ORDER_STATE_HANDLED]);
         $ins = Cache::getInstance('cacheredis');
 

+ 0 - 4
rdispatcher/proxy.php

@@ -64,7 +64,6 @@ class proxy
 
             refill\util::pop_queue_order($mchid, $mch_order);
             QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id, 'manual' => false]);
-            util::del_exclude_channel($mchid, $mch_order, $card_type);
             return;
         }
 
@@ -117,7 +116,6 @@ class proxy
 
                 refill\util::pop_queue_order($mchid,$mch_order);
                 QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => false]);
-                util::del_exclude_channel($mchid,$mch_order,$card_type);
             }
         }
     }
@@ -169,7 +167,6 @@ class proxy
 
         refill\util::pop_queue_order($mchid, $mch_order);
         QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id, 'manual' => false]);
-        util::del_exclude_channel($mchid, $mch_order, $card_type);
     }
 
 
@@ -271,7 +268,6 @@ class proxy
 
             refill\util::pop_queue_order($mchid,$mch_order);
             QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id,'manual' => false]);
-            util::del_exclude_channel($mchid,$mch_order,$card_type);
         }
     }
 }

+ 2 - 4
test/TestRedis.php

@@ -311,10 +311,8 @@ class TestRedis extends TestCase
 
     public function testValue()
     {
-        refill\util::add_exclude_channel(1,"xxxxxfdasfdas",1,'gftd');
-        refill\util::add_exclude_channel(1,"xxxxxfdasfdas",1,'gftdsino');
-        $ret = refill\util::get_exclude_channel(1,"xxxxxfdasfdas",1);
-        refill\util::del_exclude_channel(1,"xxxxxfdasfdas",1);
+        $ret = refill\util::get_order_channels(1,"xxxxxfdasfdas");
+        refill\util::del_order_channels(1,"xxxxxfdasfdas");
     }
 
 

+ 1 - 1
test/TestRefillThird.php

@@ -81,7 +81,7 @@ class TestRefillThird extends TestCase
         $params = [ 'mchid' => 1092,
             'buyer_id' => 60221,
             'amount' => 30,
-            'mch_order' => $this->make_sn(),
+            'mch_order' => '89721626805040540201',//$this->make_sn(),
             'org_quality' => 1,
             'card_no' => '13911129867'
         ];