stanley-king 1 year ago
parent
commit
cfda1a7e2f

+ 59 - 0
helper/refill/EventManager.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace refill;
+
+use Log;
+
+class EventManager
+{
+    private static $stInstance = null;
+    public static function instance()
+    {
+        if (self::$stInstance == null) {
+            self::$stInstance = new EventManager();
+        }
+
+        return self::$stInstance;
+    }
+
+    public function load()
+    {
+
+    }
+
+    public static function onBeforeSubmit(order $order)
+    {
+        return true;
+    }
+    public function onSubmit(order $order)
+    {
+    }
+
+    public function onBeforeCommit(order $order, $ch_name): bool
+    {
+        return true;
+    }
+    public function onCommit(order $order, $ch_name)
+    {
+    }
+
+    public function onNeterror(order $order, $ch_name)
+    {
+    }
+
+    public function onNotify($refill_info, $order_info, $success)
+    {
+        $uid = "{$refill_info['mchid']}-{$refill_info['mch_order']}";
+        $ch_name = $refill_info['channel_name'];
+
+        Log::record("onEvent notify uid=$uid channel=$ch_name success=$success", Log::DEBUG);
+    }
+
+    public function onComplete($refill_info, $order_info, $success)
+    {
+        $uid = "{$refill_info['mchid']}-{$refill_info['mch_order']}";
+        $ch_name = $refill_info['channel_name'];
+
+        Log::record("onEvent complete uid=$uid channel=$ch_name success=$success", Log::DEBUG);
+    }
+}

+ 1 - 1
helper/refill/RefillBase.php

