Explorar el Código

Merge branch 'raccount' of 39.97.239.116:gyfl/xyzshop into raccount

xiaoyu hace 3 años
padre
commit
87333c9137

+ 329 - 0
helper/refill/ops/order_clear.php

@@ -0,0 +1,329 @@
+<?php
+
+namespace refill;
+use Log;
+use trans_wapper;
+use Exception;
+
+class order_clear
+{
+    public function clear($start_date, $end_date, $start_line = 0)
+    {
+        $mchorder_gen = function ($start)
+        {
+            $end = $start + 3600;
+            $cond = ['order_time&order_time' => ['_multi' => true, ['egt', $start], ['lt', $end]], 'inner_status' => 0];
+
+            $i = 0;
+            while (true)
+            {
+                $start = $i * 1000;
+                $items = Model()->table('refill_order')
+                    ->field('mchid,mch_order,order_time')
+                    ->where($cond)
+                    ->order('order_time desc')->limit("{$start},1000")->select();
+                $i++;
+
+                if(empty($items)) break;
+                foreach ($items as $item) {
+                    yield $item;
+                }
+            }
+        };
+
+        $mchorder_saver = function ($start,$file) use ($mchorder_gen)
+        {
+            if (file_exists($file)) {
+                return true;
+            }
+
+            $fp = fopen($file,'w');
+            if($fp === false) {
+                Log::record("Cannot open file {$file} with write.",Log::ERR);
+                return false;
+            }
+
+            $end = $start + 86400;
+            for ($hour = $start; $hour < $end; $hour += 3600)
+            {
+                $orders = $mchorder_gen($hour);
+                foreach ($orders as $order)
+                {
+                    $ret = fputcsv($fp,$order);
+                    if($ret === false) {
+                        return false;
+                    }
+                }
+            }
+            fclose($fp);
+
+            return true;
+        };
+
+        $handle_days = function ($start_date, $end_date,$line = 0) use ($mchorder_saver)
+        {
+            for ($date = $start_date; $date < $end_date; $date += 86400)
+            {
+                $sdate = date('Y-m-d',$date);
+
+                $morder_file = BASE_DATA_PATH . "/log/order/{$sdate}-morder.csv";
+                $check_file  = BASE_DATA_PATH . "/log/order/{$sdate}-check.csv";
+                $refill_file = BASE_DATA_PATH . "/log/order/{$sdate}-refill.csv";
+                $vr_file     = BASE_DATA_PATH . "/log/order/{$sdate}-vr.csv";
+
+                $ret = $mchorder_saver($date,$morder_file);
+                if($ret === false) {
+                    Log::record("fetch or save {$sdate} mch_order fail.",Log::ERR);
+                    break;
+                }
+
+                $this->order_delete($morder_file,$check_file,$refill_file,$vr_file,$line);
+            }
+        };
+
+        $handle_days($start_date, $end_date,$start_line);
+    }
+
+    private function order_delete($mch_file, $check_file, $refill_file, $vr_file, $line)
+    {
+        $rorder_getter = function ($mchid,$mch_order,$mod_refill)
+        {
+            $result = [];
+            $i = 0;
+            while(true)
+            {
+                $start = $i * 1000;
+                $ritems = $mod_refill->table('refill_order')->field('*')
+                    ->where(['mchid' => $mchid, 'mch_order' => $mch_order])
+                    ->order('order_id desc')
+                    ->limit("{$start},1000")->master(true)->select();
+                $i++;
+
+                $result = array_merge($ritems,$result);
+                if(count($ritems) < 1000) {
+                    break;
+                }
+            }
+
+            return $result;
+        };
+
+        $vorder_getter = function ($order_ids,$mod_vr)
+        {
+            $result = [];
+            $i = 0;
+            while(true)
+            {
+                $start = $i * 1000;
+
+                $vitems = $mod_vr->table('vr_order')->field('*')
+                    ->where(['order_id' => ['in', $order_ids]])
+                    ->order('order_id asc')
+                    ->limit("{$start},1000")->master(true)->select();
+                $i++;
+
+                $result = array_merge($vitems,$result);
+                if(count($vitems) < 1000) {
+                    break;
+                }
+            }
+
+            return $result;
+        };
+
+        $order_checker = function ($mchid,$mch_order,$frefill,$fvr) use($rorder_getter,$vorder_getter)
+        {
+            $mod_refill = Model('refill_order');
+            $ritems = $rorder_getter($mchid,$mch_order,$mod_refill);
+
+            if(empty($ritems)) {
+                return [false, [], 'order count = 0'];
+            }
+
+            $oids = [];
+            $inner_state = [0 => 0 ,1 => 0];
+            $is_retrying = 0;
+            $mch_notify_counts = 0;
+            foreach ($ritems as $item)
+            {
+                $oids[] = $item['order_id'];
+                $state = intval($item['inner_status']);
+                $inner_state[$state] += 1;
+                $mch_notify_counts   += intval($item['mch_notify_state']);
+
+                if($state === 0 && $is_retrying === 0) {
+                    $is_retrying = intval($item['is_retrying']);
+                }
+            }
+
+            //检查inner_status=0唯一性。
+            if($inner_state[0] != 1) {
+                return [false, [], "inner_status=0 counts={$inner_state[0]}"];
+            }
+
+            if($mch_notify_counts === 0) {
+                return [false, [], "not notify merchant"];
+            }
+            elseif($mch_notify_counts > 1) {
+                return [false, [], "more than one order notify merchant"];
+            }
+
+            if($is_retrying) {
+                return [false, [], 'is_retrying = 1'];
+            }
+
+            $mod_vr = Model('vr_order');
+            $vitems = $vorder_getter($oids,$mod_vr);
+
+            //检查refill 表记录和vr_order表记录是否一致
+            if(count($ritems) !== count($vitems)) {
+                return [false, [], 'refill count != vr count'];
+            }
+
+            $order_state = [];
+            foreach ($vitems as $item)
+            {
+                $state = intval($item['order_state']);
+                if(!array_key_exists($state,$order_state)) {
+                    $order_state[$state] = 0;
+                }
+
+                $order_state[$state] += 1;
+            }
+
+            //检查一种订单只能有,成功或者失败状态.
+            $vcount = count($vitems);
+            if($vcount != $order_state[ORDER_STATE_SUCCESS] + $order_state[ORDER_STATE_CANCEL]) {
+                return [false, [], 'ORDER: SUCCESS + CANCEL != COUNT.'];
+            }
+            elseif($order_state[ORDER_STATE_SUCCESS] > 1) {
+                //成功订单只能小于等于1,否则为错误
+                return [false, [], 'ORDER:SUCCESS COUNT > 1'];
+            }
+            else
+            {
+                foreach ($ritems as $item) {
+                    fputcsv($frefill,$item);
+                }
+                foreach ($vitems as $item) {
+                    fputcsv($fvr,$item);
+                }
+            }
+
+            $inner_oids = [];
+            foreach ($ritems as $item)
+            {
+                $status = intval($item['inner_status']);
+                if($status === 1) {
+                    $inner_oids[] = $item['order_id'];
+                }
+            }
+
+            return [true,$inner_oids,''];
+        };
+
+        $delter = function ($order_ids,$order_time)
+        {
+            if(empty($order_ids)) return;
+
+            try {
+                $mod_refill = Model('refill_order');
+                $mod_vr = Model('vr_order');
+
+                $trans = new trans_wapper($mod_refill, __METHOD__);
+                $mod_refill->table('refill_order')->where(['order_id' => ['in',$order_ids],'order_time' => $order_time])->delete();
+                $mod_vr->table('vr_order')->where(['order_id' => ['in',$order_ids]])->delete();
+                $trans->commit();
+            } catch (Exception $e) {
+                $trans->rollback();
+            }
+        };
+
+        $file_opener = function ($mch_file, $check_file, $refill_file, $vr_file)
+        {
+            $fp = fopen($mch_file,'r');
+            $fcheck = fopen($check_file,'a+');
+            $frefill = fopen($refill_file,'a+');
+            $fvr = fopen($vr_file,'a+');
+
+            if($fp === false || $fcheck === false || $frefill === false || $fvr === false)
+            {
+                if($fp !== false) {
+                    fclose($fp);
+                }
+                if($fcheck !== false) {
+                    fclose($fcheck);
+                }
+                if($frefill !== false) {
+                    fclose($frefill);
+                }
+                if($fvr !== false) {
+                    fclose($fvr);
+                }
+
+                return [false,false,false,false,false];
+            }
+            else {
+                return [true,$fp,$fcheck,$frefill,$fvr];
+            }
+        };
+
+        $file_closer = function($files)
+        {
+            foreach ($files as $fp) {
+                fclose($fp);
+            }
+        };
+
+        $goto_line = function ($fp,$line)
+        {
+            $index = 0;
+            while(!feof($fp) && $index < $line) {
+                $items = fgetcsv($fp);
+                $index += 1;
+            }
+        };
+
+        $mch_order_reader = function($fp)
+        {
+            while(!feof($fp))
+            {
+                [$mchid, $mch_order, $order_time] = fgetcsv($fp);
+
+                if(empty($mchid) || empty($mch_order)) continue;
+                yield [$mchid,$mch_order,$order_time];
+            }
+        };
+
+        $mod_refill_err = Model('refill_error');
+        $err_recorder = function($fcheck,$mchid,$mch_order,$order_time,$err) use($mod_refill_err)
+        {
+            fputcsv($fcheck,[$mchid,$mch_order,$err]);
+            $mod_refill_err->insert(['mchid' => $mchid, 'mch_order' => $mch_order, 'order_time' => $order_time, 'msg' => $err, 'add_time' => time()]);
+        };
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        [$succ,$fp,$fcheck,$frefill,$fvr] = $file_opener($mch_file, $check_file, $refill_file, $vr_file);
+        if(!$succ) {
+            return false;
+        }
+
+        $goto_line($fp,$line);
+
+        $mch_orders = $mch_order_reader($fp);
+        foreach ($mch_orders as $order)
+        {
+            [$mchid, $mch_order, $order_time] = $order;
+            [$succ, $order_ids, $err] = $order_checker($mchid, $mch_order, $frefill, $fvr);
+            if ($succ) {
+                $delter($order_ids, $order_time);
+            } else {
+                $err_recorder($fcheck, $mchid, $mch_order, $order_time, $err);
+            }
+        }
+
+        $file_closer([$fp,$fcheck,$frefill,$fvr]);
+
+        return true;
+    }
+}