@@ -485,7 +485,7 @@ class RefillBase
         foreach ($providers as $provider)
         foreach ($providers as $provider)
         {
         {
             $channel_name = $provider->name();
             $channel_name = $provider->name();
-            $can_commit = util::onBeforeCommit($order, $channel_name);
+            $can_commit = util::onEventBeforeCommit($order, $channel_name);
             if ($can_commit === false) {
             if ($can_commit === false) {
                 continue;
                 continue;
             }
             }

+ 58 - 0
helper/refill/event/card_crash.MD

@@ -0,0 +1,58 @@
+# 撞单问题
+## 描述
+返回流水号0095和zf20230等的通道,引起撞单。
+## 本质原因
+这些通道会从运营商平台提取该号码的可能充值成功记录,误以为是自己的。
+## 局部解决办法
+1,某卡号进入这些通道后,在收到这些通道回调前,订单不允许再做任何充值。  
+2,某卡号在非这些通道充值成功后,限定时长内不允许进入这些通道。  
+3,某卡号在这些通道充值成功后,限定时长内不允许进入这些通道。  
+## 解释
+不允许再做任何充值,是不让这些订单在内部充值,也不让它们返回给客户。  
+这些通道,就是会撞单的通道。
+
+## 技术解决方案
+### 数据结构
+每个号码对应的详细数据记录包括:  
+succ_channel 成功的通道         空表示无  
+succ_time 成功时间              0 表示无  
+committings: 正在充值中,该卡号所有订单详情  
+[
+    mch_order :commit_channel 正在提单的通道   空表示无
+]
+
+### onEventBeforeSubmit
+在收到用户卡号后,处理前。  
+1,如果该卡号在这些通道成功了,并且时长不足指定时间,则该订单不被处理。  
+2,如果该卡号正在这些通道中,则该订单不被处理。
+### onEventSubmit
+1,无需判断
+2,增加卡号和记录初始值。
+### onEventBeforeCommit
+1,判断该卡号在指定时长内,在这些通道中是否有成功订单。如果有则不允许向这些通道提单。  
+2,判断相同卡号的其它订单,是否正在使用问题通道,如果是则不允许向这些通道提单。  
+### onEventCommit  
+1,记录正在充值中的该订单的通道。
+### onEventNeterror
+和submit 相同处理
+### onEventNotify
+1,失败按订单号,设正在提单的通道为空。
+### onEventComplete
+1,失败的情况下,无需处理。
+2,如果之前无成功记录 -> 更换成功通道和成功时间。  
+3,如果之前有成功记录
+   如果该订单在这些通道成功 -> 更换成功通道和成功时间。  
+   如果之前在这些通道成功 -> 按时长判断是否更新
+   否则->更新
+4,清除该卡号,该订单的正在充值信息。
+
+### 注意事项
+1,部署前,需要停止所有worker,以免混入脏数据。  
+2,commit,notify,complete 事件时,如果遇到读不出记录的卡号,则无需处理。  
+
+
+
+
+
+
+

+ 24 - 23
helper/refill/sending_monitor.php

@@ -1,14 +1,13 @@
 <?php
 <?php
 
 
-namespace refill;
+namespace refill\event;
 
 
 use Log;
 use Log;
 
 
-//监控,手机卡号在指定的多个通道中,保持充值中唯一性
-//如果订单成功,在指定时间段里面,不能继续充值
-class sending_monitor
+# 规避相同手机卡号撞单问题解
+class card_crash
 {
 {
-    private const cache_name = 'unique_sending_monitor';
+    private const cache_name = 'card_crash';
     private static $stChannelNames = [];//beirui_nation
     private static $stChannelNames = [];//beirui_nation
 
 
     private const SENDING = 1;
     private const SENDING = 1;
@@ -17,18 +16,20 @@ class sending_monitor
 
 
     public function __construct()
     public function __construct()
     {
     {
-
     }
     }
+    public function load($cfgs)
+    {
 
 
+    }
 
 
     public function can_commit($card_no, $ch_name)
     public function can_commit($card_no, $ch_name)
     {
     {
-        Log::record("sending_monitor can_commit $card_no $ch_name",Log::DEBUG);
+        Log::record("card_crash can_commit $card_no $ch_name",Log::DEBUG);
         return true;
         return true;
     }
     }
     private function can_add($card_no, $ch_name)
     private function can_add($card_no, $ch_name)
     {
     {
-        if (!in_array($ch_name, sending_monitor::$stChannelNames)) {
+        if (!in_array($ch_name, card_crash::$stChannelNames)) {
             return true;
             return true;
         }
         }
 
 
@@ -38,21 +39,21 @@ class sending_monitor
         }
         }
 
 
         [$ch_name, $time, $state] = $ret;
         [$ch_name, $time, $state] = $ret;
-        if (!in_array($ch_name, sending_monitor::$stChannelNames)) {
+        if (!in_array($ch_name, card_crash::$stChannelNames)) {
             //如果限制的通道发生变化了,过去的数据无效处理。
             //如果限制的通道发生变化了,过去的数据无效处理。
-            dcache(sending_monitor::cache_name, 'refill-', $card_no);
+            dcache(card_crash::cache_name, 'refill-', $card_no);
             return true;
             return true;
         }
         }
 
 
-        if ($state === sending_monitor::SUCC)
+        if ($state === card_crash::SUCC)
         {
         {
-            if (time() - $time >= sending_monitor::SUCC_INTERVAL_SECS) {
+            if (time() - $time >= card_crash::SUCC_INTERVAL_SECS) {
                 return true;
                 return true;
             } else {
             } else {
                 return false;
                 return false;
             }
             }
         }
         }
-        elseif ($state === sending_monitor::SENDING) {
+        elseif ($state === card_crash::SENDING) {
             return false;
             return false;
         }
         }
         else {
         else {
@@ -62,50 +63,50 @@ class sending_monitor
 
 
     public function commit($card_no, $ch_name)
     public function commit($card_no, $ch_name)
     {
     {
-        Log::record("sending_monitor commit $card_no $ch_name",Log::DEBUG);
+        Log::record("card_crash commit $card_no $ch_name",Log::DEBUG);
     }
     }
 
 
     public function notify($card_no, $ch_name, $fsucc)
     public function notify($card_no, $ch_name, $fsucc)
     {
     {
-        Log::record("sending_monitor commit $card_no $ch_name succ=$fsucc",Log::DEBUG);
+        Log::record("card_crash commit $card_no $ch_name succ=$fsucc",Log::DEBUG);
     }
     }
 
 
     private function add($card_no, $chname)
     private function add($card_no, $chname)
     {
     {
-        if (!in_array($chname, sending_monitor::$stChannelNames)) {
+        if (!in_array($chname, card_crash::$stChannelNames)) {
             return;
             return;
         }
         }
 
 
-        $this->write($card_no, $chname, sending_monitor::SENDING);
+        $this->write($card_no, $chname, card_crash::SENDING);
     }
     }
 
 
     private function success($card_no, $chname)
     private function success($card_no, $chname)
     {
     {
-        if (!in_array($chname, sending_monitor::$stChannelNames)) {
+        if (!in_array($chname, card_crash::$stChannelNames)) {
             return;
             return;
         }
         }
 
 
-        $this->write($card_no, $chname, sending_monitor::SENDING);
+        $this->write($card_no, $chname, card_crash::SENDING);
     }
     }
 
 
     private function fail($card_no, $chname)
     private function fail($card_no, $chname)
     {
     {
-        if (!in_array($chname, sending_monitor::$stChannelNames)) {
+        if (!in_array($chname, card_crash::$stChannelNames)) {
             return;
             return;
         }
         }
 
 
-        dcache(sending_monitor::cache_name, 'refill-', $card_no);
+        dcache(card_crash::cache_name, 'refill-', $card_no);
     }
     }
 
 
     private function write($card_no, $chname, $state)
     private function write($card_no, $chname, $state)
     {
     {
         $data = [$card_no => json_encode([$chname, time(), $state])];
         $data = [$card_no => json_encode([$chname, time(), $state])];
-        wcache(sending_monitor::cache_name, $data, 'refill-');
+        wcache(card_crash::cache_name, $data, 'refill-');
     }
     }
 
 
     private function read($card_no)
     private function read($card_no)
     {
     {
-        $ret = rcache(sending_monitor::cache_name, 'refill-', $card_no);
+        $ret = rcache(card_crash::cache_name, 'refill-', $card_no);
 
 
         if (empty($ret)) {
         if (empty($ret)) {
             return false;
             return false;

+ 14 - 2
helper/refill/util.php

@@ -6,6 +6,7 @@ require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
 require_once(BASE_HELPER_PATH . '/queue/rdispatcher.php');
 require_once(BASE_HELPER_PATH . '/queue/rdispatcher.php');
 require_once(BASE_HELPER_PATH . '/queue/monitor.php');
 require_once(BASE_HELPER_PATH . '/queue/monitor.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/rlock.php');
 require_once(BASE_HELPER_PATH . '/refill/policy/rlock.php');
+require_once(BASE_HELPER_PATH . '/refill/EventManager.php');
 
 
 use queue;
 use queue;
 use mtopcard;
 use mtopcard;
@@ -426,24 +427,33 @@ class util
     }
     }
 
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    public static function onEventBeforeSubmit(order $order) : bool
+    {
+        Log::record("onEvent before submit {$order->unique_id()}",Log::DEBUG);
+        return EventManager::instance()->onBeforeSubmit($order);
+    }
+
     public static function onEventSubmit(order $order)
     public static function onEventSubmit(order $order)
     {
     {
         Log::record("onEvent submit {$order->unique_id()}",Log::DEBUG);
         Log::record("onEvent submit {$order->unique_id()}",Log::DEBUG);
+        EventManager::instance()->onSubmit($order);
     }
     }
 
 
-    public static function onBeforeCommit(order $order, $ch_name): bool
+    public static function onEventBeforeCommit(order $order, $ch_name): bool
     {
     {
         Log::record("onEvent before commit uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
         Log::record("onEvent before commit uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
-        return true;
+        return EventManager::instance()->onBeforeCommit($order,$ch_name);
     }
     }
     public static function onEventCommit(order $order, $ch_name)
     public static function onEventCommit(order $order, $ch_name)
     {
     {
         Log::record("onEvent commit uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
         Log::record("onEvent commit uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
+        EventManager::instance()->onCommit($order,$ch_name);
     }
     }
 
 
     public static function onEventNeterror(order $order, $ch_name)
     public static function onEventNeterror(order $order, $ch_name)
     {
     {
         Log::record("onEvent neterror uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
         Log::record("onEvent neterror uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
+        EventManager::instance()->onNeterror($order,$ch_name);
     }
     }
 
 
     public static function onEventNotify($refill_info, $order_info, $success)
     public static function onEventNotify($refill_info, $order_info, $success)
@@ -452,6 +462,7 @@ class util
         $ch_name = $refill_info['channel_name'];
         $ch_name = $refill_info['channel_name'];
 
 
         Log::record("onEvent notify uid=$uid channel=$ch_name success=$success", Log::DEBUG);
         Log::record("onEvent notify uid=$uid channel=$ch_name success=$success", Log::DEBUG);
+        EventManager::instance()->onNotify($refill_info, $order_info, $success);
     }
     }
 
 
     public static function onEventComplete($refill_info, $order_info, $success)
     public static function onEventComplete($refill_info, $order_info, $success)
@@ -460,6 +471,7 @@ class util
         $ch_name = $refill_info['channel_name'];
         $ch_name = $refill_info['channel_name'];
 
 
         Log::record("onEvent complete uid=$uid channel=$ch_name success=$success", Log::DEBUG);
         Log::record("onEvent complete uid=$uid channel=$ch_name success=$success", Log::DEBUG);
+        EventManager::instance()->onComplete($refill_info, $order_info, $success);
     }
     }
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     public static function set_order_channels($mchid,$mchorder,$datas)
     public static function set_order_channels($mchid,$mchorder,$datas)

+ 4 - 0
rdispatcher/proxy.php

@@ -180,6 +180,10 @@ class proxy
             return $this->onEerror($order, $need_callback,'运营商维护被全局拦截.');
             return $this->onEerror($order, $need_callback,'运营商维护被全局拦截.');
         }
         }
 
 
+        if(($order->commit_times() === 0) and (util::onEventBeforeSubmit($order) === false)) {
+            return true;
+        }
+
         if($order->first_commit())
         if($order->first_commit())
         {
         {
             if (!$order->match_card_type()) {
             if (!$order->match_card_type()) {

+ 4 - 2
test/TestRefillUtil.php

@@ -10,7 +10,9 @@ require_once(BASE_ROOT_PATH . '/global.php');
 require_once(BASE_CORE_PATH . '/lrlz.php');
 require_once(BASE_CORE_PATH . '/lrlz.php');
 require_once(BASE_ROOT_PATH . '/fooder.php');
 require_once(BASE_ROOT_PATH . '/fooder.php');
 require_once(BASE_HELPER_PATH . '/refill/util.php');
 require_once(BASE_HELPER_PATH . '/refill/util.php');
-require_once(BASE_HELPER_PATH . '/refill/sending_monitor.php');
+require_once(BASE_HELPER_PATH . '/refill/event/card_crash.php');
+
+
 
 
 
 
 class TestRefillUtil extends TestCase
 class TestRefillUtil extends TestCase
@@ -46,7 +48,7 @@ class TestRefillUtil extends TestCase
     {
     {
         $card_no =  13911129867;
         $card_no =  13911129867;
         $card_no1 = 13911129868;
         $card_no1 = 13911129868;
-        $monitor = new refill\sending_monitor();
+        $monitor = new refill\event\card_crash();
         $ret = $monitor->can_commit($card_no,'beirui_nation');
         $ret = $monitor->can_commit($card_no,'beirui_nation');
         $monitor->notify($card_no,'beirui_nation',true);
         $monitor->notify($card_no,'beirui_nation',true);
         $ret = $monitor->can_commit($card_no1,'beirui_nation');
         $ret = $monitor->can_commit($card_no1,'beirui_nation');