+ 11 - 0
helper/refill/ops/pdlog_clear.php

@@ -0,0 +1,11 @@
+<?php
+
+namespace refill;
+use Log;
+use trans_wapper;
+use Exception;
+
+class pdlog_clear
+{
+
+}

+ 28 - 0
test/TestLanguage.php

@@ -0,0 +1,28 @@
+<?php
+
+
+use PHPUnit\Framework\TestCase;
+
+class TestLanguage extends TestCase
+{
+    public function testYield()
+    {
+        $checker = function ($val) {
+          return $val > 5 ? true : false;
+        };
+
+        $map_adder = function ($datas,$delta)
+        {
+            foreach ($datas as $val) {
+                $k = yield $val + $delta;
+            }
+        };
+
+        $datas = [1,2,3,4,5,6];
+        $x = $map_adder($datas,2);
+
+        foreach ($x as $v) {
+            $t = $checker($v);
+        }
+    }
+}

+ 20 - 321
test/TestRefillClear.php

@@ -10,6 +10,8 @@ require_once(BASE_ROOT_PATH . '/global.php');
 require_once(BASE_CORE_PATH . '/lrlz.php');
 require_once(BASE_ROOT_PATH . '/fooder.php');
 
+require_once(BASE_HELPER_PATH . '/refill/ops/order_clear.php');
+
 class TestRefillClear extends TestCase
 {
     public static function setUpBeforeClass(): void
@@ -17,13 +19,23 @@ class TestRefillClear extends TestCase
         Base::run_util();
     }
 
+    public function testOrderClear()
+    {
+        $start_date = strtotime('2021-09-11');
+        $end_date   = strtotime('2021-09-13');
+
+        $clear = new refill\order_clear();
+        $clear->clear($start_date,$end_date);
+    }
+
     //docker-compose run phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::testClearFirstDay)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
     public function testClearFirstDay()
     {
         $start_date = strtotime($this->earlist_orderday());
         $end_date   = $start_date + 86400;
 
-        $this->clear($start_date,$end_date);
+        $clear = new refill\order_clear();
+        $clear->clear($start_date,$end_date);
     }
     //2021年,8、9、10、11
 
@@ -32,331 +44,18 @@ class TestRefillClear extends TestCase
     {
         $start_date = strtotime('2021-12-20');
         $end_date   = strtotime('2022-12-28');
-        $this->clear($start_date,$end_date);
+
+        $clear = new refill\order_clear();
+        $clear->clear($start_date,$end_date);
     }
 
     //docker-compose run -d phpcli php /var/www/html/phpunit-9.2.5.phar --filter "/(TestRefillClear::test202202)( .*)?$/" --test-suffix TestRefillClear.php /var/www/html/test
     public function test202202()
     {
-        $start_date = strtotime('2022-02-20');
-        $end_date   = strtotime('2022-02-21');
-        $this->clear($start_date,$end_date);
-    }
-
-    public function testAllRecords()
-    {
-        $rorder_getter = function ($mchid,$mch_order,$mod_refill)
-        {
-            $result = [];
-            $i = 0;
-            while(true)
-            {
-                $start = $i * 1000;
-                $ritems = $mod_refill->table('refill_order')->field('*')
-                    ->where(['mchid' => $mchid, 'mch_order' => $mch_order])
-                    ->order('order_id desc')
-                    ->limit("{$start},1000")->master(true)->select();
-                $i++;
-
-                $result = array_merge($ritems,$result);
-                if(count($ritems) < 1000) {
-                    break;
-                }
-            }
-
-            return $result;
-        };
-
-        $vorder_getter = function ($order_ids,$mod_vr)
-        {
-            $result = [];
-            $i = 0;
-            while(true)
-            {
-                $start = $i * 1000;
-
-                $vitems = $mod_vr->table('vr_order')->field('*')
-                    ->where(['order_id' => ['in', $order_ids]])
-                    ->order('order_id asc')
-                    ->limit("{$start},1000")->master(true)->select();
-                $i++;
-
-                $result = array_merge($vitems,$result);
-                if(count($vitems) < 1000) {
-                    break;
-                }
-            }
-
-            return $result;
-        };
-
-        $mod_refill = Model('refill_order');
-        $ritems = $rorder_getter(10234,'2021120700113026892979',$mod_refill);
-        $oids = [];
-        foreach ($ritems as $item) {
-            $oids[] = $item['order_id'];
-        }
-
-        $mod_vr = Model('vr_order');
-        $vitems = $vorder_getter($oids,$mod_vr);
-
-        $ret = count($vitems) == count($ritems);
-    }
-
-    private function clear($start_date, $end_date,$line = 0)
-    {
-        $order_finder = function ($start,$fp)
-        {
-            $end = $start + 3600;
-            $cond = ['order_time&order_time' => ['_multi' => true, ['egt', $start], ['lt', $end]],
-                     'inner_status' => 0];
-
-            $i = 0;
-            while (true)
-            {
-                $start = $i * 1000;
-                $items = Model()->table('refill_order')
-                    ->field('mchid,mch_order,order_time')
-                    ->where($cond)
-                    ->order('order_time desc')->limit("{$start},1000")->select();
-                $i++;
-
-                if(empty($items)) break;
-                foreach ($items as $item) {
-                    fputcsv($fp,$item);
-                }
-            }
-        };
-
-        $order_saver = function ($start,$file) use ($order_finder)
-        {
-            if(file_exists($file)) {
-                return $file;
-            }
-
-            $fp = fopen($file,'w+');
-            if($fp === false) {
-                Log::record("Cannot open file {$file}.",Log::ERR);
-                return false;
-            }
-
-            $end = $start + 86400;
-            for ($hour = $start; $hour < $end; $hour += 3600) {
-                $order_finder($hour,$fp);
-            }
-            fclose($fp);
-
-            return $file;
-        };
-
-        $handle_days = function ($start_date, $end_date,$line = 0) use ($order_saver)
-        {
-            for ($date = $start_date; $date < $end_date; $date += 86400)
-            {
-                $sdate = date('Y-m-d',$date);
-
-                $morder_file = BASE_DATA_PATH . "/log/order/{$sdate}-morder.csv";
-                $check_file  = BASE_DATA_PATH . "/log/order/{$sdate}-check.csv";
-                $refill_file  = BASE_DATA_PATH . "/log/order/{$sdate}-refill.csv";
-                $vr_file  = BASE_DATA_PATH . "/log/order/{$sdate}-vr.csv";
-
-                $file = $order_saver($date,$morder_file);
-                if($file === false) {
-                    Log::record("order_saver cannot open morder file.",Log::ERR);
-                    break;
-                }
-
-                $this->order_delete($file,$check_file,$refill_file,$vr_file,$line);
-            }
-        };
-
-        $handle_days($start_date, $end_date,$line);
-    }
-
-    private function order_delete($file,$check_file,$refill_file,$vr_file,$line)
-    {
-        $rorder_getter = function ($mchid,$mch_order,$mod_refill)
-        {
-            $result = [];
-            $i = 0;
-            while(true)
-            {
-                $start = $i * 1000;
-                $ritems = $mod_refill->table('refill_order')->field('*')
-                    ->where(['mchid' => $mchid, 'mch_order' => $mch_order])
-                    ->order('order_id desc')
-                    ->limit("{$start},1000")->master(true)->select();
-                $i++;
-
-                $result = array_merge($ritems,$result);
-                if(count($ritems) < 1000) {
-                    break;
-                }
-            }
-
-            return $result;
-        };
-
-        $vorder_getter = function ($order_ids,$mod_vr)
-        {
-            $result = [];
-            $i = 0;
-            while(true)
-            {
-                $start = $i * 1000;
-
-                $vitems = $mod_vr->table('vr_order')->field('*')
-                    ->where(['order_id' => ['in', $order_ids]])
-                    ->order('order_id asc')
-                    ->limit("{$start},1000")->master(true)->select();
-                $i++;
-
-                $result = array_merge($vitems,$result);
-                if(count($vitems) < 1000) {
-                    break;
-                }
-            }
-
-            return $result;
-        };
-
-
-        $order_checker = function ($mchid,$mch_order,$frefill,$fvr) use($rorder_getter,$vorder_getter)
-        {
-            $mod_refill = Model('refill_order');
-            $ritems = $rorder_getter($mchid,$mch_order,$mod_refill);
-
-            if(empty($ritems)) {
-                return [false,'没查到记录.'];
-            }
-            elseif(count($ritems) === 1) {
-                return [true,[]];
-            }
-
-            $oids = [];
-            $inner_state = [0 => 0 ,1 => 1];
-            foreach ($ritems as $item) {
-                $oids[] = $item['order_id'];
-                $state = intval($item['inner_status']);
-                $inner_state[$state] += 1;
-            }
-
-            //检查inner_status=0唯一。
-            if($inner_state[0] != 1) {
-                return [false,"inner_status=0 counts = {$inner_state[0]}"];
-            }
-
-            $mod_vr = Model('vr_order');
-            $vitems = $vorder_getter($oids,$mod_vr);
-
-            //检查refill 表记录和vr_order表记录是否一致
-            if(count($ritems) !== count($vitems)) {
-                return [false,'refill_orders != vr_orders'];
-            }
-
-            $order_state = [];
-            foreach ($vitems as $item)
-            {
-                $state = intval($item['order_state']);
-                if(!array_key_exists($state,$order_state)) {
-                    $order_state[$state] = 0;
-                }
-
-                $order_state[$state] += 1;
-            }
-
-            //检查一种订单只能有,成功或者失败状态.
-            $vcount = count($vitems);
-            if($vcount != $order_state[ORDER_STATE_SUCCESS] + $order_state[ORDER_STATE_CANCEL]) {
-                return [false,'ORDER_STATE_SUCCESS + ORDER_STATE_CANCEL != order count.'];
-            }
-            elseif($order_state[ORDER_STATE_SUCCESS] > 1) {
-                //成功订单只能小于等于1,否则为错误
-                return [false,'ORDER_STATE_SUCCESS count > 1'];
-            }
-            else {
-                foreach ($ritems as $item) {
-                    fputcsv($frefill,$item);
-                }
-                foreach ($vitems as $item) {
-                    fputcsv($fvr,$item);
-                }
-            }
-
-            $inner_orders = [];
-            foreach ($ritems as $item)
-            {
-                $status = intval($item['inner_status']);
-                if($status === 1) {
-                    $inner_orders[] = $item['order_id'];
-                }
-            }
-
-            return [true,$inner_orders];
-        };
-
-        $delter = function ($order_ids,$order_time)
-        {
-            try {
-                $mod_refill = Model('refill_order');
-                $mod_vr = Model('vr_order');
-
-                $trans = new trans_wapper($mod_refill, __METHOD__);
-                $mod_refill->table('refill_order')->where(['order_id' => ['in',$order_ids],'order_time' => $order_time])->delete();
-                $mod_vr->table('vr_order')->where(['order_id' => ['in',$order_ids]])->delete();
-                $trans->commit();
-            } catch (Exception $e) {
-                $trans->rollback();
-            }
-        };
-
-        $position = function ($fp,$line)
-        {
-            $index = 0;
-            while(!feof($fp) && $index < $line) {
-                $items = fgetcsv($fp);
-                $index += 1;
-            }
-        };
-
-
-        $fp = fopen($file,'r');
-        if($fp === false) {
-            return false;
-        }
-
-        $fcheck = fopen($check_file,'a+');
-        if($fcheck === false) {
-            fclose($fp);
-            return false;
-        }
-        $frefill = fopen($refill_file,'a+');
-        $fvr = fopen($vr_file,'a+');
-
-        $position($fp,$line);
-        while(!feof($fp))
-        {
-            [$mchid, $mch_order, $order_time] = fgetcsv($fp);
-
-            if(empty($mchid) || empty($mch_order)) continue;
-
-            [$succ,$err] = $order_checker($mchid,$mch_order,$frefill,$fvr);
-            if($succ === false) {
-                fputcsv($fcheck,[$mchid,$mch_order,$err]);
-            }
-            else
-            {
-                $order_ids = $err;
-                if(!empty($order_ids)) {
-                    $delter($order_ids,$order_time);
-                }
-            }
-        }
-
-        fclose($fp);
-        fclose($fcheck);
-        fclose($frefill);
-        fclose($fvr);
+        $start_date = strtotime('2022-02-21');
+        $end_date   = strtotime('2022-02-24');
+        $clear = new refill\order_clear();
+        $clear->clear($start_date,$end_date);
     }
 
     private function earlist_orderday()

+ 1 - 5
test/TestRefillCommand.php

@@ -22,11 +22,7 @@ class TestRefillCommand extends TestCase
     public function testRefillStat()
     {
         $dates = [
-            '2022-01-13',
-            '2022-01-16',
-            '2022-01-17',
-            '2022-01-18',
-            '2022-01-19'
+            '2022-02-22'
         ];
         $refill = new statistics\stat_refill();
         $refill->restat($dates);