瀏覽代碼

Merge branch 'ralb' into coall

stanley-king 3 年之前
父節點
當前提交
1cf2dacb7e
共有 100 個文件被更改,包括 20247 次插入2672 次删除
  1. 13 2
      admin/control/control.php
  2. 13 5
      admin/control/merchant.php
  3. 7 2
      admin/control/merchant_info.php
  4. 17 3
      admin/control/order_search.php
  5. 111 21
      admin/control/ordersendlist.php
  6. 9 8
      admin/control/orderstats.php
  7. 1 1
      admin/control/provider.php
  8. 1 1
      admin/control/provider_group.php
  9. 1 0
      admin/control/provider_info.php
  10. 47 7
      admin/control/refill_cron.php
  11. 175 0
      admin/control/refill_detail.php
  12. 5 0
      admin/control/refill_evidence.php
  13. 18 9
      admin/control/refill_order.php
  14. 9 4
      admin/control/refill_order_manual.php
  15. 1 1
      admin/control/refill_stock.php
  16. 4 4
      admin/control/refill_successful.php
  17. 2 1
      admin/control/store.php
  18. 1 0
      admin/include/limit.php
  19. 1 0
      admin/include/menu.php
  20. 10 3
      admin/templates/default/merchant.edit.php
  21. 3 1
      admin/templates/default/merchant.index.php
  22. 5 2
      admin/templates/default/merchant.order.stats.php
  23. 6 0
      admin/templates/default/merchant.price.php
  24. 12 3
      admin/templates/default/merchant.refill.evidence_list.php
  25. 49 1
      admin/templates/default/provider.amount.control.php
  26. 26 2
      admin/templates/default/provider.group.php
  27. 18 2
      admin/templates/default/provider.index.php
  28. 5 2
      admin/templates/default/provider.order.stats.php
  29. 9 3
      admin/templates/default/refill.cron.php
  30. 364 0
      admin/templates/default/refill.detail.php
  31. 12 2
      admin/templates/default/refill.order.index.php
  32. 181 5
      admin/templates/default/refill.order.neterr.index.php
  33. 80 3
      admin/templates/default/refill.order.notify.err.index.php
  34. 109 7
      admin/templates/default/refill.order.search.php
  35. 54 5
      admin/templates/default/refill.order.send.index.php
  36. 50 30
      core/framework/cache/cache.redis.php
  37. 10 21
      core/framework/db/mysqli.php
  38. 22 21
      core/framework/function/core.php
  39. 8 2
      core/framework/function/goods.php
  40. 3 3
      core/framework/function/http.php
  41. 2 2
      core/framework/libraries/model.php
  42. 18 1
      crontab/control/date.php
  43. 36 3
      crontab/control/minutes.php
  44. 1465 17
      data/config/dev/refill.ini.php
  45. 799 97
      data/config/win/refill.ini.php
  46. 799 97
      data/config/xyz/refill.ini.php
  47. 799 97
      data/config/xyzadm/refill.ini.php
  48. 1 1
      data/config/xyztest/base.ini.php
  49. 13 1
      data/config/xyztest/refill.ini.php
  50. 118 0
      data/model/fetch_order.model.php
  51. 23 0
      data/model/refill_detail.model.php
  52. 22 0
      data/model/refill_order.model.php
  53. 0 10
      docker/compose/stanley/docker-compose.yml
  54. 83 0
      docker/compose/xyz-arw/docker-compose.yml
  55. 38 0
      docker/compose/xyz-storage/docker-compose.yml
  56. 0 0
      docker/compose/xyz-worker/restart.sh
  57. 30 0
      docker/compose/xyz/admin/docker-compose.yml
  58. 78 0
      docker/compose/xyz/arw/docker-compose.yml
  59. 4 0
      docker/compose/xyz/arw/restart_all.sh
  60. 3 0
      docker/compose/xyz/arw/restart_cordsrv.sh
  61. 3 0
      docker/compose/xyz/arw/stop_all.sh
  62. 19 0
      docker/compose/xyz/conf/crontab/root
  63. 二進制
      docker/compose/xyz/conf/etc/localtime
  64. 127 0
      docker/compose/xyz/conf/nginx/nginx.conf
  65. 143 0
      docker/compose/xyz/conf/php-fpm/php-fpm.conf
  66. 12 0
      docker/compose/xyz/conf/php/mch-spwan-start
  67. 11 0
      docker/compose/xyz/conf/php/mobile-spwan-start
  68. 1944 0
      docker/compose/xyz/conf/php/php-swoole.ini
  69. 1942 0
      docker/compose/xyz/conf/php/php.ini
  70. 944 0
      docker/compose/xyz/conf/redis/6379.conf
  71. 944 0
      docker/compose/xyz/conf/redis/6380.conf
  72. 47 0
      docker/compose/xyz/stat/docker-compose.yml
  73. 36 0
      docker/compose/xyz/storage/docker-compose.yml
  74. 0 130
      docker/compose/xyzt-acc/docker-compose.yml
  75. 0 39
      docker/compose/xyzt-worker/docker-compose.yml
  76. 30 0
      docker/compose/xyzt/admin/docker-compose.yml
  77. 78 0
      docker/compose/xyzt/arw/docker-compose.yml
  78. 4 0
      docker/compose/xyzt/arw/restart_all.sh
  79. 3 0
      docker/compose/xyzt/arw/restart_cordsrv.sh
  80. 3 0
      docker/compose/xyzt/arw/stop_all.sh
  81. 18 0
      docker/compose/xyzt/conf/crontab/root
  82. 二進制
      docker/compose/xyzt/conf/etc/localtime
  83. 127 0
      docker/compose/xyzt/conf/nginx/nginx.conf
  84. 143 0
      docker/compose/xyzt/conf/php-fpm/php-fpm.conf
  85. 12 0
      docker/compose/xyzt/conf/php/mch-spwan-start
  86. 11 0
      docker/compose/xyzt/conf/php/mobile-spwan-start
  87. 1944 0
      docker/compose/xyzt/conf/php/php-swoole.ini
  88. 1942 0
      docker/compose/xyzt/conf/php/php.ini
  89. 944 0
      docker/compose/xyzt/conf/redis/6379.conf
  90. 944 0
      docker/compose/xyzt/conf/redis/6380.conf
  91. 6 6
      docker/compose/xyzt-sender/docker-compose.yml
  92. 47 0
      docker/compose/xyzt/stat/docker-compose.yml
  93. 36 0
      docker/compose/xyzt/storage/docker-compose.yml
  94. 5 5
      docker/conf/crontab/root
  95. 1941 1941
      docker/conf/php/xyz-php.ini
  96. 2 0
      global.php
  97. 31 34
      helper/fcgisrv/MobileServer.php
  98. 0 2
      helper/message/msgutil.php
  99. 1 2
      helper/message/subscriber.php
  100. 0 0
      helper/mtopcard/mtopcard.php

+ 13 - 2
admin/control/control.php

@@ -333,6 +333,7 @@ class SystemControl
     protected function quality_format($quality,$card_type) {
 	    $oil_text = [
 	        1 => '无流水',
+            3 => '卡密',
             5 => '有流水'
         ];
 	    $phone_text = [
@@ -342,7 +343,9 @@ class SystemControl
             4 => '三方',
             5 => '慢24',
             6 => '慢6',
-            7 => '慢2'
+            7 => '慢2',
+            8 => '慢48',
+            9 => '慢72'
         ];
         $text = [
             mtopcard\PetroChinaCard => $oil_text,
@@ -351,7 +354,7 @@ class SystemControl
             mtopcard\ChinaUnicomCard => $phone_text,
             mtopcard\ChinaTelecomCard => $phone_text
         ];
-        return $text[$card_type][$quality] ?? '未知';
+        return $text[$card_type][$quality] ?? $quality;
     }
 
     protected function elapse_time($seconds)
@@ -373,4 +376,12 @@ class SystemControl
         }
         return $result;
     }
+
+    protected function check_fetch_order($order_sn): bool
+    {
+        $mod = Model('fetch_order');
+        $cond['order_sn'] = $order_sn;
+        $res = $mod->order_info($cond);
+        return empty($res);
+    }
 }

+ 13 - 5
admin/control/merchant.php

@@ -7,7 +7,7 @@
 defined('InShopNC') or exit('Access Invalid!');
 
 require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
-require_once(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
+include(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
 require_once(BASE_ROOT_PATH . '/core/framework/function/http.php');
 require_once(BASE_HELPER_PATH . '/stat_helper.php');
 
@@ -619,6 +619,9 @@ class merchantControl extends SystemControl
         $input['admin_name'] = $admininfo['name'];
         $input['admin_id'] = $admininfo['id'];
         $input['add_type'] = $params['add_type'];
+        if($params['type'] == 'add') {
+            $input['is_bank'] = 1;
+        }
 
         $model_merchant = Model('merchant');
         return $model_merchant->addRefillEvidence($input);
@@ -787,8 +790,9 @@ class merchantControl extends SystemControl
         $mod_order = Model('vr_order');
         $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
 
-        if ((time() - $order_info['order_time']) < 3600) {
-            showMessage('订单时间未超过1小时', 'index.php?act=refill_order&op=index');
+        $check_fetch_order = $this->check_fetch_order($order_info['order_sn']);
+        if($check_fetch_order == false) {
+            showMessage('此订单不可手动操作,请联系抢单人员操作!');
         }
         if ($type == 'success') {
             refill\util::manual_success($order_id);
@@ -962,8 +966,11 @@ class merchantControl extends SystemControl
         $type = $_GET['type'] ?? $_POST['type'];
         $form = $_GET['form'] ?? $_POST['form'];
         $rkey = $this->speed_key($type, $form);
-        $quality = ['common' => \refill\Quality::Normal, 'fast' => \refill\Quality::Quick, 'card' => \refill\Quality::CardKey,
-            'third' => \refill\Quality::ThirdShop, 'slow' => \refill\Quality::SlowTwentyFour , 'slow6' => \refill\Quality::SlowSix, 'slow2' => \refill\Quality::SlowTwo];
+        $quality = [
+            'common' => \refill\Quality::Normal, 'fast' => \refill\Quality::Quick, 'card' => \refill\Quality::CardKey,
+            'third' => \refill\Quality::ThirdShop, 'slow' => \refill\Quality::SlowTwentyFour , 'slow6' => \refill\Quality::SlowSix,
+            'slow2' => \refill\Quality::SlowTwo, 'slow48' => \refill\Quality::SlowFortyEight, 'slow72' => \refill\Quality::SlowSeventyTwo
+        ];
         if (chksubmit()) {
             $pids = $_POST['pid'];
             $names = $_POST['name'];
@@ -989,6 +996,7 @@ class merchantControl extends SystemControl
                 $index = "{$data['type']}-{$data['amount']}";
                 $result[$index][] = $data;
             }
+//            Log::record("provider amount data:".json_encode($result),Log::DEBUG);
             wcache($rkey, ['data' => serialize($result)], 'provider-');
             showMessage('编辑成功', 'index.php?act=provider&op=index');
         } else {

+ 7 - 2
admin/control/merchant_info.php

@@ -27,6 +27,7 @@ class merchant_infoControl extends SystemControl
         }
         Tpl::output('merchants', $merchants);
         Tpl::output('info_list', $info_list);
+        Tpl::output('page', $mod->showpage());
         Tpl::showpage('merchant.info');
     }
 
@@ -202,6 +203,10 @@ class merchant_infoControl extends SystemControl
                         $data = $cell->getValue();
                         $items[] = $data;
                     }
+                    if(empty($items) || count($items) < 7){
+                        Log::record("items empty or length err",LOG::DEBUG);
+                        continue;
+                    }
                     $mchid = intval($items[0]);
                     $params = [
                         'mchid' => $mchid,
@@ -219,8 +224,8 @@ class merchant_infoControl extends SystemControl
                     }
                     $json_txt = json_encode($params);
                     Log::record("import data: {$json_txt}",LOG::DEBUG);
-                    if(empty($params['store_id']) || empty($params['store_name'])) {
-                        Log::record("merchant evidence import err,not find store info, mchid: {$mchid}, amount: {$params['amount']}",LOG::DEBUG);
+                    if(empty($params['mchid']) || empty($params['company_name'])) {
+                        Log::record("merchant evidence import err,not find merchant info, mchid: {$mchid}, amount: {$params['amount']}",LOG::DEBUG);
                     }
                     $res = $mod->addMerchantEvidence($params);
                     if(!$res){

+ 17 - 3
admin/control/order_search.php

@@ -13,11 +13,20 @@ class order_searchControl extends SystemControl
         $model_refill_order = Model('refill_order');
         $order_list = [];
         $_GET['query_start_time'] = $_GET['query_start_time'] ?? date("Y-m-d 00:00:00");
+        //批量查询,二者都有,以卡号为主
         if(!empty($_GET['card_nos'])) {
-            $condition['refill_order.inner_status'] = 0;
             $card_nos = $_GET['card_nos'];
             $card_nos = str_replace(["\r\n", "\r", "\n"], ",", $card_nos);
             $condition['refill_order.card_no'] = ['in', $card_nos];
+        } elseif (!empty($_GET['mch_orders'])) {
+            $mch_orders = $_GET['mch_orders'];
+            $mch_orders = str_replace(["\r\n", "\r", "\n"], ",", $mch_orders);
+            $condition['refill_order.mch_order'] = ['in', $mch_orders];
+        } else {
+            $condition = [];
+        }
+        if(!empty($condition)) {
+            $condition['refill_order.inner_status'] = 0;
 
             $start_unixtime = intval(strtotime($_GET['query_start_time']));
             $end_unixtime = intval(strtotime($_GET['query_end_time']));
@@ -41,8 +50,13 @@ class order_searchControl extends SystemControl
             foreach ($order_list as $order_id => $order_info) {
                 $order_list[$order_id]['card_type_text'] = $this->scard_type($order_info['card_type']);
                 $order_list[$order_id]['mch_name'] = $merchants[$order_info['mchid']]['company_name'];
-                $order_list[$order_id]['diff_time_text'] = $this->elapse_time(time() - $order_info['order_time']);
-                $order_list[$order_id]['diff_time'] = time() - $order_info['order_time'];
+                if ($order_info['notify_time'] > 0) {
+                    $diff_time = $order_info['notify_time'] - $order_info['order_time'];
+                } else {
+                    $diff_time = time() - $order_info['order_time'];
+                }
+                $order_list[$order_id]['diff_time_text'] = $this->elapse_time($diff_time);
+                $order_list[$order_id]['diff_time'] = $diff_time;
                 $order_list[$order_id]['quality_text'] = $this->quality_format($order_info['quality'],$order_info['card_type']);
             }
         }

+ 111 - 21
admin/control/ordersendlist.php

@@ -1,5 +1,8 @@
 <?php
+require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
+require_once(BASE_HELPER_PATH . '/refill/util.php');
 
+use refill\util;
 
 class ordersendlistControl extends SystemControl
 {
@@ -13,8 +16,14 @@ class ordersendlistControl extends SystemControl
         $model_refill_order = Model('refill_order');
         $condition['refill_order.inner_status'] = 0;
         $condition['vr_order.order_state'] = ORDER_STATE_SEND;
+        if(empty($_GET['quality'])) {
+            //默认普充
+            $_GET['quality'] = 2;
+        }
 
-        $condition['refill_order.order_time'] = ['lt', (time() - 300)];
+        $time = time() - 20;
+        $condition['refill_order.order_time'] = ['exp', "refill_order.order_time < ({$time} - merchant.time_out)"];
+//        $condition['refill_order.order_time'] = ['lt',time()-300];
         if (!empty($_GET['mchid'])) {
             $condition['refill_order.mchid'] = $_GET['mchid'];
         }
@@ -30,13 +39,13 @@ class ordersendlistControl extends SystemControl
         if ($_GET['time'] == 2) {
             $condition['refill_order.order_time'] = ['lt', (time() - 3600)];
         }
-        $time_out_order = function($time_out, $condition){
+        $time_out_order = function ($time_out, $condition) {
             $mchids = Model('')->table('merchant')->where(['time_out' => ['elt', $time_out]])->field('mchid')->select();
             $mchids = array_column($mchids, 'mchid');
             $mchids = implode(',', $mchids);
 
             $condition['refill_order.order_time'] = ['lt', (time() - $time_out)];
-            $condition['refill_order.mchid'] = ['in',$mchids];
+            $condition['refill_order.mchid'] = ['in', $mchids];
             return $condition;
         };
         if ($_GET['time'] == 3) {
@@ -52,12 +61,18 @@ class ordersendlistControl extends SystemControl
         if ($_GET['time'] == 5) {
             $condition = $time_out_order(600, $condition);
             $time_cond[] = ['lt', (time() - 600)];
+            $_GET['card_type'] = 'phone';
         }
         if ($_GET['time'] == 6) {
             $condition = $time_out_order(900, $condition);
             $time_cond[] = ['lt', (time() - 900)];
             $_GET['card_type'] = 'phone';
         }
+        if ($_GET['time'] == 7) {
+            $condition = $time_out_order(7200, $condition);
+            $time_cond[] = ['lt', (time() - 7200)];
+            $_GET['card_type'] = 'phone';
+        }
 
         if (!empty($_GET['card_type'])) {
             if (in_array($_GET['card_type'], ['1', '2', '4', '5', '6', '7'])) {
@@ -74,17 +89,24 @@ class ordersendlistControl extends SystemControl
             $condition['refill_order.quality'] = $_GET['quality'];
         }
 
-        $order_list = $model_refill_order->getMerchantOrderList($condition, 50, 'refill_order.*,vr_order.order_state', 'refill_order.order_time asc');
+        $order_list = $model_refill_order->getMerchantTimeOut($condition, 50, 'refill_order.*,vr_order.order_state', 'refill_order.order_time asc');
+//        $order_list = $model_refill_order->getMerchantOrderList($condition, 50, 'refill_order.*,vr_order.order_state', 'refill_order.order_time asc');
 
-        $stat = Model('')->table('refill_order,vr_order')->join('inner')
-            ->on('refill_order.order_id=vr_order.order_id')
+        $stat = Model('')->table('refill_order,vr_order,merchant')->join('inner,inner')
+            ->on('refill_order.order_id=vr_order.order_id,refill_order.mchid=merchant.mchid')
             ->field('count(*) as order_count ,sum(refill_amount) as refill_amounts, sum(channel_amount) as channel_amounts, sum(mch_amount) as mch_amounts')
             ->where($condition)->find();
-        $count = $this->refill_stats($condition,$time_cond);
+//        $stat = Model('')->table('refill_order,vr_order')->join('inner')
+//            ->on('refill_order.order_id=vr_order.order_id')
+//            ->field('count(*) as order_count ,sum(refill_amount) as refill_amounts, sum(channel_amount) as channel_amounts, sum(mch_amount) as mch_amounts')
+//            ->where($condition)->find();
+        $count = $this->refill_stats($condition, $time_cond);
 
         $merchant_list = Model('')->table('merchant')->limit(1000)->order('name asc')->select();
 
-        $order_list = $this->orderFormat($order_list,$merchant_list);
+        if(!empty($order_list)) {
+            $order_list = $this->orderFormat($order_list, $merchant_list);
+        }
         $provider_list = Model('')->table('refill_provider,store')
             ->field('refill_provider.*,store.store_name')
             ->join('inner')
@@ -123,7 +145,7 @@ class ordersendlistControl extends SystemControl
     public function neterr_orderOp()
     {
         $model_refill_order = Model('refill_order');
-        if(!empty($_GET['store_id'])) {
+        if (!empty($_GET['store_id'])) {
             $condition['vr_order.store_id'] = $_GET['store_id'];
         }
         $condition['refill_order.inner_status'] = 0;
@@ -132,7 +154,7 @@ class ordersendlistControl extends SystemControl
 
         $order_list = $model_refill_order->getMerchantOrderList($condition, 50, 'refill_order.*,vr_order.order_state', 'refill_order.order_time asc');
         $merchant_list = Model('')->table('merchant')->limit(1000)->order('name asc')->select();
-        $order_list = $this->orderFormat($order_list,$merchant_list);
+        $order_list = $this->orderFormat($order_list, $merchant_list);
 
         $provider_list = Model('')->table('refill_provider,store')
             ->field('refill_provider.*,store.store_name')
@@ -147,7 +169,49 @@ class ordersendlistControl extends SystemControl
         Tpl::showpage('refill.order.neterr.index');
     }
 
-    public function orderFormat($order_list, $merchant_list)
+    public function neterr_order_manualOp()
+    {
+        $type = $_GET['type'];
+        $official_sn = $_GET['official_sn'] ?? '';
+        if ($type != 'success' && $type != 'cancel') {
+            showMessage('手动操作类型错误');
+        }
+        $order_ids = $_GET['order_ids'];
+        $model_refill_order = Model('refill_order');
+        $condition['refill_order.order_id'] = ['in', $order_ids];
+        $condition['refill_order.inner_status'] = 0;
+        $condition['refill_order.neterr'] = 1;
+        $condition['vr_order.order_state'] = ORDER_STATE_PAY;
+
+        $order_list = $model_refill_order->getMerchantOrderList($condition);
+        if (empty($order_list)) {
+            showMessage('暂无数据');
+        }
+        $logic_vr_order = Logic("vr_order");
+        $mod_vr_order = Model('vr_order');
+        foreach ($order_list as $order) {
+            $order_id = $order['order_id'];
+            if ($type == 'success') {
+                $logic_vr_order->changeOrderStateSuccess($order_id, true);
+                if (!empty($official_sn)) {
+                    $model_refill_order->edit($order_id, ['official_sn' => $official_sn]);
+                }
+            } elseif ($type == 'cancel') {
+                $order_info = $mod_vr_order->getOrderInfo(['order_id' => $order_id]);
+                $logic_vr_order->changeOrderStateCancel($order_info, '', "充值失败", true, true);
+            } else {
+                continue;
+            }
+            if ($order['notify_time'] == 0) {
+                $model_refill_order->edit($order_id, ['notify_state' => 1, 'notify_time' => time()]);
+            }
+            util::pop_queue_order($order['mchid'], $order['mch_order']);
+            QueueClient::push("NotifyMerchantComplete", ['order_id' => $order_id, 'manual' => true]);
+        }
+        showMessage('操作成功');
+    }
+
+    public function orderFormat($order_list, $merchant_list): array
     {
         $merchants = [];
         foreach ($merchant_list as $value) {
@@ -164,8 +228,30 @@ class ordersendlistControl extends SystemControl
 
             $order_list[$order_id]['diff_time'] = $diff_time;
             $order_list[$order_id]['diff_time_text'] = $this->elapse_time($diff_time);
-
-            $order_list[$order_id]['quality_text'] = $this->quality_format($order_info['quality'],$order_info['card_type']);
+            $order_list[$order_id]['quality_text'] = $this->quality_format($order_info['quality'], $order_info['card_type']);
+            if ($diff_time > $merchants[$order_info['mchid']]['time_out'] && $order_info['order_state'] == ORDER_STATE_SEND) {
+                $order_list[$order_id]['time_out_state'] = 0;
+                if (in_array($order_info['card_type'], [mtopcard\PetroChinaCard, mtopcard\SinopecCard])) {
+                    $order_list[$order_id]['time_out_state'] = 1;
+                }
+                if (in_array($order_info['card_type'], [mtopcard\ChinaMobileCard, mtopcard\ChinaUnicomCard, mtopcard\ChinaTelecomCard])) {
+                    if (in_array($order_info['quality'], [
+                        \refill\Quality::SlowTwentyFour,
+                        \refill\Quality::SlowSix,
+                        \refill\Quality::SlowTwo,
+                        \refill\Quality::SlowFortyEight,
+                        \refill\Quality::SlowSeventyTwo])) {
+                        $order_list[$order_id]['time_out_state'] = 2;
+                    } elseif (in_array($order_info['mchid'], [10132])) {
+                        //重点机构
+                        $order_list[$order_id]['time_out_state'] = 3;
+                    } else {
+                        $order_list[$order_id]['time_out_state'] = 4;
+                    }
+                }
+            } else {
+                $order_list[$order_id]['time_out_state'] = 0;
+            }
         }
 
         return $order_list;
@@ -178,12 +264,15 @@ class ordersendlistControl extends SystemControl
         $order_state_cancel = ORDER_STATE_CANCEL;
         $order_state_success = ORDER_STATE_SUCCESS;
         $condition['refill_order.inner_status'] = 0;
-        $condition['vr_order.order_state'] = ['in',"{$order_state_cancel},{$order_state_success}"];
-        $condition['refill_order.mch_notify_state'] = 0;
-        if(empty($_GET['time'])) {
+        $condition['refill_order.is_retrying'] = 0;
+        $condition['vr_order.order_state'] = ['in', "{$order_state_cancel},{$order_state_success}"];
+        $condition['refill_order.mch_notify_state'] = ['in', "0,2"];
+        $condition['refill_order.mch_notify_times'] = ['gt', 0];
+
+        if (empty($_GET['time'])) {
             $_GET['time'] = 1;
         }
-        if(empty($_GET['notify_time'])) {
+        if (empty($_GET['notify_time'])) {
             $_GET['notify_time'] = 180;
         }
         $time = $_GET['time'] * 3600;
@@ -195,7 +284,7 @@ class ordersendlistControl extends SystemControl
 
         $order_list = $model_refill_order->getMerchantOrderList($condition, '', 'refill_order.*,vr_order.order_state', 'refill_order.notify_time asc', 1000);
         $merchant_list = Model('')->table('merchant')->limit(1000)->order('name asc')->select();
-        $order_list = $this->orderFormat($order_list,$merchant_list);
+        $order_list = $this->orderFormat($order_list, $merchant_list);
 
         $provider_list = Model('')->table('refill_provider,store')
             ->field('refill_provider.*,store.store_name')
@@ -212,7 +301,7 @@ class ordersendlistControl extends SystemControl
 
     public function notifyerr_all_notifyOp()
     {
-        if(empty($_GET['time']) || empty($_GET['notify_time'])) {
+        if (empty($_GET['time']) || empty($_GET['notify_time'])) {
             showMessage('日期条件错误');
         }
         $model_refill_order = Model('refill_order');
@@ -220,8 +309,9 @@ class ordersendlistControl extends SystemControl
         $order_state_cancel = ORDER_STATE_CANCEL;
         $order_state_success = ORDER_STATE_SUCCESS;
         $condition['refill_order.inner_status'] = 0;
-        $condition['vr_order.order_state'] = ['in',"{$order_state_cancel},{$order_state_success}"];
-        $condition['refill_order.mch_notify_state'] = 0;
+        $condition['vr_order.order_state'] = ['in', "{$order_state_cancel},{$order_state_success}"];
+        $condition['refill_order.mch_notify_state'] = ['in', "0,2"];
+        $condition['refill_order.is_retrying'] = 0;
 
         $time = $_GET['time'] * 3600;
         $condition['refill_order.order_time'] = ['gt', (time() - $time)];

+ 9 - 8
admin/control/orderstats.php

@@ -31,15 +31,16 @@ class orderstatsControl extends SystemControl
         }
 
         $stats_list = $model_refill_order->getOrderStatsList($condition, 50, '*', 'time_stamp desc, cname asc');
-
-        if ($type == 'provider') {
-            $provider_list = Model('')->table('refill_provider,store')->field('refill_provider.store_id,store.store_name')->join('inner')
-                ->on('store.store_id=refill_provider.store_id')->limit(1000)->select();
-            Tpl::output('provider_list', $provider_list);
-        } elseif ($type == 'merchant') {
-            $merchant_list = Model('')->table('merchant')->limit(1000)->select();
-            Tpl::output('merchant_list', $merchant_list);
+        if($type == 'merchant') {
+            foreach ($stats_list as $key => $stats) {
+                $time = date("Y-m-d",$stats['time_stamp']+86400);
+                $mch_cache = rcache("merchant_balance_{$time}", 'refill-');
+                $caches = empty($mch_cache['data']) ? [] : unserialize($mch_cache['data']);
+                if(empty($caches)) continue;
+                $stats_list[$key]['available'] = $caches[$stats['cid']] ?? '';
+            }
         }
+        
         $total_stats = $this->stats($stats_list);
         $order_time_type_text = ['notify_time' => '回调时间', 'order_time' => '下单时间'];
         Tpl::output('total_stats', $total_stats);

+ 1 - 1
admin/control/provider.php

@@ -1,6 +1,6 @@
 <?php
 
-require_once(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
+include(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
 class providerControl extends SystemControl
 {
     public function __construct()

+ 1 - 1
admin/control/provider_group.php

@@ -1,5 +1,5 @@
 <?php
-require_once(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
+include(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
 require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
 require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
 

+ 1 - 0
admin/control/provider_info.php

@@ -27,6 +27,7 @@ class provider_infoControl extends SystemControl
         }
         Tpl::output('provider_list', $providers);
         Tpl::output('info_list', $info_list);
+        Tpl::output('page', $mod->showpage());
         Tpl::showpage('provider.info');
     }
 

+ 47 - 7
admin/control/refill_cron.php

@@ -1,6 +1,7 @@
 <?php
 
-
+use refill\util;
+use Log;
 class refill_cronControl extends SystemControl
 {
     public function __construct()
@@ -10,18 +11,57 @@ class refill_cronControl extends SystemControl
 
     public function indexOp()
     {
-        $cron = [];
+        $condition = [];
         if(!empty($_GET['search'])) {
             $search = $_GET['search'];
-            $mod = Model('cron');
             $condition['params'] = ['like', '%'.$search.'%'];
-            $cron = $mod->getCronList($condition);
-            foreach ($cron as $key => $value) {
-                $cron[$key]['params'] = unserialize($value['params']);
-            }
+        }
+        $mod = Model('cron');
+        $cron = $mod->getCronList($condition);
+
+        $merchants = [];
+        $merchant_list = Model('')->table('merchant')->limit(1000)->select();
+        foreach ($merchant_list as  $value) {
+            $merchants[$value['mchid']] = $value;
         }
 
+        foreach ($cron as $key => $value) {
+            $params = unserialize($value['params']);
+            foreach ($params as $param) {
+                $mchid = $param['params']['mchid'];
+            }
+            $cron[$key]['params'] = $params;
+            $cron[$key]['company_name'] = $merchants[$mchid]['company_name'];
+        }
+        Tpl::output('show_page', $mod->showpage());
         Tpl::output('cron', $cron);
         Tpl::showpage('refill.cron');
     }
+
+    public function DelOp()
+    {
+        $id = $_GET['id'];
+        $mod = Model('cron');
+        $cron_info = $mod->getCronInfo(['id' => $id]);
+        if (empty($cron_info)) {
+            showMessage('队列信息不存在');
+        }
+        if($cron_info['exetime'] <= time()) {
+            showMessage('队列任务时间限制');
+        }
+        $result = $mod->delCron(['id' => $id]);
+        if (!$result) {
+            showMessage('删除失败');
+        }
+        $params = unserialize($cron_info['params']);
+        foreach ($params as $param) {
+            $mchid = $param['params']['mchid'];
+            $mch_order = $param['params']['mch_order'];
+        }
+        Log::record("del cron mchid:{$mchid},mch_order:{$mch_order}",Log::DEBUG);
+        if(!empty($mch_order) && !empty($mchid)) {
+            util::pop_queue_order($mchid,$mch_order);
+        }
+        showMessage('删除成功');
+    }
 }

+ 175 - 0
admin/control/refill_detail.php

@@ -0,0 +1,175 @@
+<?php
+require_once(BASE_HELPER_PATH . '/refill/util.php');
+
+use refill\util;
+class refill_detailControl extends SystemControl
+{
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function indexOp()
+    {
+        $mod = Model('refill_detail');
+        $condition = [];
+        $order_state_send = ORDER_STATE_SEND;
+        $order_state_queue = ORDER_STATE_QUEUE;
+        $condition['order_state'] = ['in',"{$order_state_send},{$order_state_queue}"];
+        if(!empty($_GET['mchid'])) {
+            $condition['mchid'] = $_GET['mchid'];
+        }
+        if(in_array($_GET['order_state'], [$order_state_send,$order_state_queue])) {
+            $condition['order_state'] = $_GET['order_state'];
+        }
+        if (!empty($_GET['mch_orders'])) {
+            $mch_orders = $_GET['mch_orders'];
+            $mch_orders = str_replace(["\r\n", "\r", "\n"], ",", $mch_orders);
+            $condition['mch_order'] = ['in', $mch_orders];
+        }
+
+        $start_unixtime = intval(strtotime($_GET['query_start_time']));
+        $end_unixtime = intval(strtotime($_GET['query_end_time']));
+        if ($start_unixtime > 0 && $end_unixtime > $start_unixtime) {
+            $condition['order_time'] = [['egt', $start_unixtime], ['lt', $end_unixtime], 'and'];
+        } elseif ($start_unixtime > 0) {
+            $condition['order_time'] = ['egt', $start_unixtime];
+        } elseif ($end_unixtime > 0) {
+            $condition['order_time'] = ['lt', $end_unixtime];
+        }
+
+        $merchants = [];
+        $merchant_list = Model('')->table('merchant')->limit(1000)->select();
+        foreach ($merchant_list as  $value) {
+            $merchants[$value['mchid']] = $value;
+        }
+
+        if($_GET['export'] == 1) {
+            $this->RefillDetailExport($condition,$merchants);
+            exit;
+        }else{
+            $list = $mod->getRefillDetailList($condition,30);
+            $list = $this->DataFormat($list,$merchants);
+        }
+
+        Tpl::output('merchant_list', $merchants);
+        Tpl::output('list', $list);
+        Tpl::output('show_page', $mod->showpage());
+        Tpl::showpage('refill.detail');
+    }
+
+    private function DataFormat($list,$merchants)
+    {
+        foreach ($list as $key => $value) {
+            $params = json_decode($value['params'],true);
+            $list[$key]['company_name'] = $merchants[$value['mchid']]['company_name'];
+            $list[$key]['params'] = $params;
+            if($value['order_state'] == ORDER_STATE_SEND) {
+                $list[$key]['order_state_text'] = '待收货';
+            } elseif ($value['order_state'] == ORDER_STATE_QUEUE) {
+                $list[$key]['order_state_text'] = '队列中';
+            } else {
+                $list[$key]['order_state_text'] = '/';
+            }
+        }
+        return $list;
+    }
+
+    private function RefillDetailExport($condition, $merchants)
+    {
+        $i = 0;
+        $result = [];
+        while (true) {
+            $start = $i * 1000;
+            $list = Model('')->table('refill_refund')->where($condition)->order('refund_time desc')->limit("{$start},1000")->select();
+
+            if (empty($list)) {
+                break;
+            }
+            $i++;
+            foreach ($list as $value) {
+                $result[] = $value;
+            }
+        }
+        $result = $this->DataFormat($result,$merchants);
+        $this->createExcel($result);
+    }
+
+    private function createExcel($data = array())
+    {
+        Language::read('export');
+        import('libraries.excel');
+        $excel_obj = new Excel();
+        $excel_data = array();
+        //设置样式
+        $excel_obj->setStyle(array('id' => 's_title', 'Font' => array('FontName' => '宋体', 'Size' => '12', 'Bold' => '1')));
+        //header
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '通道名称');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '通道退款金额');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '机构编码');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '机构名称');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '机构退款金额');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '退款卡号');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '退款卡类型');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '退款面值');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '退款日期');
+        $excel_data[0][] = array('styleid' => 's_title', 'data' => '备注');
+        //data
+        foreach ((array)$data as $v) {
+            $mch_name = $v['company_name'] ?? $v['name'];
+            $tmp = array();
+            $tmp[] = array('data' => "{$v['provider_name']}({$v['store_name']})");
+            $tmp[] = array('data' => $v['channel_amount']);
+            $tmp[] = array('data' => $v['mchid']);
+            $tmp[] = array('data' => $mch_name);
+            $tmp[] = array('data' => $v['mch_amount']);
+            $tmp[] = array('data' => $v['card_no']);
+            $tmp[] = array('data' => $v['card_type_text']);
+            $tmp[] = array('data' => $v['refill_amount']);
+            $tmp[] = array('data' => date('Y-m-d H:i:s', $v['refund_time']));
+            $tmp[] = array('data' => $v['bz']);
+
+            $excel_data[] = $tmp;
+        }
+        $excel_data = $excel_obj->charset($excel_data, CHARSET);
+        $excel_obj->addArray($excel_data);
+        $excel_obj->addWorksheet($excel_obj->charset(L('exp_od_order'), CHARSET));
+        $excel_obj->generateXML($excel_obj->charset(L('exp_od_order'), CHARSET) . date('Y-m-d-H', time()));
+        exit;
+    }
+
+    public function order_disposeOp()
+    {
+        $id = $_GET['id'];
+        $type = $_GET['type'];
+        $condition['detail_id'] = ['in',$id];
+        $condition['order_state'] = ORDER_STATE_QUEUE;
+
+        $refill_detail = Model('refill_detail')->where($condition)->select();
+        $mod = Model('refill_order');
+        foreach ($refill_detail as $detail) {
+            $mchid = $detail['mchid'];
+            $mch_order = $detail['mch_order'];
+            Log::record("mchid: {$mchid} , mch_order: {$mch_order}", Log::DEBUG);
+            $refill_order = $mod->getOrderInfo(['mchid' => $mchid,'mch_order' => $mch_order]);
+            if (empty($refill_order)) {
+                Log::record("order dispose type:{$type}, params:{$detail['params']}",Log::DEBUG);
+                $params = json_decode($detail['params'],true);
+                if ($type == 'cancel') {
+                    //零元订单失败
+                    Log::record("cancel",Log::DEBUG);
+                    util::push_add_zero($params);
+                } elseif ($type == 'anew') {
+                    //重新补充
+                    Log::record("anew",Log::DEBUG);
+                    util::push_add($params);
+                } else {
+                    continue;
+                }
+            } else {
+                util::pop_queue_order($mchid,$mch_order);
+            }
+        }
+        showMessage('操作成功');
+    }
+}

+ 5 - 0
admin/control/refill_evidence.php

@@ -34,6 +34,9 @@ class refill_evidenceControl extends SystemControl
         if (!empty($_GET['add_type'])) {
             $condition['add_type'] = intval($_GET['add_type']);
         }
+        if (!empty($_GET['is_bank'])) {
+            $condition['is_bank'] = intval($_GET['is_bank']);
+        }
         $export = $_GET['export'] ?? 0;
 
         $start_unixtime = intval(strtotime($_GET['query_start_time']));
@@ -100,6 +103,7 @@ class refill_evidenceControl extends SystemControl
         $status_text = ['申请中', '已通过', '已驳回'];
         $operation_text = ['未预存', '已预存'];
         $add_type_text = ['商户预存','后台手动预存','后台手动调款'];
+        $is_bank_text = ['否','是'];
 
         foreach ($data as $key => $value) {
             $data[$key]['add_time'] = date('Y-m-d H:i', $value['add_time']);
@@ -107,6 +111,7 @@ class refill_evidenceControl extends SystemControl
             $data[$key]['status_text'] = $status_text[$value['status']-1];
             $data[$key]['operation_text'] = $operation_text[$value['is_operation']-1];
             $data[$key]['add_type_text'] = $add_type_text[$value['add_type']-1];
+            $data[$key]['is_bank_text'] = $is_bank_text[$value['is_bank']];
         }
 
         return $data;

+ 18 - 9
admin/control/refill_order.php

@@ -94,8 +94,10 @@ class refill_orderControl extends SystemControl
             $fToday = true;
         }
 
-        if (in_array($_GET['order_state'], ['0', '10', '20', '30', '40'])) {
+        if (in_array($_GET['order_state'], ['0', '10', '20', '30', '40']))
+        {
             $condition['vr_order.order_state'] = $_GET['order_state'];
+
             if ($_GET['order_state'] == ORDER_STATE_SEND) {
                 if ($_GET['time'] == 1) {
                     $condition['refill_order.order_time'] = ['between', [(time() - 3600), (time() - 1800)]];
@@ -276,7 +278,7 @@ class refill_orderControl extends SystemControl
             ->field('refill_provider.*,store.store_name')
             ->join('inner')
             ->on('store.store_id=refill_provider.store_id')
-            ->order('opened asc, name asc')
+            ->order('name asc')
             ->limit(1000)
             ->select();
         foreach ($provider_list as $value) {
@@ -312,20 +314,20 @@ class refill_orderControl extends SystemControl
     {
         $order_sn = $_GET['order_sn'] ?? '';
         $model_refill_order = Model('refill_order');
-        $order_info = $model_refill_order->getOrderInfo(['order_sn' => $order_sn]);
-        if (empty($order_info)) {
+        $refill_info = $model_refill_order->getOrderInfo(['order_sn' => $order_sn]);
+        if (empty($refill_info)) {
             $res = ['state' => -1, 'msg' => '订单不存在'];
             exit(json_encode($res));
         }
-        $mch_order = $order_info['mch_order'];
-        $order_time = $order_info['order_time'];
-        $mchid = $order_info['mchid'];
+        $mch_order = $refill_info['mch_order'];
+        $order_time = $refill_info['order_time'];
+        $mchid = $refill_info['mchid'];
 
         $condition['refill_order.mch_order'] = $mch_order;
         $condition['refill_order.order_time'] = ['egt', $order_time];
         $condition['refill_order.mchid'] = $mchid;
 
-        $field = 'refill_order.order_sn,refill_order.commit_time,refill_order.notify_time,refill_order.channel_name,vr_order.order_state';
+        $field = 'refill_order.order_sn,refill_order.commit_time,refill_order.notify_time,refill_order.channel_name,vr_order.order_state,refill_order.err_msg';
         $order_list = $model_refill_order->getMerchantOrderList($condition, 1000, $field);
 
         foreach ($order_list as $order_id => $order_info) {
@@ -343,6 +345,7 @@ class refill_orderControl extends SystemControl
                 } else {
                     $diff_time = time() - $order_info['commit_time'];
                     if($order_info['order_state'] != ORDER_STATE_SEND) {
+                        $diff_time = 0;
                         $order_list[$order_id]['order_state_text'] = '提交失败';
                     }
                 }
@@ -354,7 +357,13 @@ class refill_orderControl extends SystemControl
             }
             $order_list[$order_id]['diff_time'] = $diff_time;
         }
-        $res = ['state' => 1, 'data' => $order_list, 'count' => count($order_list)];
+        $mch_notify_state = ['未确认','已确认','回调失败'];
+        $res = ['state' => 1,
+            'data' => $order_list,
+            'count' => count($order_list),
+            'mch_notify_times' => $refill_info['mch_notify_times'],
+            'mch_notify_state' => $mch_notify_state[$refill_info['mch_notify_state']]
+        ];
         exit(json_encode($res));
     }
 }

+ 9 - 4
admin/control/refill_order_manual.php

@@ -50,14 +50,14 @@ class refill_order_manualControl extends SystemControl
         $mod_order = Model('vr_order');
         $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
 
-        if ((time() - $order_info['order_time']) < 3600) {
-            showMessage('订单时间未超过1小时', 'index.php?act=refill_order&op=index');
-        }
-
         $mod_refill = Model('refill_order');
         $logic_vr_order = Logic("vr_order");
         $refill_info = Model('refill_order')->getOrderInfo(['order_id' => $order_id]);
 
+        $check_fetch_order = $this->check_fetch_order($order_info['order_sn']);
+        if($check_fetch_order == false) {
+            showMessage('此订单不可手动操作,请联系抢单人员操作!');
+        }
         if ($type == 'success') {
             $logic_vr_order->changeOrderStateSuccess($order_id,true);
         } elseif ($type == 'cancel') {
@@ -65,6 +65,7 @@ class refill_order_manualControl extends SystemControl
         } else {
             showMessage('手动操作类型错误', 'index.php?act=refill_order&op=index');
         }
+
         if($refill_info['notify_time'] == 0) {
             $mod_refill->edit($order_id, ['notify_state' =>1, 'notify_time' => time()]);
         }
@@ -90,10 +91,14 @@ class refill_order_manualControl extends SystemControl
             $order_list = $model_refill_order->getMerchantOrderList($condition,'','refill_order.*,vr_order.order_state');
             if($type == 'success') {
                 foreach ($order_list as $order) {
+                    $check_fetch_order = $this->check_fetch_order($order['order_sn']);
+                    if($check_fetch_order == false) continue;
                     refill\util::manual_success($order['order_id']);
                 }
             } elseif ($type == 'cancel') {
                 foreach ($order_list as $order) {
+                    $check_fetch_order = $this->check_fetch_order($order['order_sn']);
+                    if($check_fetch_order == false) continue;
                     refill\util::manual_cancel($order['order_id']);
                 }
             } elseif ($type == 'notify'){

+ 1 - 1
admin/control/refill_stock.php

@@ -1,7 +1,7 @@
 <?php
 
 require_once(BASE_HELPER_PATH . '/refill/policy/rlock.php');
-require_once(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
+include(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
 require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
 
 class refill_stockControl extends SystemControl

+ 4 - 4
admin/control/refill_successful.php

@@ -1,5 +1,5 @@
 <?php
-require_once(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
+include(BASE_CONFIG_PATH . CONFIG_PREFIX . '/refill.ini.php');
 require_once(BASE_ROOT_PATH . '/core/framework/function/http.php');
 require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
 class refill_successfulControl extends SystemControl
@@ -74,13 +74,13 @@ class refill_successfulControl extends SystemControl
         $result['chname'] = $chnameData;
         if ($type == 'system') {
             $merchants = [];
-            $merchant_list = Model('')->table('merchant')->limit(1000)->field('mchid,name,company_name')->select();
-            foreach ($merchant_list as $key => $value) {
+            $merchant_list = Model('')->table('merchant')->limit(1000)->field('mchid,name,company_name,time_out')->select();
+            foreach ($merchant_list as $value) {
                 $merchants[$value['mchid']] = $value;
             }
             foreach ($chnameData as $mchid) {
                 $merchant_name = $merchants[$mchid]['company_name'] == '' ? $merchants[$mchid]['name'] : $merchants[$mchid]['company_name'];
-                $mchname[$mchid] = "{$mchid}-{$merchant_name}";
+                $mchname[$mchid] = "{$mchid}-{$merchant_name}-{$merchants[$mchid]['time_out']}";
             }
             asort($mchname);
             $result['chname'] = $mchname;

+ 2 - 1
admin/control/store.php

@@ -296,7 +296,8 @@ class storeControl extends SystemControl{
     /**
      * 添加经营类目
      */
-    public function store_bind_class_addOp() {
+    public function store_bind_class_addOp()
+    {
         $store_id = intval($_POST['store_id']);
         $commis_rate = intval($_POST['commis_rate']);
         if($commis_rate < 0 || $commis_rate > 100) {

+ 1 - 0
admin/include/limit.php

@@ -47,6 +47,7 @@ $_limit =  array(
         array('name'=> '充值系统设置', 'op'=>null, 'act'=>'refill_config'),
         array('name'=> '退款信息管理', 'op'=>null, 'act'=>'refill_refund'),
         array('name'=> '客服订单查询', 'op'=>null, 'act'=>'order_search'),
+        array('name'=> '接单查询', 'op'=>null, 'act'=>'refill_detail'),
     )),
 	array('name'=>$lang['nc_store'], 'child'=>array(
 		array('name'=>$lang['nc_store_manage'], 'op'=>null, 'act'=>'store'),

+ 1 - 0
admin/include/menu.php

@@ -110,6 +110,7 @@ $arr = array(
 					array('args'=>'index,refill_config,merchant',			'text'=>'充值系统设置'),
 					array('args'=>'index,refill_refund,merchant',			'text'=>'退款信息管理'),
 					array('args'=>'index,order_search,merchant',			'text'=>'客服订单查询'),
+					array('args'=>'index,refill_detail,merchant',			'text'=>'接单查询'),
 				)
 			),
 			4 => array(

+ 10 - 3
admin/templates/default/merchant.edit.php

@@ -65,8 +65,13 @@
                 <td class="vatop">
                     <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 1){ echo 'checked';}?> value="1" type="radio">无流水
                     <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 5){ echo 'checked';}?> value="5" type="radio">有流水
-                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 20){ echo 'checked';}?> value="20" type="radio">无流水 + 有流水
-                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 21){ echo 'checked';}?> value="21" type="radio">有流水 + 无流水
+                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 3){ echo 'checked';}?> value="3" type="radio">卡密
+                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 20){ echo 'checked';}?> value="20" type="radio">无流水+有流水
+                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 21){ echo 'checked';}?> value="21" type="radio">有流水+无流水
+                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 22){ echo 'checked';}?> value="22" type="radio">有流水+卡密
+                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 23){ echo 'checked';}?> value="23" type="radio">无流水+卡密
+                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 24){ echo 'checked';}?> value="24" type="radio">有流水+无流水+卡密
+                    <input name="oil_quality" <?php if($output['merchant']['oil_quality'] == 25){ echo 'checked';}?> value="25" type="radio">无流水+有流水+卡密
                 </td>
             </tr>
             <tr>
@@ -81,9 +86,11 @@
                     <input name="quality" <?php if($output['merchant']['quality'] == 5){ echo 'checked';}?> value="5" type="radio">慢24
                     <input name="quality" <?php if($output['merchant']['quality'] == 6){ echo 'checked';}?> value="6" type="radio">慢6
                     <input name="quality" <?php if($output['merchant']['quality'] == 7){ echo 'checked';}?> value="7" type="radio">慢2
+                    <input name="quality" <?php if($output['merchant']['quality'] == 8){ echo 'checked';}?> value="8" type="radio">慢48
+                    <input name="quality" <?php if($output['merchant']['quality'] == 9){ echo 'checked';}?> value="9" type="radio">慢72
                     <input name="quality" <?php if($output['merchant']['quality'] == 11){ echo 'checked';}?> value="11" type="radio">慢充一次+普充
                     <input name="quality" <?php if($output['merchant']['quality'] == 12){ echo 'checked';}?> value="12" type="radio">三方一次+普充
-                    <input name="quality" <?php if($output['merchant']['quality'] == 13){ echo 'checked';}?> value="13" type="radio">三方一次+普充+卡密+快充
+                    <input name="quality" <?php if($output['merchant']['quality'] == 13){ echo 'checked';}?> value="13" type="radio">普充+卡密+快充
                     <input name="quality" <?php if($output['merchant']['quality'] == 14){ echo 'checked';}?> value="14" type="radio">普充+快充
                     <input name="quality" <?php if($output['merchant']['quality'] == 15){ echo 'checked';}?> value="15" type="radio">慢充6+普充
                 </td>

+ 3 - 1
admin/templates/default/merchant.index.php

@@ -20,7 +20,7 @@ defined('InShopNC') or exit('Access Invalid!'); ?>
             <tbody>
             <tr>
                 <th><label for="merchant_name"><?php echo $lang['merchant_name']; ?></label></th>
-                <td><input type="text" value="<?php echo $output['merchant_name']; ?>" name="merchant_name"
+                <td><input type="text" value="<?php echo $_GET['merchant_name']; ?>" name="merchant_name"
                            id="merchant_name" class="txt"></td>
                 <td><a href="javascript:void(0);" id="ncsubmit" class="btn-search "
                        title="<?php echo $lang['nc_query']; ?>">&nbsp;</a>
@@ -54,6 +54,7 @@ defined('InShopNC') or exit('Access Invalid!'); ?>
             <tr class="thead">
                 <th><?php echo $lang['merchant_name']; ?>编号</th>
                 <th>机构账号</th>
+                <th>会员ID</th>
                 <th>机构公司名称</th>
                 <th>所剩余额</th>
                 <th>授信额度</th>
@@ -74,6 +75,7 @@ defined('InShopNC') or exit('Access Invalid!'); ?>
                     <tr class="trFlex">
                         <td><?php echo $v['mchid']; ?></td>
                         <td><?php echo $v['name']; ?></td>
+                        <td><?php echo $v['admin_id']; ?></td>
                         <td><?php echo $v['company_name']; ?></td>
                         <td>
                             <?php if($v['available_predeposit'] > 0){?>

+ 5 - 2
admin/templates/default/merchant.order.stats.php

@@ -132,9 +132,10 @@
 <!--                <th class="align-center">订单总量</th>-->
 <!--                <th class="align-center">失败订单数量</th>-->
 <!--                <th class="align-center">成功占比</th>-->
+                <th class="align-center">当日结余</th>
                 <th class="align-center">下游成功单量</th>
-                <th class="align-center">下游成功扣款金额</th>
                 <th class="align-center">下游成功面值</th>
+                <th class="align-center">下游成功扣款金额</th>
                 <th class="align-center">单量误差</th>
                 <th class="align-center">扣款金额误差</th>
                 <th class="align-center">面值误差</th>
@@ -155,14 +156,15 @@
                         <td class="align-center"><?php echo $v['success_count']; ?></td>
                         <td class="align-center"><?php echo $v['success_refill_amounts']; ?></td>
                         <td class="align-center"><?php echo $v['success_mch_amounts']; ?></td>
+                        <td class="align-center"><?php echo $v['available']; ?></td>
 <!--                        <td class="align-center">--><?php //echo $v['success_channel_amounts']; ?><!--</td>-->
 <!--                        <td class="align-center">--><?php //echo $v['profit_amounts']; ?><!--</td>-->
 <!--                        <td class="align-center">--><?php //echo $v['order_count']; ?><!--</td>-->
 <!--                        <td class="align-center">--><?php //echo $v['cancel_count']; ?><!--</td>-->
 <!--                        <td class="align-center">--><?php //echo $v['success_ratio']; ?><!--</td>-->
                         <td class="align-center"><?php echo $v['corder_success_count']; ?></td>
-                        <td class="align-center"><?php echo $v['corder_success_amounts']; ?></td>
                         <td class="align-center"><?php echo $v['corder_success_refill_amounts']; ?></td>
+                        <td class="align-center"><?php echo $v['corder_success_amounts']; ?></td>
                         <td class="align-center">
                             <?php if($v['gap_order_count'] != 0){?>
                             <span style="color: #f30707">
@@ -402,6 +404,7 @@
             selest_nc = xmSelect.render({
                     el: '#selest_nc',
                     size: 'mini',
+                    filterable: true,
                     style: {
                         minHeight: '27px',
                         lineHeight: '27px',

+ 6 - 0
admin/templates/default/merchant.price.php

@@ -88,6 +88,12 @@
                 <li><a href="index.php?act=merchant&op=price&quality=5&mchid=<?php echo $_GET['mchid'] ?>" class="classA" data-quality="5"><span>慢24(有流水)费率设置</span></a></li>
                 <li><a href="index.php?act=merchant&op=price&quality=6&mchid=<?php echo $_GET['mchid'] ?>" class="classA" data-quality="6"><span>慢6费率设置</span></a></li>
                 <li><a href="index.php?act=merchant&op=price&quality=7&mchid=<?php echo $_GET['mchid'] ?>" class="classA" data-quality="7"><span>慢2费率设置</span></a></li>
+                <li><a href="index.php?act=merchant&op=price&quality=8&mchid=<?php echo $_GET['mchid'] ?>" class="classA" data-quality="8"><span>慢48费率设置</span></a></li>
+                <li><a href="index.php?act=merchant&op=price&quality=9&mchid=<?php echo $_GET['mchid'] ?>" class="classA" data-quality="9"><span>慢72费率设置</span></a></li>
+
+                <li><a href="index.php?act=merchant&op=price&quality=13&mchid=<?php echo $_GET['mchid'] ?>" class="classA" data-quality="13"><span>普通+卡密+快充</span></a></li>
+                <li><a href="index.php?act=merchant&op=price&quality=14&mchid=<?php echo $_GET['mchid'] ?>" class="classA" data-quality="14"><span>普通+快充</span></a></li>
+
                 <li><a href="index.php?act=merchant&op=third_merchant_price&mchid=<?php echo $_GET['mchid'] ?>"><span>三方业务通道费率设置</span></a></li>
             </ul>
         </div>

+ 12 - 3
admin/templates/default/merchant.refill.evidence_list.php

@@ -38,9 +38,16 @@
                 <td>
                     <select name="add_type">
                         <option value="">请选择...</option>
-                        <option value="1" <?php if($_GET['state_sel'] == '1'){ echo 'selected';}?>>商户预存</option>
-                        <option value="2" <?php if($_GET['state_sel'] == '2'){ echo 'selected';}?>>后台手动预存</option>
-                        <option value="3" <?php if($_GET['state_sel'] == '3'){ echo 'selected';}?>>后台手动调款</option>
+                        <option value="1" <?php if($_GET['add_type'] == '1'){ echo 'selected';}?>>商户预存</option>
+                        <option value="2" <?php if($_GET['add_type'] == '2'){ echo 'selected';}?>>后台手动预存</option>
+                        <option value="3" <?php if($_GET['add_type'] == '3'){ echo 'selected';}?>>后台手动调款</option>
+                    </select>
+                </td>
+                <th><label for="is_bank">转款类型</label></th>
+                <td>
+                    <select name="is_bank">
+                        <option value="">请选择...</option>
+                        <option value="1" <?php if($_GET['is_bank'] == '1'){ echo 'selected';}?>>银行转账</option>
                     </select>
                 </td>
                 <th><label for="query_start_time">下单时间</label></th>
@@ -100,6 +107,7 @@
                 <th>申请后可用金额</th>
                 <th class="align-center">转账银行开户人姓名</th>
                 <th class="align-center">转账银行名称</th>
+                <th class="align-center">是否银行转账</th>
                 <th class="align-center">申请状态</th>
                 <th class="align-center">预存状态</th>
                 <th class="align-center">申请日期</th>
@@ -126,6 +134,7 @@
                         </td>
                         <td class="align-left"><?php echo $v['bank_username']; ?></td>
                         <td class="align-left"><?php echo $v['bank_name']; ?></td>
+                        <td class="align-center"><?php echo $v['is_bank_text']; ?></td>
                         <td class="align-center">
                             <?php if ($v['status'] == 1){ ?>
                                 <span style="color: #0A8CD2">

+ 49 - 1
admin/templates/default/provider.amount.control.php

@@ -72,6 +72,9 @@
     .text.price {
         width: 40px;
     }
+    .text.pricee {
+        width: 40px;
+    }
 </style>
 <?php defined('InShopNC') or exit('Access Invalid!'); ?>
 <div class="page provider_amount_control">
@@ -87,9 +90,12 @@
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow" class="classA" data-type="2-slow"><span>慢24话费单量控制</span></a></li>
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow6" class="classA" data-type="2-slow6"><span>慢6话费单量控制</span></a></li>
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow2" class="classA" data-type="2-slow2"><span>慢2话费单量控制</span></a></li>
+                <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow48" class="classA" data-type="2-slow48"><span>慢48话费单量控制</span></a></li>
+                <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow72" class="classA" data-type="2-slow72"><span>慢72话费单量控制</span></a></li>
 
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=1&form=common" class="classA" data-type="1-common"><span>无流水油卡单量控制</span></a></li>
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=1&form=slow" class="classA" data-type="1-slow"><span>有流水油卡单量控制</span></a></li>
+                <li><a href="index.php?act=merchant&op=provider_amount_control&type=1&form=card" class="classA" data-type="1-card"><span>卡密油卡单量控制</span></a></li>
             </ul>
         </div>
     </div>
@@ -103,7 +109,7 @@
             </tr>
             <tr>
                 <td class="tip_info">
-                    单量:请输入大于-1的数字,-1表示不限;&nbsp;&nbsp;&nbsp;&nbsp;
+                    单量:请输入大于等于-1的数字,-1表示不限;&nbsp;&nbsp;&nbsp;&nbsp;
                     优先级:请输入1-100的数字;&nbsp;&nbsp;&nbsp;&nbsp;是否启动:1-开启,0-关闭
                 </td>
             </tr>
@@ -126,6 +132,15 @@
                             <td class="batch-td">
                                 <div class="listNum">
                                     单量
+                                    <div class="batch" style="display: inline-block"><i class="icon-edit" title="批量操作"></i>
+                                        <div class="batch-input" style="display:none">
+                                            <h6>批量设置单量(大于等于-1):</h6>
+                                            <a href="javascript:void(0)" class="close">X</a>
+                                            <input name="" type="number" class="text pricee"/>
+                                            <a href="javascript:void(0)" class="ncsc-btn-minii" data-type="pricee">设置</a><span
+                                                    class="arrow"></span>
+                                        </div>
+                                    </div>
                                 </div>
                                 <div class="priority">
                                     优先级
@@ -359,6 +374,39 @@
                    $(this).val(price)
                }
             })
+            
+        })
+
+                // 单量设置开关
+            $('.batch > .icon-edit').click(function () {
+            $('.batch > .batch-input').hide();
+            $(this).next().show();
+        });
+        $('.batch-input > .close').click(function () {
+            $(this).parent().hide();
+        });
+        $('.pricee').change(function () {
+            let val = $(this).val()
+            if (val <= -2) {
+                layer.msg('单量只能设置大于-1');
+            }
+        })
+        // 点击设置
+        $('.ncsc-btn-minii').click(function () {
+            let price = $(this).siblings('.pricee').val()
+            if (price <= -2) {
+                layer.msg('单量只能设置大于-1');
+                return
+            }
+            var lie = $(this).parents('.batch-td').prevAll().length
+            $('.input-one').each(function () {
+               let tdCon = $(this).parents('td').prevAll().length / 6
+               let readOnly = $(this).attr('readOnly')
+               if (lie == tdCon && !readOnly) {
+                   $(this).val(price)
+               }
+            })
+            
         })
     });
 </script>

+ 26 - 2
admin/templates/default/provider.group.php

@@ -88,13 +88,29 @@
                             <?php }?>
                             慢2话费通道
                         </p>
+                        <p data-quality="8" data-type="2">
+                            <?php if(in_array('8-2',$output['check'])){?>
+                                <i class="layui-icon layui-icon-rate-solid"></i>
+                            <?php }else{?>
+                                <i class="layui-icon layui-icon-rate"></i>
+                            <?php }?>
+                            慢48话费通道
+                        </p>
+                        <p data-quality="9" data-type="2">
+                            <?php if(in_array('9-2',$output['check'])){?>
+                                <i class="layui-icon layui-icon-rate-solid"></i>
+                            <?php }else{?>
+                                <i class="layui-icon layui-icon-rate"></i>
+                            <?php }?>
+                            慢72话费通道
+                        </p>
                         <p data-quality="1" data-type="1">
                         <?php if(in_array('1-1',$output['check'])){?>
                                 <i class="layui-icon layui-icon-rate-solid"></i>
                             <?php }else{?>
                                 <i class="layui-icon layui-icon-rate"></i>
                             <?php }?>
-                            普通油卡通道
+                            无流水油卡通道
                         </p>
                         <p data-quality="5" data-type="1">
                         <?php if(in_array('5-1',$output['check'])){?>
@@ -102,7 +118,15 @@
                             <?php }else{?>
                                 <i class="layui-icon layui-icon-rate"></i>
                             <?php }?>
-                            慢充油卡通道
+                            有流水油卡通道
+                        </p>
+                        <p data-quality="3" data-type="1">
+                            <?php if(in_array('3-1',$output['check'])){?>
+                                <i class="layui-icon layui-icon-rate-solid"></i>
+                            <?php }else{?>
+                                <i class="layui-icon layui-icon-rate"></i>
+                            <?php }?>
+                            卡密油卡通道
                         </p>
                     </div>
                     <div class="inblock" style="flex:1">

+ 18 - 2
admin/templates/default/provider.index.php

@@ -14,9 +14,12 @@
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow"><span>慢24话费单量控制</span></a></li>
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow6"><span>慢6话费单量控制</span></a></li>
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow2"><span>慢2话费单量控制</span></a></li>
+                <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow48"><span>慢48话费单量控制</span></a></li>
+                <li><a href="index.php?act=merchant&op=provider_amount_control&type=2&form=slow72"><span>慢72话费单量控制</span></a></li>
 
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=1&form=common"><span>无流水油卡单量控制</span></a></li>
                 <li><a href="index.php?act=merchant&op=provider_amount_control&type=1&form=slow"><span>有流水油卡单量控制</span></a></li>
+                <li><a href="index.php?act=merchant&op=provider_amount_control&type=1&form=card"><span>卡密油卡单量控制</span></a></li>
             </ul>
         </div>
     </div>
@@ -115,8 +118,8 @@
                                 <?php }?>
                             </div>
                             <div>
-                                <a href="index.php?act=merchant&op=provider_edit&id=<?php echo $v['provider_id'] ?>">编辑通道</a>
-                                | <a href="index.php?act=merchant&op=provider_del&id=<?php echo $v['provider_id'] ?>">删除通道</a>
+                                <a  href="index.php?act=merchant&op=provider_edit&id=<?php echo $v['provider_id'] ?>">编辑通道</a>
+                                | <a class="deleid" href="#" data_id="<?php echo $v['provider_id'] ?>">删除通道</a>
                             </div>
                         </td>
                     </tr>
@@ -139,6 +142,8 @@
     </form>
 </div>
 <script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/js/jquery.edit.js" charset="utf-8"></script>
+<script type="text/javascript" src="<?php echo ADMIN_TEMPLATES_URL;?>/layui/layui.js"></script>
+<link rel="stylesheet" type="text/css" href="<?php echo ADMIN_TEMPLATES_URL; ?>/layui/css/layui.css"/>
 <script>
     $(function () {
         $('#ncsubmit').click(function () {
@@ -153,5 +158,16 @@
                 $(this)[0].style.backgroundColor = '#fff'
             })
         })
+        $('.deleid').click(function()  {
+            let de_id = $(this).attr('data_id')
+            layer.confirm('确定要删除通道 ?', {
+                btn: ['确定', '取消']
+            }, function() {
+                window.location.href = `index.php?act=merchant&op=provider_del&id= ${de_id}`
+            }, function() {
+
+            })
+        })
+
     });
 </script>

+ 5 - 2
admin/templates/default/provider.order.stats.php

@@ -123,8 +123,8 @@
 <!--                <th class="align-center">失败订单数量</th>-->
 <!--                <th class="align-center">成功占比</th>-->
                 <th class="align-center">上游成功单量</th>
-                <th class="align-center">上游成功扣款金额</th>
                 <th class="align-center">上游成功面值</th>
+                <th class="align-center">上游成功扣款金额</th>
                 <th class="align-center">单量误差</th>
                 <th class="align-center">扣款金额误差</th>
                 <th class="align-center">面值误差</th>
@@ -151,8 +151,8 @@
 <!--                        <td class="align-center">--><?php //echo $v['cancel_count']; ?><!--</td>-->
 <!--                        <td class="align-center">--><?php //echo $v['success_ratio']; ?><!--</td>-->
                         <td class="align-center"><?php echo $v['corder_success_count']; ?></td>
-                        <td class="align-center"><?php echo $v['corder_success_amounts']; ?></td>
                         <td class="align-center"><?php echo $v['corder_success_refill_amounts']; ?></td>
+                        <td class="align-center"><?php echo $v['corder_success_amounts']; ?></td>
                         <td class="align-center">
                             <?php if($v['gap_order_count'] != 0){?>
                             <span style="color: #f30707">
@@ -380,6 +380,7 @@
         //多选
         let selest_nc
         let default_no_mch = $('input[name="default_no_mch"]').val().split(',');
+        console.log('name', default_no_mch);
         
         $.get('index.php?act=refill_order&op=provider_data',function(data) {
             data = JSON.parse(data)
@@ -387,6 +388,7 @@
             if (default_no_mch) {
                 for (let index = 0; index < default_no_mch.length; index++) {
                     for (let j = 0; j < data.length; j++) {
+
                         if (default_no_mch[index] == data[j].value) {
                             data[j].selected = true
                             
@@ -397,6 +399,7 @@
             selest_nc = xmSelect.render({
                     el: '#selest_nc',
                     size: 'mini',
+                    filterable: true,
                     style: {
                         minHeight: '27px',
                         lineHeight: '27px',

+ 9 - 3
admin/templates/default/refill.cron.php

@@ -62,9 +62,11 @@
             <th class="align-center">队列名称</th>
             <th class="align-center">执行方法</th>
             <th class="align-center">机构编码</th>
+            <th class="align-center">机构名称</th>
             <th class="align-center">商家单号</th>
             <th class="align-center">充值卡号</th>
             <th class="align-center">面值</th>
+            <th class="align-center">操作</th>
         </thead>
         <tbody id="tbody">
         <?php if (count($output['cron']) > 0) { ?>
@@ -74,23 +76,27 @@
                     <td class="align-center"><?php echo date('Y-m-d H:i:s', $cron['exetime']); ?></td>
                     <td class="align-center"><?php echo array_key_first($cron['params']); ?></td>
                     <?php foreach ($cron['params'] as $param){ ?>
-                        <td class="align-center"><?php echo $param['method']; ?></td>
+                        <td class="align-center"><?php echo $param['method'];?></td>
                         <td class="align-center"><?php echo $param['params']['mchid']; ?></td>
+                        <td class="align-center"><?php echo $cron['company_name']; ?></td>
                         <td class="align-center"><?php echo $param['params']['mch_order']; ?></td>
                         <td class="align-center"><?php echo $param['params']['card_no']; ?></td>
                         <td class="align-center"><?php echo $param['params']['amount']; ?></td>
                     <?php }?>
+                    <td class="align-center">
+                        <a href="index.php?act=refill_cron&op=del&id=<?php echo $cron['id'] ?>">删除</a>
+                    </td>
                 </tr>
             <?php } ?>
         <?php } else { ?>
             <tr class="no_data">
-                <td colspan="7"><?php echo $lang['nc_no_record']; ?></td>
+                <td colspan="8"><?php echo $lang['nc_no_record']; ?></td>
             </tr>
         <?php } ?>
         </tbody>
         <tfoot>
         <tr class="tfoot">
-            <td colspan="7" id="dataFuncs">
+            <td colspan="8" id="dataFuncs">
                 <div class="pagination"> <?php echo $output['show_page']; ?> </div>
             </td>
         </tr>

+ 364 - 0
admin/templates/default/refill.detail.php

@@ -0,0 +1,364 @@
+<style>
+    th label {
+        display: inline-block;
+        width: 60px;
+    }
+
+    .lineLi {
+        display: inline-block;
+        min-width: 150px;
+        font-size: 14px;
+    }
+    .page .fixed-bar .item-title h3 {
+        margin-top:18px !important;
+        margin-bottom:10px !important;
+        font-weight:700 !important;
+    }
+    .tab-base li span {
+        font-size:12px !important;
+    }
+    .layui-form-select .layui-input {
+        height:23px;
+        padding-left: 11px;
+        padding-right: 0!important;
+    }
+    input::placeholder{ 
+        color:#333; 
+    }
+    .layui-form-selected dl {
+    display: flex!important;
+    flex-wrap: wrap!important;
+    }
+    .layui-form-select dl {
+      
+        top: 29px !important;
+        left: 4px!important;
+        min-width: 802%!important;
+        max-height: 280px!important;
+        padding: 14px 0!important;
+    }
+    .layui-form-select dl dd.layui-this{
+        display: none;
+    }
+    .layui-form-select dl dd {
+    cursor: pointer;
+    width: 130px;
+    }
+    .lefto {
+        margin-left: 6px;
+    }
+    .db-right {
+        padding-right: 134px!important;
+    border-bottom: 1px solid #ccc;
+
+    }
+    .db-center {
+        padding: 9px 0;
+    border-bottom: 1px solid #ccc;
+    }
+    .db-top {
+        padding: 0 30px;
+    }
+    #selectAll {
+        cursor: pointer;
+    }
+</style>
+
+<?php defined('InShopNC') or exit('Access Invalid!'); ?>
+<div class="page">
+    <div class="fixed-bar">
+        <div class="item-title">
+            <h3>接单查询</h3>
+            <ul class="tab-base">
+                <li><a href="JavaScript:void(0);" class="current"><span>接单记录列表</span></a></li>
+            </ul>
+        </div>
+    </div>
+    <div class="fixed-empty"></div>
+    <form method="get" action="index.php" name="formSearch" id="formSearch">
+        <input type="hidden" name="act" value="refill_detail"/>
+        <input type="hidden" name="op" value="index"/>
+        <table class="tb-type1 noborder search">
+            <tr>
+                <th><label>客户名称</label></th>
+                <td class="layui-form">
+                    <select name="mchid" class="querySelect" lay-verify="">
+                        <option value=""><?php echo $lang['nc_please_choose']; ?></option>
+                        <?php foreach ($output['merchant_list'] as $merchant) { ?>
+                            <option value="<?php echo $merchant['mchid'] ?>"
+                                    <?php if ($_GET['mchid'] == $merchant['mchid']){ ?>selected<?php } ?>><?php echo $merchant['company_name'] == '' ? $merchant['name'] : $merchant['company_name']; ?>
+                            </option>
+                        <?php } ?>
+                    </select>
+                </td>
+
+                <th><label for="query_start_time">下单时间</label></th>
+                <td>
+                    <input class="txt date" type="text" value="<?php echo $_GET['query_start_time']; ?>"
+                           id="startTime" name="query_start_time" autocomplete="off" style="width:120px" />
+                    <label for="query_start_time">~</label>
+                    <input class="txt date" type="text" value="<?php echo $_GET['query_end_time']; ?>"
+                           id="endTime" name="query_end_time" autocomplete="off" style="width:120px" />
+                </td>
+
+                <th><label>商家单号(多行查询)</label></th>
+                <td><textarea name="mch_orders" id="mch_orders" cols="30" rows="10"><?php echo $_GET['mch_orders'];?></textarea></td>
+
+                <th><label>订单状态</label></th>
+                <td>
+
+                    <select name="order_state" class="querySelect">
+                        <option value=""><?php echo $lang['nc_please_choose']; ?></option>
+                        <option value="<?php echo ORDER_STATE_SEND;?>"
+                                <?php if ($_GET['order_state'] == ORDER_STATE_SEND){ ?>selected<?php } ?>>待收货
+                        </option>
+                        <option value="<?php echo ORDER_STATE_QUEUE;?>"
+                                <?php if ($_GET['order_state'] == ORDER_STATE_QUEUE){ ?>selected<?php } ?>>队列中
+                        </option>
+                    </select>
+                </td>
+                <td>
+                    <a href="javascript:void(0);" id="ncsubmit" class="btn-search "
+                       title="<?php echo $lang['nc_query']; ?>">&nbsp;
+                    </a>
+                </td>
+            </tr>
+        </table>
+        <table class="tb-type1 noborder search">
+            <tr>
+                <td>
+                    <a href="#" class="btns" onclick="hCopyCardNo(event)">
+                        <span><i class="icon-edit"></i>拷贝充值卡号</span>
+                    </a>
+                    <a href="#" class="btns" onclick="hCopyOrder(event)">
+                        <span><i class="icon-edit"></i>拷贝客户单号</span>
+                    </a>
+                    <a href="#" class="btns"  id="hFail">
+                        <span><i class="icon-edit"></i>批量失败</span>
+                    </a>
+                    <a href="#" class="btns" id="hSupplement">
+                        <span><i class="icon-edit"></i>批量补充</span>
+                    </a>
+                </td>
+            </tr>
+        </table>
+    </form>
+    <table class="table tb-type2 nobdb">
+        <thead>
+        <tr class="thead">
+            <th class="align-center" id="selectAll">全选</th>
+            <th class="align-center">机构编号</th>
+            <th class="align-center">机构名称</th>
+            <th class="align-center">商家单号</th>
+            <th class="align-center">充值卡号</th>
+            <th class="align-center">充值额度</th>
+            <th class="align-right">下单日期</th>
+            <th class="align-center">订单状态</th>
+            <th class="align-center"><?php echo $lang['nc_handle']; ?></th>            
+        </tr>
+        </thead>
+        <tbody id="tbody">
+        <?php if (count($output['list']) > 0) { ?>
+            <?php
+            foreach ($output['list'] as $key => $order) { ?>
+                <tr class="hover trFlex">
+                    <td class="align-center">
+                    <input type="checkbox" id="checkBoxList" name="checkbox" value="<?php echo $order['detail_id'];?>">
+                    </td>
+                    <td class="align-center"><?php echo $order['mchid']; ?></td>
+                    <td class="align-center"><?php echo $order['company_name'];?></td>
+                    <td class="align-center"><?php echo $order['mch_order']; ?></td>
+                    <td class="align-center"><?php echo $order['params']['card_no']; ?></td>
+                    <td class="align-center"><?php echo $order['params']['amount']; ?></td>
+                    <td class="align-right"><?php echo date('Y-m-d H:i:s', $order['order_time']) ?? '/'; ?></td>
+                    <td class="align-center"><?php echo $order['order_state_text']; ?></td>
+                    <td class="align-center">
+                        <!-- <a href="#">
+                                回调</a>
+                        | -->
+                        <a href="index.php?act=refill_detail&op=order_dispose&type=cancel&id=<?php echo $order['detail_id']; ?>" id="hdFail">
+                        回调失败</a>
+                        |
+                        <a href="index.php?act=refill_detail&op=order_dispose&type=anew&id=<?php echo $order['detail_id']; ?>">
+                        重新补充</a>
+                    </td>
+                </tr>
+            <?php } ?>
+        <?php } else { ?>
+            <tr class="no_data">
+                <td colspan="8"><?php echo $lang['nc_no_record']; ?></td>
+            </tr>
+        <?php } ?>
+        </tbody>
+        <tfoot>
+        <tr class="tfoot">
+            <td colspan="8" id="dataFuncs">
+                <div class="pagination"> <?php echo $output['show_page']; ?> </div>
+            </td>
+        </tr>
+        </tfoot>
+    </table>
+    <!-- 预警提示 -->
+    <audio id="auto" src="<?php echo RESOURCE_SITE_URL; ?>/warning.mp3"></audio>
+</div>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/laydate/laydate.js"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/js/jquery-ui/jquery.ui.js"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL; ?>/js/jquery-ui/i18n/zh-CN.js"
+        charset="utf-8"></script>
+<script type="text/javascript" src="<?php echo RESOURCE_SITE_URL;?>/refill/layer.js"></script>
+<script type="text/javascript" src="<?php echo ADMIN_TEMPLATES_URL;?>/layui/layui.js"></script>
+<link rel="stylesheet" type="text/css" href="<?php echo ADMIN_TEMPLATES_URL; ?>/layui/css/layui.css"/>
+<link rel="stylesheet" type="text/css"
+      href="<?php echo RESOURCE_SITE_URL; ?>/js/jquery-ui/themes/ui-lightness/jquery.ui.css"/>
+<script type="text/javascript">
+    $(function () {
+        $('#ncsubmit').click(function () {
+            $('#formSearch').submit();
+        });
+        $('#query_start_time').datepicker({dateFormat: 'yy-mm-dd'});
+        $('#query_end_time').datepicker({dateFormat: 'yy-mm-dd'});
+        
+        // 日期选择器
+        laydate.render({
+            elem: '#startTime',
+            type: 'datetime'
+        });
+        laydate.render({
+            elem: '#endTime',
+            type: 'datetime'
+        });
+ 
+
+        //全选
+          //全选
+          $('#selectAll' ).click ( function () {
+          if ($(this).text() == '全选') {
+              $("input[name='checkbox']").each(function() {
+                  this.checked = true;
+              })
+              $(this).text("取消全选")
+          } else {
+              $("input[name='checkbox']").each(function() {
+                  this.checked = false;
+              })
+              $(this).text("全选")
+
+          }
+     
+
+            })
+
+            
+
+            
+            //批量
+            $('#hFail').click(function () {
+                layer.confirm('您确定要批量失败', {
+                btn: ['确定','取消'],
+                title:'批量失败'
+            }, function(){
+
+
+             let arr = [];
+            $("input:checkbox:checked").each(function (i) {
+                arr[i] = $(this).val();
+            })
+            let str = arr.join(",");
+            if (str != '') {
+            window.location.href =`index.php?act=refill_detail&op=order_dispose&id= ${str ? str : ''}&type=cancel`
+            console.log(str);
+            layer.msg('批量成功', {icon: 1});
+
+            } else {
+                layer.msg('请还没有任何操作,请先选择');
+            }
+
+		
+
+            }, function(){
+            });
+            })
+
+                        //批量
+                $('#hSupplement').click(function () {
+                layer.confirm('您确定要批量补充', {
+                btn: ['确定','取消'],
+                title:'批量失败'
+            }, function(){
+
+
+             let arr = [];
+            $("input:checkbox:checked").each(function (i) {
+                arr[i] = $(this).val();
+            })
+            let str = arr.join(",");
+            if (str != '') {
+            window.location.href =`index.php?act=refill_detail&op=order_dispose&id= ${str ? str : ''}&type=anew`
+            console.log(str);
+            layer.msg('批量成功', {icon: 1});
+
+            } else {
+                layer.msg('请还没有任何操作,请先选择');
+            }
+
+		
+
+            }, function(){
+            });
+            })
+      
+
+        // 表格hover时背景
+        $('.trFlex').each(function () {
+            let data_color = $(this).attr('data-timeout_State');
+            $(this).css('background', '#fff')
+            $(this).hover(function () {
+                $(this)[0].style.backgroundColor = '#cbe9f3'
+            }, function () {
+                $(this).css('background', '#fff')
+            })
+        })
+    });
+    function hCopyOrder(e) {
+        let str = ''
+        $('#tbody tr').each(function () {
+            let res = $(this).find('td').eq(3).text()
+            str += res + '\n'
+        })
+        let oInput = document.createElement("textarea");
+        oInput.style.border = "0 none";
+        oInput.style.color = "transparent";
+        oInput.value = str;
+        document.body.appendChild(oInput);
+        oInput.select(); // 选择对象
+        document.execCommand("Copy"); // 执行浏览器复制命令
+        oInput.parentNode.removeChild(oInput)
+    }
+
+    function hCopyCardNo(e) {
+        let str = ''
+        $('#tbody tr').each(function () {
+            let res = $(this).find('td').eq(4).text()
+            str += res + '\n'
+        })
+        let oInput = document.createElement("textarea");
+        oInput.style.border = "0 none";
+        oInput.style.color = "transparent";
+        oInput.value = str;
+        document.body.appendChild(oInput);
+        oInput.select(); // 选择对象
+        document.execCommand("Copy"); // 执行浏览器复制命令
+        oInput.parentNode.removeChild(oInput)
+    }
+
+    //批量补充
+    // function hSupplement(e) {
+    //     layer.confirm('您确定要批量补充', {
+    //     btn: ['确定','取消'],
+    //     title:'批量补充'
+    // }, function(){
+    //     layer.msg('1', {icon: 1});
+    // }, function(){
+    // });
+    // }
+</script> 

+ 12 - 2
admin/templates/default/refill.order.index.php

@@ -82,6 +82,9 @@
         padding: 9px 0;
     border-bottom: 1px solid #ccc;
     }
+    .db-top {
+        padding: 0 30px;
+    }
 
 </style>
 <?php defined('InShopNC') or exit('Access Invalid!'); ?>
@@ -243,6 +246,10 @@
                                 <?php if ($_GET['quality'] == '6'){ ?>selected<?php } ?>>慢6</option>
                         <option value="7"
                                 <?php if ($_GET['quality'] == '7'){ ?>selected<?php } ?>>慢2</option>
+                        <option value="8"
+                                <?php if ($_GET['quality'] == '8'){ ?>selected<?php } ?>>慢48</option>
+                        <option value="9"
+                                <?php if ($_GET['quality'] == '9'){ ?>selected<?php } ?>>慢72</option>
                     </select>
                     <label>有无流水</label>
                     <select name="official_status">
@@ -551,6 +558,7 @@
                                          <td class="db-center">${item.diff_time_text}</td>
                                          <td class="db-center">${item.order_state_text}</td>
                                          <td class="db-center">${item.channel_name}</td>
+                                         <td class="db-center">${item.err_msg}</td>
 
 
                              <tr>
@@ -559,7 +567,7 @@
 
 
                     layer.open({
-                   title: `共${data.count}单`,
+                   title: `<span>共${data.count}单</span> <span class="db-top">回调状态:${data.mch_notify_state}</span> <span>回调次数:${data.mch_notify_times}</span>` ,
                    content: `<table>
                    <thead>
                              <tr>
@@ -569,6 +577,7 @@
                                          <th class="db-right">耗时</th>
                                          <th class="db-right">订单状态</th>
                                          <th class="db-right">供方名称</th>
+                                         <th class="db-right">错误原因</th>
 
                              </tr>
                     </thead>
@@ -607,6 +616,7 @@
             selest_nc = xmSelect.render({
                 el: '#selest_nc',
                 size: 'mini',
+                filterable: true,
                 style: {
                     minHeight: '27px',
                     lineHeight: '27px',
@@ -615,7 +625,7 @@
                 language:'zn',
                 data:data
             })
-            // console.log('data', data);
+            console.log('data', data);
         })
         $('#query_start_time').datepicker({dateFormat: 'yy-mm-dd'});
         $('#query_end_time').datepicker({dateFormat: 'yy-mm-dd'});

+ 181 - 5
admin/templates/default/refill.order.neterr.index.php

@@ -47,6 +47,18 @@
     .lefto {
         margin-left: 6px;
     }
+    .db-right {
+        padding-right: 134px!important;
+    border-bottom: 1px solid #ccc;
+
+    }
+    .db-center {
+        padding: 9px 0;
+    border-bottom: 1px solid #ccc;
+    }
+    .db-top {
+        padding: 0 30px;
+    }
 </style>
 
 <?php defined('InShopNC') or exit('Access Invalid!'); ?>
@@ -95,6 +107,9 @@
                     <a href="#" class="btns" onclick="hCopyCardNo(event)">
                         <span><i class="icon-edit"></i>拷贝充值卡号</span>
                     </a>
+                    <a href="#" class="btns"  id="hFail">
+                        <span><i class="icon-edit"></i>批量失败</span>
+                    </a>
                 </td>
             </tr>
         </table>
@@ -102,6 +117,7 @@
     <table class="table tb-type2 nobdb">
         <thead>
         <tr class="thead">
+            <th class="align-center" id="selectAll">全选</th>
             <th class="align-center">编号</th>
             <th class="align-center">订单号</th>
             <th class="align-center">机构编号</th>
@@ -112,12 +128,14 @@
             <th class="align-right">下单日期</th>
             <th class="align-right">耗时</th>
             <th class="align-center">订单状态</th>
+            <th class="align-center">运营商流水号</th>
             <th class="align-center">通道质量</th>
             <th class="align-center">失败原因</th>
             <th class="align-center">商家单号</th>
             <th class="align-center">扣款金额</th>
             <th class="align-center">渠道单号</th>
             <th class="align-center">渠道名称</th>
+            <th class="align-center"><?php echo $lang['nc_handle']; ?></th>
         </tr>
         </thead>
         <tbody id="tbody">
@@ -125,6 +143,9 @@
             <?php
             foreach ($output['order_list'] as $key => $order) { ?>
                 <tr class="hover trFlex">
+                    <td class="align-center">
+                        <input type="checkbox" id="checkBoxList" name="checkbox" value="<?php echo $order['order_id'];?>">
+                    </td>
                     <td class="align-center"><?php echo $key + 1; ?></td>
                     <td class="align-left"><?php echo $order['order_sn']; ?></td>
                     <td class="align-center"><?php echo $order['mchid']; ?></td>
@@ -132,7 +153,9 @@
                     <td class="align-left"><?php echo $order['card_no']; ?></td>
                     <td class="align-center"><?php echo $order['card_type_text']; ?></td>
                     <td class="align-center"><?php echo $order['refill_amount']; ?></td>
-                    <td class="align-right"><?php echo date('Y-m-d H:i:s', $order['order_time']); ?></td>
+                    <td class="align-right"> <span class="doubleclick"  data-order="<?php echo $order['order_sn'];?>">
+                            <?php echo date('Y-m-d H:i:s', $order['order_time']); ?>
+                        </span></td>
                     <td class="align-right">
                         <?php if (empty($order['notify_time'])) {
                             if ($order['diff_time'] >= 1800 && $order['diff_time'] <= 3600) {
@@ -149,23 +172,34 @@
                         <?php } ?>
                     </td>
                     <td class="align-center"><?php echo orderState($order); ?></td>
+                    <td class="align-left"><?php echo $order['official_sn']; ?></td>
                     <td class="align-left"><?php echo $order['quality_text']; ?></td>
                     <td class="align-left"><?php echo $order['err_msg']; ?></td>
                     <td class="align-left"><?php echo $order['mch_order']; ?></td>
                     <td class="align-center"><?php echo $order['mch_amount']; ?></td>
                     <td class="align-left" class="ch_trade_no"><?php echo $order['ch_trade_no']; ?></td>
                     <td class="align-center"><?php echo $order['channel_name']; ?></td>
+                    <td class="align-center">
+                        <!-- <a href="#">
+                                回调</a>
+                        | -->
+                        <a class="hsuccess" data_id="<?php echo $order['order_id']; ?>" href="#" id="hsuccess">
+                        手动成功</a>
+                        |
+                        <a class="hcancel" data_id="<?php echo $order['order_id']; ?>" href="#" id="hcancel">
+                        手动失败</a>
+                    </td>
                 </tr>
             <?php } ?>
         <?php } else { ?>
             <tr class="no_data">
-                <td colspan="15"><?php echo $lang['nc_no_record']; ?></td>
+                <td colspan="20"><?php echo $lang['nc_no_record']; ?></td>
             </tr>
         <?php } ?>
         </tbody>
         <tfoot>
         <tr class="tfoot">
-            <td colspan="15" id="dataFuncs">
+            <td colspan="20" id="dataFuncs">
                 <div class="pagination"> <?php echo $output['show_page']; ?> </div>
             </td>
         </tr>
@@ -190,6 +224,148 @@
         });
         $('#query_start_time').datepicker({dateFormat: 'yy-mm-dd'});
         $('#query_end_time').datepicker({dateFormat: 'yy-mm-dd'});
+                  //全选
+         $('#selectAll' ).click ( function () {
+          if ($(this).text() == '全选') {
+              $("input[name='checkbox']").each(function() {
+                  this.checked = true;
+              })
+              $(this).text("取消全选")
+          } else {
+              $("input[name='checkbox']").each(function() {
+                  this.checked = false;
+              })
+              $(this).text("全选")
+
+          }
+     
+
+            })
+            //批量
+             $('#hFail').click(function () {
+                layer.confirm('您确定要批量失败', {
+                btn: ['确定','取消'],
+                title:'批量失败'
+                }, function(){
+
+
+                let arr = [];
+                $("input:checkbox:checked").each(function (i) {
+                arr[i] = $(this).val();
+            })
+            let str = arr.join(",");
+            // console.log(str);
+            if (str != '') {
+            window.location.href =`index.php?act=ordersendlist&op=neterr_order_manual&order_ids= ${str ? str : ''}&type=cancel`
+            console.log(str);
+            // layer.msg('批量成功', {icon: 1});
+
+            } else {
+                layer.msg('请还没有任何操作,请先选择');
+            }
+
+		
+
+            }, function(){
+            });
+            })
+            //手动成功
+            $('.hsuccess').click(function() {
+                let succid = $(this).attr('data_id');
+                layer.prompt({
+
+                    // formType:  1 ,
+                    title:  '请输入运营商流水号' ,
+                    // area: [ '500px' ,  '150px' ],
+                    // btnAlign:  'c' ,
+                    yes: function(index, layero){
+                        // 获取文本框输入的值
+                        var value = layero.find( ".layui-layer-input" ).val();
+                        console.log(value);
+                        if  (value) {
+                            window.location.href =`index.php?act=ordersendlist&op=neterr_order_manual&order_ids= ${succid}&type=success&official_sn= ${value}`
+                            // layer.close(index);
+                        }  else  {
+                            window.location.href =`index.php?act=ordersendlist&op=neterr_order_manual&order_ids= ${succid}&type=success`
+                        }
+                    }
+                    });
+            })
+            //手动失败
+            $('.hcancel').click(function() {
+                let succid = $(this).attr('data_id');
+                layer.confirm('确定要手动失败 ?', {
+                  btn: ['确定','失败'] //按钮
+                }, function(){
+                    window.location.href =`index.php?act=ordersendlist&op=neterr_order_manual&order_ids= ${succid}&type=cancel`
+                }, function(){
+               
+                  });
+                });
+           
+
+
+                        //双击
+             $('.doubleclick').dblclick(function() {
+            let db_click = $(this).attr('data-order')
+            $.get('index.php?act=refill_order&op=showOrders', {
+                order_sn:db_click
+            }, function(data) {
+                data = JSON.parse(data)
+           
+                if (data.state == 1) {
+                    
+                var dbclick = data.data
+                let ConentArr = [];
+                let html = ''; 
+                for (let i = 0; i < dbclick.length; i++) {
+                    var item = dbclick[i];
+                    html += `
+                    <tr>
+                                        <td class="db-center">${item.order_sn}</td>
+                                         <td class="db-center">${item.commit_time_text}</td>
+                                         <td class="db-center">${item.notify_time_text}</td>
+                                         <td class="db-center">${item.diff_time_text}</td>
+                                         <td class="db-center">${item.order_state_text}</td>
+                                         <td class="db-center">${item.channel_name}</td>
+                                         <td class="db-center">${item.err_msg}</td>
+
+
+                             <tr>
+                    `
+                }
+
+
+                    layer.open({
+                   title: `<span>共${data.count}单</span> <span class="db-top">回调状态:${data.mch_notify_state}</span> <span>回调次数:${data.mch_notify_times}</span>`,
+                   content: `<table>
+                   <thead>
+                             <tr>
+                                         <th class="db-right">订单号</th>
+                                         <th class="db-right">下单日期</th>
+                                         <th class="db-right">回调日期</th>
+                                         <th class="db-right">耗时</th>
+                                         <th class="db-right">订单状态</th>
+                                         <th class="db-right">供方名称</th>
+                                         <th class="db-right">错误原因</th>
+
+                             </tr>
+                    </thead>
+                             <tbody>
+                             ${html}
+                             </tbody>
+                            </table>`,
+                            
+
+                        });
+                } else {
+                    alert("没有此订单");
+
+                }
+                
+            })
+
+        })
         // 日期选择器
         laydate.render({
             elem: '#startTime',
@@ -236,7 +412,7 @@
     function hCopyChannel(e) {
         let str = ''
         $('#tbody tr').each(function () {
-            let res = $(this).find('td').eq(1).text()
+            let res = $(this).find('td').eq(2).text()
             str += res + '\n'
         })
         let oInput = document.createElement("textarea");
@@ -252,7 +428,7 @@
     function hCopyCardNo(e) {
         let str = ''
         $('#tbody tr').each(function () {
-            let res = $(this).find('td').eq(4).text()
+            let res = $(this).find('td').eq(5).text()
             str += res + '\n'
         })
         let oInput = document.createElement("textarea");

+ 80 - 3
admin/templates/default/refill.order.notify.err.index.php

@@ -47,6 +47,18 @@
     .lefto {
         margin-left: 6px;
     }
+    .db-right {
+        padding-right: 134px!important;
+    border-bottom: 1px solid #ccc;
+
+    }
+    .db-center {
+        padding: 9px 0;
+    border-bottom: 1px solid #ccc;
+    }
+    .db-top {
+        padding: 0 30px;
+    }
 </style>
 
 <?php defined('InShopNC') or exit('Access Invalid!'); ?>
@@ -153,7 +165,11 @@
                     <td class="align-left"><?php echo $order['card_no']; ?></td>
                     <td class="align-center"><?php echo $order['card_type_text']; ?></td>
                     <td class="align-center"><?php echo $order['refill_amount']; ?></td>
-                    <td class="align-right"><?php echo date('Y-m-d H:i:s', $order['order_time']); ?></td>
+                    <td class="align-right">
+                    <span class="doubleclick"  data-order="<?php echo $order['order_sn'];?>">
+                            <?php echo date('Y-m-d H:i:s', $order['order_time']); ?>
+                        </span>
+                    </td>
                     <td class="align-right">
                         <?php if (empty($order['notify_time'])) {
                             if ($order['diff_time'] >= 1800 && $order['diff_time'] <= 3600) {
@@ -190,13 +206,13 @@
             <?php } ?>
         <?php } else { ?>
             <tr class="no_data">
-                <td colspan="15"><?php echo $lang['nc_no_record']; ?></td>
+                <td colspan="18"><?php echo $lang['nc_no_record']; ?></td>
             </tr>
         <?php } ?>
         </tbody>
         <tfoot>
         <tr class="tfoot">
-            <td colspan="15" id="dataFuncs">
+            <td colspan="18" id="dataFuncs">
                 <div class="pagination"> <?php echo $output['show_page']; ?> </div>
             </td>
         </tr>
@@ -283,6 +299,67 @@
                 $(this)[0].style.backgroundColor = '#fff'
             })
         })
+                        //双击
+              $('.doubleclick').dblclick(function() {
+            let db_click = $(this).attr('data-order')
+            $.get('index.php?act=refill_order&op=showOrders', {
+                order_sn:db_click
+            }, function(data) {
+                data = JSON.parse(data)
+           
+                if (data.state == 1) {
+                    
+                var dbclick = data.data
+                let ConentArr = [];
+                let html = ''; 
+                for (let i = 0; i < dbclick.length; i++) {
+                    var item = dbclick[i];
+                    html += `
+                    <tr>
+                                        <td class="db-center">${item.order_sn}</td>
+                                         <td class="db-center">${item.commit_time_text}</td>
+                                         <td class="db-center">${item.notify_time_text}</td>
+                                         <td class="db-center">${item.diff_time_text}</td>
+                                         <td class="db-center">${item.order_state_text}</td>
+                                         <td class="db-center">${item.channel_name}</td>
+                                         <td class="db-center">${item.err_msg}</td>
+
+
+                             <tr>
+                    `
+                }
+
+
+                    layer.open({
+                   title: `<span>共${data.count}单</span> <span class="db-top">回调状态:${data.mch_notify_state}</span> <span>回调次数:${data.mch_notify_times}</span>`,
+                   content: `<table>
+                   <thead>
+                             <tr>
+                                         <th class="db-right">订单号</th>
+                                         <th class="db-right">下单日期</th>
+                                         <th class="db-right">回调日期</th>
+                                         <th class="db-right">耗时</th>
+                                         <th class="db-right">订单状态</th>
+                                         <th class="db-right">供方名称</th>
+                                         <th class="db-right">错误原因</th>
+
+                             </tr>
+                    </thead>
+                             <tbody>
+                             ${html}
+                             </tbody>
+                            </table>`,
+                            
+
+                        });
+                } else {
+                    alert("没有此订单");
+
+                }
+                
+            })
+
+        })
         // 供方名称颜色
         $('.textColor').each(function () {
             let color = $(this).attr('data-color')

+ 109 - 7
admin/templates/default/refill.order.search.php

@@ -3,6 +3,26 @@
         display: inline-block;
         width: 100px;
     }
+    .db-right {
+        padding-right: 134px!important;
+    border-bottom: 1px solid #ccc;
+
+    }
+    .db-center {
+        padding: 9px 0;
+    border-bottom: 1px solid #ccc;
+    }
+    .db-top {
+        padding: 0 30px;
+    }
+    .page .fixed-bar .item-title h3 {
+        margin-top:18px !important;
+        margin-bottom:10px !important;
+        font-weight:700 !important;
+    }
+    .tab-base li span {
+        font-size:12px !important;
+    }
 </style>
 
 <?php defined('InShopNC') or exit('Access Invalid!'); ?>
@@ -31,6 +51,8 @@
                 </td>
                 <th><label>充值卡号(多行查询)</label></th>
                 <td><textarea name="card_nos" id="card_nos" cols="30" rows="10"><?php echo $_GET['card_nos'];?></textarea></td>
+                <th><label>商家单号(多行查询)</label></th>
+                <td><textarea name="mch_orders" id="mch_orders" cols="30" rows="10"><?php echo $_GET['mch_orders'];?></textarea></td>
                 <td>
                     <a href="javascript:void(0);" id="ncsubmit" class="btn-search "
                        title="<?php echo $lang['nc_query']; ?>">&nbsp;
@@ -43,6 +65,9 @@
                     <a href="#" class="btns" onclick="hCopyCardNo(event)">
                         <span><i class="icon-edit"></i>拷贝充值卡号+渠道商</span>
                     </a>
+                    <a href="#" class="btns" onclick="hCopyOrder(event)">
+                        <span><i class="icon-edit"></i>拷贝订单号</span>
+                    </a>
                 </td>
             </tr>
         </table>
@@ -81,7 +106,11 @@
                     <td class="align-left"><?php echo $order['card_no']; ?></td>
                     <td class="align-center"><?php echo $order['card_type_text']; ?></td>
                     <td class="align-center"><?php echo $order['refill_amount']; ?></td>
-                    <td class="align-right"><?php echo date('Y-m-d H:i:s', $order['order_time']); ?></td>
+                    <td class="align-right">
+                        <span class="doubleclick"  data-order="<?php echo $order['order_sn'];?>">
+                            <?php echo date('Y-m-d H:i:s', $order['order_time']); ?>
+                        </span>
+                    </td>
                     <td class="align-right">
                         <?php if (empty($order['notify_time'])) {
                             if ($order['diff_time'] >= 1800 && $order['diff_time'] <= 3600) {
@@ -129,6 +158,8 @@
         charset="utf-8"></script>
 <link rel="stylesheet" type="text/css"
       href="<?php echo RESOURCE_SITE_URL; ?>/js/jquery-ui/themes/ui-lightness/jquery.ui.css"/>
+      <script type="text/javascript" src="<?php echo ADMIN_TEMPLATES_URL;?>/layui/layui.js"></script>
+<link rel="stylesheet" type="text/css" href="<?php echo ADMIN_TEMPLATES_URL; ?>/layui/css/layui.css"/>
 <script type="text/javascript">
     $(function () {
         $('#ncsubmit').click(function () {
@@ -160,6 +191,61 @@
                 window.location.reload();
             }, 60000);
         }
+                //双击
+                $('.doubleclick').dblclick(function() {
+            let db_click = $(this).attr('data-order')
+            $.get('index.php?act=refill_order&op=showOrders', {
+                order_sn:db_click
+            }, function(data) {
+                data = JSON.parse(data)
+                if (data.state == 1) {
+                    
+                var dbclick = data.data
+                let ConentArr = [];
+                let html = ''; 
+                for (let i = 0; i < dbclick.length; i++) {
+                    var item = dbclick[i];
+                    html += `
+                    <tr>
+                         <td class="db-center">${item.order_sn}</td>
+                         <td class="db-center">${item.commit_time_text}</td>
+                         <td class="db-center">${item.notify_time_text}</td>
+                         <td class="db-center">${item.diff_time_text}</td>
+                         <td class="db-center">${item.order_state_text}</td>
+                         <td class="db-center">${item.channel_name}</td>
+                         <td class="db-center">${item.err_msg}</td>
+                    <tr>
+                    `
+                }
+                layer.open({
+                   title: `<span>共${data.count}单</span> <span class="db-top">回调状态:${data.mch_notify_state}</span> <span>回调次数:${data.mch_notify_times}</span>` ,
+                   content: `<table>
+                   <thead>
+                             <tr>
+                                 <th class="db-right">订单号</th>
+                                 <th class="db-right">下单日期</th>
+                                 <th class="db-right">回调日期</th>
+                                 <th class="db-right">耗时</th>
+                                 <th class="db-right">订单状态</th>
+                                 <th class="db-right">供方名称</th>
+                                 <th class="db-right">错误原因</th>
+                             </tr>
+                    </thead>
+                             <tbody>
+                             ${html}
+                             </tbody>
+                            </table>`,
+                            
+
+                        });
+                } else {
+                    alert("没有此订单");
+
+                }
+                
+            })
+
+        })
         // 表格hover时背景
         $('.trFlex').each(function () {
             $(this).hover(function () {
@@ -186,13 +272,29 @@
             let channel_name = $(this).find('td').eq(15).text()
             str += card_no + '+' + channel_name + '\n'
         })
-        let oInput = document.createElement("textarea");
-        oInput.style.border = "0 none";
-        oInput.style.color = "transparent";
-        oInput.value = str;
+        let oInput = document.createElement("textarea");
+        oInput.style.border = "0 none";
+        oInput.style.color = "transparent";
+        oInput.value = str;
+        document.body.appendChild(oInput);
+        oInput.select(); // 选择对象
+        document.execCommand("Copy"); // 执行浏览器复制命令
+        oInput.parentNode.removeChild(oInput)
+    }
+
+    function hCopyOrder(e) {
+        let str = ''
+        $('#tbody tr').each(function () {
+            let order = $(this).find('td').eq(1).text()
+            str += order + '\n'
+        })
+        let oInput = document.createElement("textarea");
+        oInput.style.border = "0 none";
+        oInput.style.color = "transparent";
+        oInput.value = str;
         document.body.appendChild(oInput);
-        oInput.select(); // 选择对象
-        document.execCommand("Copy"); // 执行浏览器复制命令
+        oInput.select(); // 选择对象
+        document.execCommand("Copy"); // 执行浏览器复制命令
         oInput.parentNode.removeChild(oInput)
     }
 </script> 

+ 54 - 5
admin/templates/default/refill.order.send.index.php

@@ -56,6 +56,9 @@
         padding: 9px 0;
     border-bottom: 1px solid #ccc;
     }
+    .db-top {
+        padding: 0 30px;
+    }
 </style>
 
 <?php defined('InShopNC') or exit('Access Invalid!'); ?>
@@ -78,7 +81,7 @@
             <tr>
                 <th><label>客户名称</label></th>
                 <td class="layui-form">
-                    <select name="mchid" class="querySelect" lay-verify="">
+                    <select name="mchid" class="querySelect" lay-verify="" lay-search>
                         <option value=""><?php echo $lang['nc_please_choose']; ?></option>
                         <?php foreach ($output['merchant_list'] as $merchant) { ?>
                             <option value="<?php echo $merchant['mchid'] ?>"
@@ -157,6 +160,12 @@
                         <option value="7"
                                 <?php if ($_GET['quality'] == '7'){ ?>selected<?php } ?>>慢2
                         </option>
+                        <option value="8"
+                                <?php if ($_GET['quality'] == '8'){ ?>selected<?php } ?>>慢48
+                        </option>
+                        <option value="9"
+                                <?php if ($_GET['quality'] == '9'){ ?>selected<?php } ?>>慢72
+                        </option>
                     </select>
                 </td>
                 <th><label>订单耗时</label></th>
@@ -181,6 +190,9 @@
                         <option value="6"
                                 <?php if ($_GET['time'] == '6'){ ?>selected<?php } ?>>特定耗时15分钟订单
                         </option>
+                        <option value="7"
+                                <?php if ($_GET['time'] == '7'){ ?>selected<?php } ?>>特定耗时2小时订单
+                        </option>
                     </select>
                 </td>
                 <td>
@@ -233,6 +245,8 @@
                         <li class="lineLi" style="color:#000;">超过10分钟订单数量:<?php echo $output['count'][2] ?? 0 ?></li>
                     <?php } elseif ($_GET['time'] == 6) { ?>
                     <li class="lineLi" style="color:#000;">超过15分钟订单数量:<?php echo $output['count'][2] ?? 0 ?></li>
+                    <?php } elseif ($_GET['time'] == 7) { ?>
+                        <li class="lineLi" style="color:#000;">超过两小时订单数量:<?php echo $output['count'][2] ?? 0 ?></li>
                     <?php } ?>
                 </ul>
             </td>
@@ -265,7 +279,7 @@
         <?php if (count($output['order_list']) > 0) { ?>
             <?php
             foreach ($output['order_list'] as $key => $order) { ?>
-                <tr class="hover trFlex">
+                <tr class="hover trFlex" id="dataColor" data-timeout_State="<?php echo $order['time_out_state'];?>">
                     <td class="align-center"><?php echo $key + 1; ?></td>
                     <td class="align-left"><?php echo $order['order_sn']; ?></td>
                     <td class="align-center"><?php echo $order['mchid']; ?></td>
@@ -314,7 +328,7 @@
         </tbody>
         <tfoot>
         <tr class="tfoot">
-            <td colspan="15" id="dataFuncs">
+            <td colspan="17" id="dataFuncs">
                 <div class="pagination"> <?php echo $output['show_page']; ?> </div>
             </td>
         </tr>
@@ -339,6 +353,16 @@
         });
         $('#query_start_time').datepicker({dateFormat: 'yy-mm-dd'});
         $('#query_end_time').datepicker({dateFormat: 'yy-mm-dd'});
+    //  $('#dataColor').each(function () {
+    //      console.log($('#dataColor').attr('data-timeout_State'));
+    //      let data_color = $('#dataColor').attr('data-timeout_State');
+    //      if (data_color == 1) {
+    //         $(this).css('background', '#f1dde6')
+    //      } else {
+    //         $(this).css('background', '#fff')
+    //      }
+    //  })
+        
         // 日期选择器
         laydate.render({
             elem: '#startTime',
@@ -371,6 +395,7 @@
                                          <td class="db-center">${item.diff_time_text}</td>
                                          <td class="db-center">${item.order_state_text}</td>
                                          <td class="db-center">${item.channel_name}</td>
+                                         <td class="db-center">${item.err_msg}</td>
 
 
                              <tr>
@@ -379,7 +404,7 @@
 
 
                     layer.open({
-                   title: `共${data.count}单`,
+                   title: `<span>共${data.count}单</span> <span class="db-top">回调状态:${data.mch_notify_state}</span> <span>回调次数:${data.mch_notify_times}</span>`,
                    content: `<table>
                    <thead>
                              <tr>
@@ -389,6 +414,7 @@
                                          <th class="db-right">耗时</th>
                                          <th class="db-right">订单状态</th>
                                          <th class="db-right">供方名称</th>
+                                         <th class="db-right">错误原因</th>
 
                              </tr>
                     </thead>
@@ -424,10 +450,33 @@
         }
         // 表格hover时背景
         $('.trFlex').each(function () {
+            let data_color = $(this).attr('data-timeout_State');
+            if (data_color == 1) {
+                $(this).css('background', '#f1dde6')
+            } else if (data_color == 2) {
+                $(this).css('background', '#f2f3c6')
+            } else if (data_color == 3) {
+                $(this).css('background', '#ff7575')
+            } else if (data_color == 4) {
+                $(this).css('background', '#81C0C0')
+            } else {
+                $(this).css('background', '#fff')
+            }
             $(this).hover(function () {
                 $(this)[0].style.backgroundColor = '#cbe9f3'
             }, function () {
-                $(this)[0].style.backgroundColor = '#fff'
+                let data_color = $(this).attr('data-timeout_State');
+                if (data_color == 1) {
+                    $(this).css('background', '#f1dde6')
+                } else if (data_color == 2) {
+                    $(this).css('background', '#f2f3c6')
+                } else if (data_color == 3) {
+                    $(this).css('background', '#ff7575')
+                } else if (data_color == 4) {
+                    $(this).css('background', '#81C0C0')
+                } else {
+                    $(this).css('background', '#fff')
+                }
             })
         })
         // 供方名称颜色

+ 50 - 30
core/framework/cache/cache.redis.php

@@ -8,7 +8,6 @@ defined('InShopNC') or exit('Access Invalid!');
 class CacheRedis extends Cache
 {
 	private $config;
-	private $connected;
 	private $type;
 	private $prefix;
     public function __construct()
@@ -24,34 +23,54 @@ class CacheRedis extends Cache
     private function init_master()
     {
     	static $_cache;
-    	if (isset($_cache)){
-    		$this->handler = $_cache;
-    	}else{
-	        $func = $this->config['pconnect'] ? 'pconnect' : 'connect';
-	        $this->handler  = new Redis;
-	        $this->enable = $this->handler->$func($this->config['master']['host'], $this->config['master']['port']);
-	        $_cache = $this->handler;
+    	if (isset($_cache))
+    	{
+    	    if($_cache->isConnected()) {
+                $this->handler = $_cache;
+                return;
+            } else {
+                $_cache->close();
+                Log::record("CacheRedis init_slave disconnect.",Log::DEBUG);
+            }
     	}
-    }
+        if (is_mobile()) {
+            $func = 'connect';
+        } else {
+            $func = $this->config['pconnect'] ? 'pconnect' : 'connect';
+        }
 
-    private function init_slave(){
-    	static $_cache;
-    	if (isset($_cache)){
-    		$this->handler = $_cache;
-    	}else{
-	        $func = $this->config['pconnect'] ? 'pconnect' : 'connect';
-	        $this->handler = new Redis;
-	        $this->enable = $this->handler->$func($this->config['slave']['host'], $this->config['slave']['port']);
-	        $_cache = $this->handler;
-    	}
+        $this->handler  = new Redis();
+        $this->enable = $this->handler->$func($this->config['master']['host'], $this->config['master']['port']);
+        $_cache = $this->handler;
     }
 
-    private function isConnected() {
-    	$this->init_master();
-        return $this->enable;
+    private function init_slave()
+    {
+        static $_cache;
+        if (isset($_cache))
+        {
+            if($_cache->isConnected()) {
+                $this->handler = $_cache;
+                return;
+            } else {
+                $_cache->close();
+                Log::record("CacheRedis init_slave disconnect.",Log::DEBUG);
+            }
+        }
+
+        if (is_mobile()) {
+            $func = 'connect';
+        } else {
+            $func = $this->config['pconnect'] ? 'pconnect' : 'connect';
+        }
+
+        $this->handler = new Redis();
+        $this->enable = $this->handler->$func($this->config['slave']['host'], $this->config['slave']['port']);
+        $_cache = $this->handler;
     }
 
-	public function get($key, $prefix = ''){
+	public function get($key, $prefix = '')
+    {
 		$this->init_slave();
 		if (!$this->enable) return false;
 		$this->type = $prefix;
@@ -60,7 +79,8 @@ class CacheRedis extends Cache
         return unserialize($value);
 	}
 
-    public function set($key, $value, $prefix = '', $expire = null) {
+    public function set($key, $value, $prefix = '', $expire = null)
+    {
     	$this->init_master();
     	if (!$this->enable) return false;
     	$this->type = $prefix;
@@ -86,7 +106,7 @@ class CacheRedis extends Cache
 
     public function get_org($key,$prefix = '')
     {
-        $this->init_master();
+        $this->init_slave();
         if (!$this->enable) return false;
         $this->type = $prefix;
         $result = $this->handler->get($this->_key($key));
@@ -220,6 +240,7 @@ class CacheRedis extends Cache
     }
 
     public function hIncrByFloat($name, $prefix, $key, $num = 1) {
+        $this->init_master();
         if ($this->hget($name, $prefix,$key) !== false) {
             $this->handler->hIncrByFloat($this->_key($name), $key, floatval($num));
         }
@@ -242,13 +263,12 @@ class CacheRedis extends Cache
 		return $this->prefix.$this->type.$str;
 	}
 
-    public function keys($key = '') {
-        $this->init_master();
-
+    public function keys($key = '')
+    {
+        $this->init_slave();
         if(!isset($key) || empty($key)) {
             $key = '*';
         }
-
         return $this->handler->keys($this->_key($key));
     }
 
@@ -259,7 +279,7 @@ class CacheRedis extends Cache
     }
 
     public function lLen($key) {
-        $this->init_master();
+        $this->init_slave();
         if (!$this->enable) return false;
         return $this->handler->lLen($key);
     }

+ 10 - 21
core/framework/db/mysqli.php

@@ -64,16 +64,6 @@ class Db
 		                 COLLATION_DATABASE = utf8mb4_unicode_ci,
 		                 COLLATION_SERVER = utf8mb4_unicode_ci,
 		                 sql_mode=''";
-//                $query_string = "
-//		                 SET CHARACTER_SET_CLIENT = utf8,
-//		                 CHARACTER_SET_CONNECTION = utf8,
-//		                 CHARACTER_SET_DATABASE = utf8,
-//		                 CHARACTER_SET_RESULTS = utf8,
-//		                 CHARACTER_SET_SERVER = utf8,
-//		                 COLLATION_CONNECTION = utf8_general_ci,
-//		                 COLLATION_DATABASE = utf8_general_ci,
-//		                 COLLATION_SERVER = utf8_general_ci,
-//		                 sql_mode=''";
                 break;
             case 'GBK':
                 $query_string = "
@@ -122,10 +112,8 @@ class Db
     public static function query($sql, $host = 'master')
     {
         self::init_link();
-
         $count = 0;
-        do
-            {
+        do {
             $staer = new statistic_tm();
             $query = self::$link[$host]->query($sql);
             $staer->end();
@@ -134,21 +122,22 @@ class Db
             {
                 $eno = mysqli_errno(self::$link[$host]);
                 $emsg = mysqli_error(self::$link[$host]);
-                $error = "Db Error eno={$eno} msg={$emsg}";
-                Log::record("{$error} \r\n sql={$sql}", Log::ERR);
+                $error = "DbError eno={$eno} msg={$emsg}";
+                Log::record("{$error} sql={$sql}", Log::ERR);
 
-                if (self::$ifTransacting) {
-                    throw_exception($error);
-                }
-                elseif ($eno == self::ErrUnConnect) {
+                if ($eno == self::ErrUnConnect) {
                     if ($count > 0) return false;
                     self::connect($host);
                     $count++;
-                }
-                elseif (C('debug')) {
+                } elseif (C('debug')) {
                     throw_exception($error . '<br/>' . $sql);
                     return false;
                 }
+                elseif(self::ping($host) == false) {
+                    if ($count > 0) return false;
+                    self::connect($host);
+                    $count++;
+                }
                 else {
                     return false;
                 }

+ 22 - 21
core/framework/function/core.php

@@ -1685,27 +1685,28 @@ function compress_code($content)
  */
 function get_obj_instance($class, $method='', $args = array())
 {
-	static $_cache = array();
-	$key = $class.$method.(empty($args) ? null : md5(serialize($args)));
-	if (isset($_cache[$key])){
-		return $_cache[$key];
-	}else{
-		if (class_exists($class)){
-			$obj = new $class;
-			if (method_exists($obj,$method)){
-				if (empty($args)){
-					$_cache[$key] = $obj->$method();
-				}else{
-					$_cache[$key] = call_user_func_array(array(&$obj, $method), $args);
-				}
-			}else{
-				$_cache[$key] = $obj;
-			}
-			return $_cache[$key];
-		}else{
-			throw_exception('Class '.$class.' isn\'t exists!');
-		}
-	}
+    static $_cache = [];
+    $key = $class . $method . (empty($args) ? null : md5(serialize($args)));
+    if (isset($_cache[$key])) {
+        return $_cache[$key];
+    }
+    elseif (class_exists($class))
+    {
+        $obj = new $class;
+        if (method_exists($obj, $method))
+        {
+            if (empty($args)) {
+                $_cache[$key] = $obj->$method();
+            } else {
+                $_cache[$key] = call_user_func_array([&$obj, $method], $args);
+            }
+        } else {
+            $_cache[$key] = $obj;
+        }
+        return $_cache[$key];
+    } else {
+        throw_exception('Class ' . $class . ' isn\'t exists!');
+    }
 }
 
 /**

+ 8 - 2
core/framework/function/goods.php

@@ -205,10 +205,16 @@ function brandLogo($image_name = '') {
 * @param array $order_info 订单数组
 * @return string $order_state 描述输出
 */
-function orderState($order_info) {
+function orderState($order_info)
+{
+    $is_retrying = $order_info['is_retrying'];
     switch ($order_info['order_state']) {
         case ORDER_STATE_CANCEL:
-            $order_state = L('order_state_cancel');
+            if ($is_retrying) {
+                $order_state = '重试中';
+            } else {
+                $order_state = L('order_state_cancel');
+            }
         break;
         case ORDER_STATE_NEW:
             $order_state = L('order_state_new');

+ 3 - 3
core/framework/function/http.php

@@ -75,7 +75,7 @@ function http_request($url, $params = array(), $method = 'GET', $multi = false,
         $code = curl_getinfo($ci,CURLINFO_HTTP_CODE);
         if($code != 200) {
             $net_errno = "HTTP-{$code}";
-            Log::record("netmodule http_request http errno={$code} url={$url}",Log::ERR);
+            Log::record("netmodule http_request http errno={$net_errno} url={$url}",Log::ERR);
         }
     }
 
@@ -119,7 +119,7 @@ function http_post_data($url, $body, $headers = array(),&$net_errno = 0)
         $code = curl_getinfo($ci,CURLINFO_HTTP_CODE);
         if($code != 200) {
             $net_errno = "HTTP-{$code}";
-            Log::record("netmodule http_request http errno={$code} url={$url}",Log::ERR);
+            Log::record("netmodule http_request http errno={$net_errno} url={$url}",Log::ERR);
         }
     }
     curl_close($ci);
@@ -191,7 +191,7 @@ function https_request($url, $params = array(), $method = 'GET', $multi = false,
         $code = curl_getinfo($ci,CURLINFO_HTTP_CODE);
         if($code != 200) {
             $net_errno = "HTTP-{$code}";
-            Log::record("netmodule http_request http errno={$code} url={$url}",Log::ERR);
+            Log::record("netmodule http_request http errno={$net_errno} url={$url}",Log::ERR);
         }
     }
     curl_close($ci);

+ 2 - 2
core/framework/libraries/model.php

@@ -50,9 +50,9 @@ class trans_wapper
         $this->mState |= 0x0100;
         $this->mStart = microtime(true);
         if($this->mMod == null) {
-            Db::commit();
+            Db::rollback();
         } else {
-            $this->mMod->commit();
+            $this->mMod->rollback();
         }
         $msg = sprintf("trans_wapper rollback {$this->mName} use_time=%.6f",microtime(true) - $this->mStart);
         Log::record($msg,Log::DEBUG);

+ 18 - 1
crontab/control/date.php

@@ -48,10 +48,16 @@ class dateControl extends BaseCronControl
      */
     const ARRIVAL_NOTICE_NUM = 100;
 
+    public function indexOp()
+    {
+
+    }
+
+
     /**
      * 默认方法
      */
-    public function indexOp()
+    public function index_orgOp()
     {
         //更新订单商品佣金值
         $this->_order_commis_rate_update();
@@ -109,6 +115,17 @@ class dateControl extends BaseCronControl
         $refill->run();
     }
 
+    public function merchant_availableOp()
+    {
+        $merchant = Model('merchant')->getMerchantList([], 1000, '', true,'merchant.mchid,member.available_predeposit,merchant.credit_bonus');
+        $merchants = [];
+        foreach ($merchant as $value) {
+            $merchants[$value['mchid']] = $value['available_predeposit'] - $value['credit_bonus'];
+        }
+        $time = date("Y-m-d");
+        wcache("merchant_balance_{$time}", ['data' => serialize($merchants)], 'refill-');
+    }
+
     public function nine_clockOp()
     {
         //订单自动完成

+ 36 - 3
crontab/control/minutes.php

@@ -10,22 +10,55 @@
 defined('InShopNC') or exit('Access Invalid!');
 
 require_once (BASE_ROOT_PATH . '/helper/message/publisher.php');
+require_once(BASE_HELPER_PATH . '/refill/util.php');
 
 class minutesControl extends BaseCronControl
 {
+    public function indexexOp()
+    {
+        $this->_cron_common([1,2,3,4,5,6,7]);
+    }
+
     public function indexOp()
     {
         Log::record(__FUNCTION__ . " start",Log::DEBUG);
         //未付款订单超期自动关闭
         $this->_order_timeout_cancel();
         $this->_cron_common([1,2,3,4,5,6,7]);
-        $this->_web_index_update();
+        $this->_fetch_order_unavaliable();
         $this->_check_merchant_alarm_amount();
+        Log::record(__FUNCTION__ . " end",Log::DEBUG);
+
+//        $this->_web_index_update();
+//        $this->_check_merchant_alarm_amount();
 //        $this->check_refill_order_limit();
 
 //      $this->_cron_mail_send();
 //        $this->_SendOrderQuery();
-        Log::record(__FUNCTION__ . " end",Log::DEBUG);
+    }
+
+    private function _fetch_order_unavaliable()
+    {
+        try {
+            $mod_fetch_order = Model('fetch_order');
+            $trans = new trans_wapper($mod_fetch_order,__METHOD__);
+            $items = $mod_fetch_order->timeout_orders(900);
+            foreach ($items as $item) {
+                $fetch_id = $item['fetch_id'];
+                $mod_fetch_order->unavaliable($fetch_id);
+            }
+            $trans->commit();
+
+            foreach ($items as $item) {
+                $order_sn = $item['order_sn'];
+                $chname = $item['channel_name'];
+                refill\util::push_notify($chname,['order_sn' => $order_sn,'state' => 'CANCEL']);
+            }
+        }
+        catch (Exception $ex) {
+            $trans->rollback();
+            Log::record(__METHOD__ . " " . $ex->getMessage(),Log::ERR);
+        }
     }
 
     private function _check_merchant_alarm_amount()
@@ -35,7 +68,7 @@ class minutesControl extends BaseCronControl
             $caches = empty($mch_cache['data']) ? [] : unserialize($mch_cache['data']);
 
             $new_caches = [];
-            $merchants = Model('merchant')->getMerchantList([],'','','merchant.*,member.available_predeposit' ,"0,1000");
+            $merchants = Model('merchant')->getMerchantList(['merchant.merchant_state'=>1],'','',true,'merchant.*,member.available_predeposit' ,"0,1000");
             foreach ($merchants as $merchant)
             {
                 $mchid = $merchant['mchid'];

文件差異過大導致無法顯示
+ 1465 - 17
data/config/dev/refill.ini.php


文件差異過大導致無法顯示
+ 799 - 97
data/config/win/refill.ini.php


文件差異過大導致無法顯示
+ 799 - 97
data/config/xyz/refill.ini.php


文件差異過大導致無法顯示
+ 799 - 97
data/config/xyzadm/refill.ini.php


+ 1 - 1
data/config/xyztest/base.ini.php

@@ -11,7 +11,7 @@ define('USE_BONUS_RATE',false);
 define('SERVER_TYPE','panda');
 define('CROSS_DOAMIN',false);
 define('COMPANY_NAME', 'XYZ_COMPANY');
-define('ZERO_GOODS_ID', 6245);
+define('ZERO_GOODS_ID', 6405);
 
 $config = [];
 $config['base_site_url']        = SRV_HOST;

+ 13 - 1
data/config/xyztest/refill.ini.php

@@ -14,9 +14,21 @@ $config['refill_specs'] = [
     'chinatelecom' => $config['refill_phone_specs']
 ];
 
+$fetch_yezi_phone = ['name' => 'fetch_yezi', 'store_id' => 72,'qualitys' => '3',
+    'amount' => [
+        100 =>  [['goods_id' => 6699, 'price' => 95, 'quality' => 3, 'card_type' => 'sinopec,petrochina']],
+        200 =>  [['goods_id' => 6700, 'price' => 190, 'quality' => 3, 'card_type' => 'sinopec,petrochina']],
+        500 =>  [['goods_id' => 6701, 'price' => 475, 'quality' => 3, 'card_type' => 'sinopec,petrochina']],
+        1000 =>  [['goods_id' => 6702, 'price' => 950, 'quality' => 3, 'card_type' => 'sinopec,petrochina']],
+        2000 => [['goods_id' => 6703, 'price' => 1900, 'quality' => 3, 'card_type' => 'sinopec,petrochina']],
+    ],
+    'official_sn' => true, 'refill_type' => 'fetch'];
+
 
 //充值渠道配置表
-$oil_providers = [];
+$oil_providers = [
+    ['name' => 'fetch_yezi', 'cfg' => $fetch_yezi_phone],
+];
 $config['oil_providers'] = $oil_providers;
 
 $baidu_phone = ['name' => 'baidu', 'store_id' => 71,'qualitys' => '1',

+ 118 - 0
data/model/fetch_order.model.php

@@ -0,0 +1,118 @@
+<?php
+
+
+defined('InShopNC') or exit('Access Invalid!');
+
+
+class fetch_orderModel extends Model
+{
+    const FETCH_ORDER_UNAVALIABLE = 0;
+    const FETCH_ORDER_AVALIABLE = 1;
+    const FETCH_ORDER_PROCESSING = 2;
+    const FETCH_ORDER_PROCESSED = 3;
+    
+    public function __construct()
+    {
+        parent::__construct('fetch_order');
+    }
+
+    public function add($fetch_datas)
+    {
+        return $this->insert($fetch_datas);
+    }
+
+    public function store_order_count($store_id)
+    {
+        return $this->where(['fetch_status' => self::FETCH_ORDER_AVALIABLE, 'store_id' => $store_id])->count();
+    }
+
+    public function member_order_count($store_id,$member_id)
+    {
+        return $this->where(['fetch_status' => self::FETCH_ORDER_PROCESSING, 'store_id' => $store_id,'member_id' => $member_id])->count();
+    }
+
+    //抢单
+    public function fetch($store_id, $member_id, $card_type, $count, $spec)
+    {
+        try {
+            $trans = new trans_wapper($this,__METHOD__);
+            $items = $this->where(['fetch_status' => self::FETCH_ORDER_AVALIABLE, 'card_type' => $card_type, 'store_id' => $store_id, 'refill_amount' => $spec])
+                ->limit($count)
+                ->lock(true)
+                ->master(true)
+                ->order('add_time asc')
+                ->select();
+            foreach ($items as $item) {
+                $fetch_id = $item['fetch_id'];
+                $this->where(['fetch_id' => $fetch_id])->update(['fetch_status' => self::FETCH_ORDER_PROCESSING,'member_id' => $member_id,'fetch_time' => time()]);
+            }
+            $trans->commit();
+
+            return $items;
+        }
+        catch (Exception $ex) {
+            $trans->rollback();
+            Log::record(__METHOD__ . " fetch order trans err:" . $ex->getMessage() ,Log::ERR);
+            return [];
+        }
+    }
+
+    //退回订单,抢完后,但不想处理的单子,其它人可以继续处理.
+    public function reput($fetch_id)
+    {
+        return $this->where(['fetch_id' => $fetch_id,'fetch_status' => self::FETCH_ORDER_PROCESSING])->update(['member_id' => 0,'fetch_time' => 0,'fetch_status' => self::FETCH_ORDER_AVALIABLE]);
+    }
+
+    //处理完成的单子
+    public function processed($fetch_id,$fetch_result,$official_sn = '',$voucher = '')
+    {
+        return $this->where(['fetch_id' => $fetch_id,'fetch_status' => self::FETCH_ORDER_PROCESSING])
+                    ->update([
+                        'fetch_status' => self::FETCH_ORDER_PROCESSED,
+                        'finsh_time' => time(),
+                        'fetch_result' => $fetch_result,
+                        'official_sn' => $official_sn,
+                        'voucher' => $voucher
+                    ]);
+    }
+
+    //超时未处理订单,不可以再接单.
+    public function timeout_orders($timeout)
+    {
+        return $this->where(['fetch_status' => self::FETCH_ORDER_AVALIABLE, 'add_time' => ['lt',time() - $timeout]])
+            ->lock(true)
+            ->master(true)->select();
+    }
+
+    public function order_info($condition = [], $fields = '*', $master = false)
+    {
+        return $this->field($fields)->where($condition)->master($master)->find();
+    }
+
+    public function unavaliable($fetch_id)
+    {
+        return $this->where(['fetch_id' => $fetch_id,'fetch_status' => self::FETCH_ORDER_AVALIABLE])
+            ->update(['fetch_status' => self::FETCH_ORDER_UNAVALIABLE]);
+    }
+
+
+    //用户已经抢到,尚未处理完成的单子列表
+    public function fetch_order_list($store_id, $member_id)
+    {
+        return $this->field('*')->where(['store_id' => $store_id,'member_id' => $member_id,'fetch_status' => self::FETCH_ORDER_PROCESSING])->select();
+    }
+
+    //
+    public function getFetchOrderList($condition, $pagesize = '', $field = '*', $order = 'add_time desc', $limit = '')
+    {
+        $list = $this->field($field)->where($condition)->page($pagesize)->order($order)->limit($limit)->select();
+        if (empty($list)) return [];
+        return $list;
+    }
+
+    //
+    public function editFetchOrder($update,$condition)
+    {
+        return $this->where($condition)->update($update);
+    }
+}

+ 23 - 0
data/model/refill_detail.model.php

@@ -0,0 +1,23 @@
+<?php
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class refill_detailModel extends Model
+{
+    public function __construct()
+    {
+        parent::__construct('refill_detail');
+    }
+
+    public function getRefillDetailList($condition, $pagesize = '', $field = '*', $order = 'order_time desc', $limit = '')
+    {
+        $list = $this->field($field)->where($condition)->page($pagesize)->order($order)->limit($limit)->select();
+        if (empty($list)) return [];
+        return $list;
+    }
+
+    public function getDetailInfo($condition)
+    {
+        return $this->where($condition)->find();
+    }
+}

+ 22 - 0
data/model/refill_order.model.php

@@ -36,6 +36,18 @@ class refill_orderModel extends Model
         return $list;
     }
 
+    public function getMerchantTimeOut($condition, $pagesize = '', $field = '*', $order = 'refill_order.order_id desc', $limit = '', $master = false)
+    {
+        $list = $this->table('refill_order,vr_order,merchant')
+            ->join('inner,inner')
+            ->on('refill_order.order_id=vr_order.order_id,refill_order.mchid=merchant.mchid')
+            ->where($condition)
+            ->field($field)
+            ->page($pagesize)->order($order)->limit($limit)->master($master)->select();
+        if (empty($list)) return [];
+        return $list;
+    }
+
     public function getOrderStatsList($condition, $pagesize = '', $field = '*', $order = 'time_stamp desc', $limit = '')
     {
         $list = $this->table('refill_stats')->field($field)
@@ -48,4 +60,14 @@ class refill_orderModel extends Model
     {
         return $this->table('refill_order')->field('order_time')->where(['order_id' => ['gt',0]])->order('order_id asc')->find();
     }
+
+    public function add_detail($mchid,$mch_order,$details,$order_state)
+    {
+        return $this->table('refill_detail')->insert(['mchid' => $mchid,'mch_order' => $mch_order,'order_time' => time(),'params' => json_encode($details),'order_state' => $order_state]);
+    }
+
+    public function edit_detail($mchid,$mch_order,$datas)
+    {
+        return $this->table('refill_detail')->where(['mchid' => $mchid,'mch_order' => $mch_order])->update($datas);
+    }
 }

+ 0 - 10
docker/compose/stanley/docker-compose.yml

@@ -1,16 +1,6 @@
 version: "3.7"
 
 services:
-#  gogs:
-#    image: gogs/gogs:latest
-#    ports:
-#      - "10080:3000"
-#      - "10022:22"
-#    volumes:
-#      - /mnt/gitcode:/data
-#      - /mnt/gogs:/app/gogs
-#    container_name: "ibaobei-gogs"
-
   nginxsrv:
     image: nginx:alpine
     ports:

+ 83 - 0
docker/compose/xyz-arw/docker-compose.yml

@@ -0,0 +1,83 @@
+version: "3.7"
+
+services:
+  nginxsrv:
+    image: nginx:alpine
+    ports:
+      - "443:443"
+      - "80:80"
+    volumes:
+      - ../../../:/var/www/html
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /nfs/merchant:/var/www/html/merchant
+      - /nfs/icp:/var/www/html/icp
+      - ../../conf/nginx/cert:/etc/nginx/cert
+      - ../../conf/nginx/nginx-xyz-https.conf:/etc/nginx/nginx.conf:ro
+    container_name: "panda-nginx"
+    command: [nginx,'-g','daemon off;']
+    extra_hosts:
+      - "docker.hostip:172.17.0.1"
+
+  mobilesrv:
+    image: php-zts:7.3.18
+    ports:
+      - "9100:9100"
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - ../../conf/php/xyz-php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - ../../conf/php/mobile-spwan-start:/usr/local/bin/docker-spwan-start
+    container_name: "panda-mobile"
+    command: ['docker-spwan-start']
+    depends_on:
+      - "redisrv"
+
+  cordsrv:
+    image: php-swool-redis:latest
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - ../../conf/php/xyz-php-swoole.ini:/usr/local/etc/php/php.ini
+    container_name: "panda-codispatcher"
+    command: [php,"/var/www/html/rdispatcher/codispatcher.php","16"]
+    deploy:
+      resources:
+        limits:
+          cpus: '8'
+
+  queuesrv:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - ../../conf/php/xyz-php.ini:/usr/local/etc/php/php.ini
+    container_name: "panda-queue"
+    command: [php,"/var/www/html/queue/index.php", "queue", "index"]
+
+  searcher:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - ../../conf/php/xyz-php.ini:/usr/local/etc/php/php.ini
+    container_name: "panda-searcher"
+    command: [php, "/var/www/html/searcher.php"]
+
+  phpcli:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../conf/php/xyz-php.ini:/usr/local/etc/php/php.ini
+      - ../../../:/var/www/html
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "panda-php"

+ 38 - 0
docker/compose/xyz-storage/docker-compose.yml

@@ -0,0 +1,38 @@
+version: "3.7"
+
+services:
+  redisrv:
+    image: redis:alpine
+    ports:
+      - "6379:6379"
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../conf/redis/6379.conf:/etc/redis/redis.conf
+      - /mnt/redisdata:/data
+    container_name: "panda-redis"
+    command: [redis-server,"/etc/redis/redis.conf"]
+
+  crontabsrv:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - ../../conf/php/xyz-php.ini:/usr/local/etc/php/php.ini
+      - ../../conf/crontab/root:/var/spool/cron/crontabs/root
+    container_name: "panda-crontab"
+    command: [crond,"-f"]
+    depends_on:
+      - "redisrv"
+
+  cronsec:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - ../../conf/php/xyz-php.ini:/usr/local/etc/php/php.ini
+    container_name: "panda-cronsec"
+    command: [php,"/var/www/html/crontab/index.php",'minutes','second_queue']

+ 0 - 0
docker/compose/xyz-worker/restart.sh


+ 30 - 0
docker/compose/xyz/admin/docker-compose.yml

@@ -0,0 +1,30 @@
+version: "3.7"
+
+services:
+  mchsrv:
+    image: php-zts:7.3.18
+    ports:
+      - "9102:9102"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - ../conf/php/mch-spwan-start:/usr/local/bin/docker-spwan-start
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "panda-merchant"
+    command: [docker-spwan-start]
+
+  websrv:
+    image: php-fpm:alpine
+    ports:
+      - "9000:9000"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - ../conf/php-fpm/php-fpm.conf:/usr/local/etc/php-fpm.conf
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "panda-web"
+    command: [php-fpm]

+ 78 - 0
docker/compose/xyz/arw/docker-compose.yml

@@ -0,0 +1,78 @@
+version: "3.7"
+
+services:
+  nginxsrv:
+    image: nginx:alpine
+    ports:
+      - "80:80"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /nfs/merchant:/var/www/html/merchant
+    container_name: "panda-nginx"
+    command: [nginx,'-g','daemon off;']
+    extra_hosts:
+      - "docker.hostip:172.17.0.1"
+
+  mobilesrv:
+    image: php-zts:7.3.18
+    ports:
+      - "9100:9100"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - ../conf/php/mobile-spwan-start:/usr/local/bin/docker-spwan-start
+    container_name: "panda-mobile"
+    command: ['docker-spwan-start']
+
+  cordsrv:
+    image: php-swool-redis:latest
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php-swoole.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "worker-codispatcher"
+    command: [php,"/var/www/html/rdispatcher/codispatcher.php","16"]
+    deploy:
+      resources:
+        limits:
+          cpus: '8'
+
+  queuesrv:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "worker-queue"
+    command: [php,"/var/www/html/queue/index.php", "queue", "index"]
+
+  searcher:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "worker-searcher"
+    command: [php, "/var/www/html/searcher.php"]
+
+  phpcli:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "panda-php"

+ 4 - 0
docker/compose/xyz/arw/restart_all.sh

@@ -0,0 +1,4 @@
+docker-compose stop -t 1200 cordsrv
+docker-compose down
+docker-compose up -d
+docker-compose ps

+ 3 - 0
docker/compose/xyz/arw/restart_cordsrv.sh

@@ -0,0 +1,3 @@
+docker-compose stop -t 1200 cordsrv
+docker-compose up -d cordsrv
+docker-compose ps

+ 3 - 0
docker/compose/xyz/arw/stop_all.sh

@@ -0,0 +1,3 @@
+docker-compose stop -t 1200 cordsrv
+docker-compose down
+docker-compose ps

+ 19 - 0
docker/compose/xyz/conf/crontab/root

@@ -0,0 +1,19 @@
+# do daily/weekly/monthly maintenance
+# min	hour	day	month	weekday	command
+*/15	*	*	*	*	run-parts /etc/periodic/15min
+0	*	*	*	*	run-parts /etc/periodic/hourly
+0	2	*	*	*	run-parts /etc/periodic/daily
+0	3	*	*	6	run-parts /etc/periodic/weekly
+0	5	1	*	*	run-parts /etc/periodic/monthly
+#0   3   *   *   *   php /var/www/html/crontab/index.php date index
+0   4   *   *   *   php /var/www/html/crontab/index.php date forth_clock
+#0   9   *   *   *   php /var/www/html/crontab/index.php date nine_clock
+#0   10  *   *   *   php /var/www/html/crontab/index.php date ten_clock
+*    *   *   *   *   php /var/www/html/crontab/index.php minutes index
+#0   10-20/1 *   *   *   php /var/www/html/crontab/index.php hour index
+#0   3   1   */1 *   php /var/www/html/crontab/index.php month index
+*    *   *   *   *   echo "test" >> /var/test.log
+
+#0   1   *   *   *   php /var/www/html/crontab/index.php date _order_stats
+0   0    *   *   *   php /var/www/html/crontab/index.php date merchant_available
+

二進制
docker/compose/xyz/conf/etc/localtime


+ 127 - 0
docker/compose/xyz/conf/nginx/nginx.conf

@@ -0,0 +1,127 @@
+user nginx;
+worker_processes  8;
+error_log   /var/error.log  info;
+worker_rlimit_nofile 10240;
+
+events {
+    worker_connections  8192;
+    multi_accept on;
+    use epoll;
+}
+
+http 
+{
+    include       mime.types;
+    default_type  application/octet-stream;
+    fastcgi_buffer_size 32k;
+    fastcgi_buffers 8 32k;
+    underscores_in_headers on;
+    client_max_body_size 1024M;
+    tcp_nopush on;
+
+    sendfile            on;
+    keepalive_timeout   65;
+
+    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                      '$status $body_bytes_sent "$http_referer" '
+                      '"$http_user_agent" "$http_x_forwarded_for"';
+
+    server 
+    {
+    	listen       80;
+        set  $folder_name /var/www/html;
+        server_name www.xyzshops.cn order.xyzshops.cn;
+        root $folder_name;
+        index index.html index.php; 
+    	client_max_body_size 100m;
+    	proxy_connect_timeout 500s;
+        proxy_read_timeout 500s;
+        proxy_send_timeout 500s;
+        fastcgi_connect_timeout 75;
+        fastcgi_read_timeout 600;   
+        fastcgi_send_timeout 600;
+
+        set_real_ip_from 100.64.0.0/10;
+        real_ip_header X-Forwarded-For;
+
+        charset utf-8;
+        
+        location /logs {
+            deny all;
+            return 403;
+        }
+
+        location /data/log {
+            deny all;
+            return 403;
+        }
+        location / {
+            index  index.html index.htm index.php;
+        }
+        
+        location /mshop {
+            root $folder_name;
+            autoindex on;        
+            index  index.html index.htm index.php;
+	        try_files $uri $uri/ /mshop/index.html;
+        }
+
+        location /plot {
+            root $folder_name;
+            proxy_pass         http://172.26.105.126:5000;
+            proxy_redirect     off;
+
+            proxy_set_header   Host                 $host;
+            proxy_set_header   X-Real-IP            $remote_addr;
+            proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
+            proxy_set_header   X-Forwarded-Proto    $scheme;
+        }
+
+        location /merchant {
+            root $folder_name;
+            autoindex on;
+            index  index.html index.htm index.php;
+            try_files $uri $uri/ /merchant/index.html;
+        }
+
+        location ~ /mobile/[/\w]+\.php$ {
+            root           $folder_name;
+            fastcgi_pass   docker.hostip:9100;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            fastcgi_param  SIGN $http_sign;
+            include fastcgi_params;
+        }
+
+        location ~ /mobile/[/\w]+\.html$ {
+            try_files $uri $uri/ /mobile/index.html;
+        }
+
+        location ~ /racc/[/\w]+\.php$ {
+            root           $folder_name;
+            fastcgi_pass   docker.hostip:9101;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            fastcgi_param  SIGN $http_sign;
+            include fastcgi_params;
+        }
+
+        location ~ /mchsrv/[/\w]+\.php$ {
+            root           $folder_name;
+            fastcgi_pass   172.26.105.126:9102;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            fastcgi_param SIGN $http_sign;
+            include fastcgi_params;
+        }
+
+        location ~ \.php$ {
+	        add_header Cache-Control no-store;
+            root           $folder_name;
+            fastcgi_pass   172.26.105.126:9000;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            include        fastcgi_params;
+        }
+    }
+}

+ 143 - 0
docker/compose/xyz/conf/php-fpm/php-fpm.conf

@@ -0,0 +1,143 @@
+;;;;;;;;;;;;;;;;;;;;;
+; FPM Configuration ;
+;;;;;;;;;;;;;;;;;;;;;
+
+; All relative paths in this configuration file are relative to PHP's install
+; prefix (/usr/local). This prefix can be dynamically changed by using the
+; '-p' argument from the command line.
+
+;;;;;;;;;;;;;;;;;;
+; Global Options ;
+;;;;;;;;;;;;;;;;;;
+
+[global]
+; Pid file
+; Note: the default prefix is /usr/local/var
+; Default Value: none
+;pid = run/php-fpm.pid
+
+; Error log file
+; If it's set to "syslog", log is sent to syslogd instead of being written
+; into a local file.
+; Note: the default prefix is /usr/local/var
+; Default Value: log/php-fpm.log
+;error_log = log/php-fpm.log
+
+; syslog_facility is used to specify what type of program is logging the
+; message. This lets syslogd specify that messages from different facilities
+; will be handled differently.
+; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
+; Default Value: daemon
+;syslog.facility = daemon
+
+; syslog_ident is prepended to every message. If you have multiple FPM
+; instances running on the same server, you can change the default value
+; which must suit common needs.
+; Default Value: php-fpm
+;syslog.ident = php-fpm
+
+; Log level
+; Possible Values: alert, error, warning, notice, debug
+; Default Value: notice
+;log_level = notice
+
+; Log limit on number of characters in the single line (log entry). If the
+; line is over the limit, it is wrapped on multiple lines. The limit is for
+; all logged characters including message prefix and suffix if present. However
+; the new line character does not count into it as it is present only when
+; logging to a file descriptor. It means the new line character is not present
+; when logging to syslog.
+; Default Value: 1024
+;log_limit = 4096
+
+; Log buffering specifies if the log line is buffered which means that the
+; line is written in a single write operation. If the value is false, then the
+; data is written directly into the file descriptor. It is an experimental
+; option that can potentionaly improve logging performance and memory usage
+; for some heavy logging scenarios. This option is ignored if logging to syslog
+; as it has to be always buffered.
+; Default value: yes
+;log_buffering = no
+
+; If this number of child processes exit with SIGSEGV or SIGBUS within the time
+; interval set by emergency_restart_interval then FPM will restart. A value
+; of '0' means 'Off'.
+; Default Value: 0
+;emergency_restart_threshold = 0
+
+; Interval of time used by emergency_restart_interval to determine when
+; a graceful restart will be initiated.  This can be useful to work around
+; accidental corruptions in an accelerator's shared memory.
+; Available Units: s(econds), m(inutes), h(ours), or d(ays)
+; Default Unit: seconds
+; Default Value: 0
+;emergency_restart_interval = 0
+
+; Time limit for child processes to wait for a reaction on signals from master.
+; Available units: s(econds), m(inutes), h(ours), or d(ays)
+; Default Unit: seconds
+; Default Value: 0
+;process_control_timeout = 0
+
+; The maximum number of processes FPM will fork. This has been designed to control
+; the global number of processes when using dynamic PM within a lot of pools.
+; Use it with caution.
+; Note: A value of 0 indicates no limit
+; Default Value: 0
+; process.max = 128
+
+; Specify the nice(2) priority to apply to the master process (only if set)
+; The value can vary from -19 (highest priority) to 20 (lowest priority)
+; Note: - It will only work if the FPM master process is launched as root
+;       - The pool process will inherit the master process priority
+;         unless specified otherwise
+; Default Value: no set
+; process.priority = -19
+
+; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
+; Default Value: yes
+;daemonize = yes
+
+; Set open file descriptor rlimit for the master process.
+; Default Value: system defined value
+;rlimit_files = 1024
+
+; Set max core size rlimit for the master process.
+; Possible Values: 'unlimited' or an integer greater or equal to 0
+; Default Value: system defined value
+;rlimit_core = 0
+
+; Specify the event mechanism FPM will use. The following is available:
+; - select     (any POSIX os)
+; - poll       (any POSIX os)
+; - epoll      (linux >= 2.5.44)
+; - kqueue     (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)
+; - /dev/poll  (Solaris >= 7)
+; - port       (Solaris >= 10)
+; Default Value: not set (auto detection)
+;events.mechanism = epoll
+
+; When FPM is built with systemd integration, specify the interval,
+; in seconds, between health report notification to systemd.
+; Set to 0 to disable.
+; Available Units: s(econds), m(inutes), h(ours)
+; Default Unit: seconds
+; Default value: 10
+;systemd_interval = 10
+
+;;;;;;;;;;;;;;;;;;;;
+; Pool Definitions ;
+;;;;;;;;;;;;;;;;;;;;
+
+; Multiple pools of child processes may be started with different listening
+; ports and different management options.  The name of the pool will be
+; used in logs and stats. There is no limitation on the number of pools which
+; FPM can handle. Your system will tell you anyway :)
+
+; Include one or more files. If glob(3) exists, it is used to include a bunch of
+; files from a glob(3) pattern. This directive can be used everywhere in the
+; file.
+; Relative path can also be used. They will be prefixed by:
+;  - the global prefix if it's been set (-p argument)
+;  - /usr/local otherwise
+include=etc/php-fpm.d/*.conf

+ 12 - 0
docker/compose/xyz/conf/php/mch-spwan-start

@@ -0,0 +1,12 @@
+#!/bin/sh
+set -e
+spawn-fcgi -a 0.0.0.0 -p 9102 -F 10 -f "php /var/www/html/mchsrv/mchsrv_run.php"
+
+
+time=$(date "+%Y%m%d")
+
+if [ ! -f "/var/www/html/data/log/${time}-mchsrv.log" ]; then
+    touch "/var/www/html/data/log/${time}-mchsrv.log"
+fi
+
+tail -f "/var/www/html/data/log/${time}-mchsrv.log"

+ 11 - 0
docker/compose/xyz/conf/php/mobile-spwan-start

@@ -0,0 +1,11 @@
+#!/bin/sh
+set -e
+spawn-fcgi -a 0.0.0.0 -p 9100 -F 20 -f "php /var/www/html/mobile/mobile_run.php"
+
+time=$(date "+%Y%m%d")
+
+if [ ! -f "/var/www/html/data/log/${time}-mobile.log" ]; then
+    touch "/var/www/html/data/log/${time}-mobile.log"
+fi
+
+tail -f "/var/www/html/data/log/${time}-mobile.log"

文件差異過大導致無法顯示
+ 1944 - 0
docker/compose/xyz/conf/php/php-swoole.ini


文件差異過大導致無法顯示
+ 1942 - 0
docker/compose/xyz/conf/php/php.ini


+ 944 - 0
docker/compose/xyz/conf/redis/6379.conf

@@ -0,0 +1,944 @@
+## Generated by install_server.sh ##
+# Redis configuration file example.
+#
+# Note that in order to read the configuration file, Redis must be
+# started with the file path as first argument:
+#
+# ./redis-server /path/to/redis.conf
+
+# Note on units: when memory size is needed, it is possible to specify
+# it in the usual form of 1k 5GB 4M and so forth:
+#
+# 1k => 1000 bytes
+# 1kb => 1024 bytes
+# 1m => 1000000 bytes
+# 1mb => 1024*1024 bytes
+# 1g => 1000000000 bytes
+# 1gb => 1024*1024*1024 bytes
+#
+# units are case insensitive so 1GB 1Gb 1gB are all the same.
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here.  This is useful if you
+# have a standard template that goes to all Redis servers but also need
+# to customize a few per-server settings.  Include files can include
+# other files, so use this wisely.
+#
+# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
+# from admin or Redis Sentinel. Since Redis always uses the last processed
+# line as value of a configuration directive, you'd better put includes
+# at the beginning of this file to avoid overwriting config change at runtime.
+#
+# If instead you are interested in using includes to override configuration
+# options, it is better to use include as the last line.
+#
+# include /path/to/local.conf
+# include /path/to/other.conf
+
+################################ GENERAL  #####################################
+
+# By default Redis does not run as a daemon. Use 'yes' if you need it.
+# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
+daemonize no
+
+# When running daemonized, Redis writes a pid file in /var/run/redis.pid by
+# default. You can specify a custom pid file location here.
+pidfile /var/run/redis.pid
+
+# Accept connections on the specified port, default is 6379.
+# If port 0 is specified Redis will not listen on a TCP socket.
+port 6379
+
+# TCP listen() backlog.
+#
+# In high requests-per-second environments you need an high backlog in order
+# to avoid slow clients connections issues. Note that the Linux kernel
+# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
+# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
+# in order to get the desired effect.
+tcp-backlog 511
+
+# By default Redis listens for connections from all the network interfaces
+# available on the server. It is possible to listen to just one or multiple
+# interfaces using the "bind" configuration directive, followed by one or
+# more IP addresses.
+#
+# Examples:
+#
+# bind 192.168.1.100 10.0.0.1
+bind 0.0.0.0
+
+# Specify the path for the Unix socket that will be used to listen for
+# incoming connections. There is no default, so Redis will not listen
+# on a unix socket when not specified.
+#
+# unixsocket /tmp/redis.sock
+# unixsocketperm 700
+
+# Close the connection after a client is idle for N seconds (0 to disable)
+timeout 0
+
+# TCP keepalive.
+#
+# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
+# of communication. This is useful for two reasons:
+#
+# 1) Detect dead peers.
+# 2) Take the connection alive from the point of view of network
+#    equipment in the middle.
+#
+# On Linux, the specified value (in seconds) is the period used to send ACKs.
+# Note that to close the connection the double of the time is needed.
+# On other kernels the period depends on the kernel configuration.
+#
+# A reasonable value for this option is 60 seconds.
+tcp-keepalive 0
+
+# Specify the server verbosity level.
+# This can be one of:
+# debug (a lot of information, useful for development/testing)
+# verbose (many rarely useful info, but not a mess like the debug level)
+# notice (moderately verbose, what you want in production probably)
+# warning (only very important / critical messages are logged)
+loglevel notice
+
+# Specify the log file name. Also the empty string can be used to force
+# Redis to log on the standard output. Note that if you use standard
+# output for logging but daemonize, logs will be sent to /dev/null
+logfile redis.log
+
+# To enable logging to the system logger, just set 'syslog-enabled' to yes,
+# and optionally update the other syslog parameters to suit your needs.
+# syslog-enabled no
+
+# Specify the syslog identity.
+# syslog-ident redis
+
+# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
+# syslog-facility local0
+
+# Set the number of databases. The default database is DB 0, you can select
+# a different one on a per-connection basis using SELECT <dbid> where
+# dbid is a number between 0 and 'databases'-1
+databases 16
+
+################################ SNAPSHOTTING  ################################
+#
+# Save the DB on disk:
+#
+#   save <seconds> <changes>
+#
+#   Will save the DB if both the given number of seconds and the given
+#   number of write operations against the DB occurred.
+#
+#   In the example below the behaviour will be to save:
+#   after 900 sec (15 min) if at least 1 key changed
+#   after 300 sec (5 min) if at least 10 keys changed
+#   after 60 sec if at least 10000 keys changed
+#
+#   Note: you can disable saving completely by commenting out all "save" lines.
+#
+#   It is also possible to remove all the previously configured save
+#   points by adding a save directive with a single empty string argument
+#   like in the following example:
+#
+#   save ""
+
+save 900 1
+save 300 10
+save 60 10000
+
+# By default Redis will stop accepting writes if RDB snapshots are enabled
+# (at least one save point) and the latest background save failed.
+# This will make the user aware (in a hard way) that data is not persisting
+# on disk properly, otherwise chances are that no one will notice and some
+# disaster will happen.
+#
+# If the background saving process will start working again Redis will
+# automatically allow writes again.
+#
+# However if you have setup your proper monitoring of the Redis server
+# and persistence, you may want to disable this feature so that Redis will
+# continue to work as usual even if there are problems with disk,
+# permissions, and so forth.
+stop-writes-on-bgsave-error no
+
+# Compress string objects using LZF when dump .rdb databases?
+# For default that's set to 'yes' as it's almost always a win.
+# If you want to save some CPU in the saving child set it to 'no' but
+# the dataset will likely be bigger if you have compressible values or keys.
+rdbcompression yes
+
+# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
+# This makes the format more resistant to corruption but there is a performance
+# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
+# for maximum performances.
+#
+# RDB files created with checksum disabled have a checksum of zero that will
+# tell the loading code to skip the check.
+rdbchecksum yes
+
+# The filename where to dump the DB
+dbfilename dump.rdb
+
+# The working directory.
+#
+# The DB will be written inside this directory, with the filename specified
+# above using the 'dbfilename' configuration directive.
+#
+# The Append Only File will also be created inside this directory.
+#
+# Note that you must specify a directory here, not a file name.
+dir /data
+
+################################# REPLICATION #################################
+
+# Master-Slave replication. Use slaveof to make a Redis instance a copy of
+# another Redis server. A few things to understand ASAP about Redis replication.
+#
+# 1) Redis replication is asynchronous, but you can configure a master to
+#    stop accepting writes if it appears to be not connected with at least
+#    a given number of slaves.
+# 2) Redis slaves are able to perform a partial resynchronization with the
+#    master if the replication link is lost for a relatively small amount of
+#    time. You may want to configure the replication backlog size (see the next
+#    sections of this file) with a sensible value depending on your needs.
+# 3) Replication is automatic and does not need user intervention. After a
+#    network partition slaves automatically try to reconnect to masters
+#    and resynchronize with them.
+#
+# slaveof <masterip> <masterport>
+
+# If the master is password protected (using the "requirepass" configuration
+# directive below) it is possible to tell the slave to authenticate before
+# starting the replication synchronization process, otherwise the master will
+# refuse the slave request.
+#
+# masterauth <master-password>
+
+# When a slave loses its connection with the master, or when the replication
+# is still in progress, the slave can act in two different ways:
+#
+# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
+#    still reply to client requests, possibly with out of date data, or the
+#    data set may just be empty if this is the first synchronization.
+#
+# 2) if slave-serve-stale-data is set to 'no' the slave will reply with
+#    an error "SYNC with master in progress" to all the kind of commands
+#    but to INFO and SLAVEOF.
+#
+slave-serve-stale-data yes
+
+# You can configure a slave instance to accept writes or not. Writing against
+# a slave instance may be useful to store some ephemeral data (because data
+# written on a slave will be easily deleted after resync with the master) but
+# may also cause problems if clients are writing to it because of a
+# misconfiguration.
+#
+# Since Redis 2.6 by default slaves are read-only.
+#
+# Note: read only slaves are not designed to be exposed to untrusted clients
+# on the internet. It's just a protection layer against misuse of the instance.
+# Still a read only slave exports by default all the administrative commands
+# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
+# security of read only slaves using 'rename-command' to shadow all the
+# administrative / dangerous commands.
+slave-read-only yes
+
+# Replication SYNC strategy: disk or socket.
+#
+# -------------------------------------------------------
+# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY
+# -------------------------------------------------------
+#
+# New slaves and reconnecting slaves that are not able to continue the replication
+# process just receiving differences, need to do what is called a "full
+# synchronization". An RDB file is transmitted from the master to the slaves.
+# The transmission can happen in two different ways:
+#
+# 1) Disk-backed: The Redis master creates a new process that writes the RDB
+#                 file on disk. Later the file is transferred by the parent
+#                 process to the slaves incrementally.
+# 2) Diskless: The Redis master creates a new process that directly writes the
+#              RDB file to slave sockets, without touching the disk at all.
+#
+# With disk-backed replication, while the RDB file is generated, more slaves
+# can be queued and served with the RDB file as soon as the current child producing
+# the RDB file finishes its work. With diskless replication instead once
+# the transfer starts, new slaves arriving will be queued and a new transfer
+# will start when the current one terminates.
+#
+# When diskless replication is used, the master waits a configurable amount of
+# time (in seconds) before starting the transfer in the hope that multiple slaves
+# will arrive and the transfer can be parallelized.
+#
+# With slow disks and fast (large bandwidth) networks, diskless replication
+# works better.
+repl-diskless-sync no
+
+# When diskless replication is enabled, it is possible to configure the delay
+# the server waits in order to spawn the child that transfers the RDB via socket
+# to the slaves.
+#
+# This is important since once the transfer starts, it is not possible to serve
+# new slaves arriving, that will be queued for the next RDB transfer, so the server
+# waits a delay in order to let more slaves arrive.
+#
+# The delay is specified in seconds, and by default is 5 seconds. To disable
+# it entirely just set it to 0 seconds and the transfer will start ASAP.
+repl-diskless-sync-delay 5
+
+# Slaves send PINGs to server in a predefined interval. It's possible to change
+# this interval with the repl_ping_slave_period option. The default value is 10
+# seconds.
+#
+# repl-ping-slave-period 10
+
+# The following option sets the replication timeout for:
+#
+# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
+# 2) Master timeout from the point of view of slaves (data, pings).
+# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
+#
+# It is important to make sure that this value is greater than the value
+# specified for repl-ping-slave-period otherwise a timeout will be detected
+# every time there is low traffic between the master and the slave.
+#
+# repl-timeout 60
+
+# Disable TCP_NODELAY on the slave socket after SYNC?
+#
+# If you select "yes" Redis will use a smaller number of TCP packets and
+# less bandwidth to send data to slaves. But this can add a delay for
+# the data to appear on the slave side, up to 40 milliseconds with
+# Linux kernels using a default configuration.
+#
+# If you select "no" the delay for data to appear on the slave side will
+# be reduced but more bandwidth will be used for replication.
+#
+# By default we optimize for low latency, but in very high traffic conditions
+# or when the master and slaves are many hops away, turning this to "yes" may
+# be a good idea.
+repl-disable-tcp-nodelay no
+
+# Set the replication backlog size. The backlog is a buffer that accumulates
+# slave data when slaves are disconnected for some time, so that when a slave
+# wants to reconnect again, often a full resync is not needed, but a partial
+# resync is enough, just passing the portion of data the slave missed while
+# disconnected.
+#
+# The bigger the replication backlog, the longer the time the slave can be
+# disconnected and later be able to perform a partial resynchronization.
+#
+# The backlog is only allocated once there is at least a slave connected.
+#
+# repl-backlog-size 1mb
+
+# After a master has no longer connected slaves for some time, the backlog
+# will be freed. The following option configures the amount of seconds that
+# need to elapse, starting from the time the last slave disconnected, for
+# the backlog buffer to be freed.
+#
+# A value of 0 means to never release the backlog.
+#
+# repl-backlog-ttl 3600
+
+# The slave priority is an integer number published by Redis in the INFO output.
+# It is used by Redis Sentinel in order to select a slave to promote into a
+# master if the master is no longer working correctly.
+#
+# A slave with a low priority number is considered better for promotion, so
+# for instance if there are three slaves with priority 10, 100, 25 Sentinel will
+# pick the one with priority 10, that is the lowest.
+#
+# However a special priority of 0 marks the slave as not able to perform the
+# role of master, so a slave with priority of 0 will never be selected by
+# Redis Sentinel for promotion.
+#
+# By default the priority is 100.
+slave-priority 100
+
+# It is possible for a master to stop accepting writes if there are less than
+# N slaves connected, having a lag less or equal than M seconds.
+#
+# The N slaves need to be in "online" state.
+#
+# The lag in seconds, that must be <= the specified value, is calculated from
+# the last ping received from the slave, that is usually sent every second.
+#
+# This option does not GUARANTEE that N replicas will accept the write, but
+# will limit the window of exposure for lost writes in case not enough slaves
+# are available, to the specified number of seconds.
+#
+# For example to require at least 3 slaves with a lag <= 10 seconds use:
+#
+# min-slaves-to-write 3
+# min-slaves-max-lag 10
+#
+# Setting one or the other to 0 disables the feature.
+#
+# By default min-slaves-to-write is set to 0 (feature disabled) and
+# min-slaves-max-lag is set to 10.
+
+################################## SECURITY ###################################
+
+# Require clients to issue AUTH <PASSWORD> before processing any other
+# commands.  This might be useful in environments in which you do not trust
+# others with access to the host running redis-server.
+#
+# This should stay commented out for backward compatibility and because most
+# people do not need auth (e.g. they run their own servers).
+#
+# Warning: since Redis is pretty fast an outside user can try up to
+# 150k passwords per second against a good box. This means that you should
+# use a very strong password otherwise it will be very easy to break.
+#
+# requirepass foobared
+
+# Command renaming.
+#
+# It is possible to change the name of dangerous commands in a shared
+# environment. For instance the CONFIG command may be renamed into something
+# hard to guess so that it will still be available for internal-use tools
+# but not available for general clients.
+#
+# Example:
+#
+# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
+#
+# It is also possible to completely kill a command by renaming it into
+# an empty string:
+#
+# rename-command CONFIG ""
+#
+# Please note that changing the name of commands that are logged into the
+# AOF file or transmitted to slaves may cause problems.
+
+################################### LIMITS ####################################
+
+# Set the max number of connected clients at the same time. By default
+# this limit is set to 10000 clients, however if the Redis server is not
+# able to configure the process file limit to allow for the specified limit
+# the max number of allowed clients is set to the current file limit
+# minus 32 (as Redis reserves a few file descriptors for internal uses).
+#
+# Once the limit is reached Redis will close all the new connections sending
+# an error 'max number of clients reached'.
+#
+# maxclients 10000
+
+# Don't use more memory than the specified amount of bytes.
+# When the memory limit is reached Redis will try to remove keys
+# according to the eviction policy selected (see maxmemory-policy).
+#
+# If Redis can't remove keys according to the policy, or if the policy is
+# set to 'noeviction', Redis will start to reply with errors to commands
+# that would use more memory, like SET, LPUSH, and so on, and will continue
+# to reply to read-only commands like GET.
+#
+# This option is usually useful when using Redis as an LRU cache, or to set
+# a hard memory limit for an instance (using the 'noeviction' policy).
+#
+# WARNING: If you have slaves attached to an instance with maxmemory on,
+# the size of the output buffers needed to feed the slaves are subtracted
+# from the used memory count, so that network problems / resyncs will
+# not trigger a loop where keys are evicted, and in turn the output
+# buffer of slaves is full with DELs of keys evicted triggering the deletion
+# of more keys, and so forth until the database is completely emptied.
+#
+# In short... if you have slaves attached it is suggested that you set a lower
+# limit for maxmemory so that there is some free RAM on the system for slave
+# output buffers (but this is not needed if the policy is 'noeviction').
+#
+# maxmemory <bytes>
+
+# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
+# is reached. You can select among five behaviors:
+#
+# volatile-lru -> remove the key with an expire set using an LRU algorithm
+# allkeys-lru -> remove any key according to the LRU algorithm
+# volatile-random -> remove a random key with an expire set
+# allkeys-random -> remove a random key, any key
+# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
+# noeviction -> don't expire at all, just return an error on write operations
+#
+# Note: with any of the above policies, Redis will return an error on write
+#       operations, when there are no suitable keys for eviction.
+#
+#       At the date of writing these commands are: set setnx setex append
+#       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
+#       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
+#       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
+#       getset mset msetnx exec sort
+#
+# The default is:
+#
+# maxmemory-policy noeviction
+
+# LRU and minimal TTL algorithms are not precise algorithms but approximated
+# algorithms (in order to save memory), so you can tune it for speed or
+# accuracy. For default Redis will check five keys and pick the one that was
+# used less recently, you can change the sample size using the following
+# configuration directive.
+#
+# The default of 5 produces good enough results. 10 Approximates very closely
+# true LRU but costs a bit more CPU. 3 is very fast but not very accurate.
+#
+# maxmemory-samples 5
+
+############################## APPEND ONLY MODE ###############################
+
+# By default Redis asynchronously dumps the dataset on disk. This mode is
+# good enough in many applications, but an issue with the Redis process or
+# a power outage may result into a few minutes of writes lost (depending on
+# the configured save points).
+#
+# The Append Only File is an alternative persistence mode that provides
+# much better durability. For instance using the default data fsync policy
+# (see later in the config file) Redis can lose just one second of writes in a
+# dramatic event like a server power outage, or a single write if something
+# wrong with the Redis process itself happens, but the operating system is
+# still running correctly.
+#
+# AOF and RDB persistence can be enabled at the same time without problems.
+# If the AOF is enabled on startup Redis will load the AOF, that is the file
+# with the better durability guarantees.
+#
+# Please check http://redis.io/topics/persistence for more information.
+
+appendonly no
+
+# The name of the append only file (default: "appendonly.aof")
+
+appendfilename "appendonly.aof"
+
+# The fsync() call tells the Operating System to actually write data on disk
+# instead of waiting for more data in the output buffer. Some OS will really flush
+# data on disk, some other OS will just try to do it ASAP.
+#
+# Redis supports three different modes:
+#
+# no: don't fsync, just let the OS flush the data when it wants. Faster.
+# always: fsync after every write to the append only log. Slow, Safest.
+# everysec: fsync only one time every second. Compromise.
+#
+# The default is "everysec", as that's usually the right compromise between
+# speed and data safety. It's up to you to understand if you can relax this to
+# "no" that will let the operating system flush the output buffer when
+# it wants, for better performances (but if you can live with the idea of
+# some data loss consider the default persistence mode that's snapshotting),
+# or on the contrary, use "always" that's very slow but a bit safer than
+# everysec.
+#
+# More details please check the following article:
+# http://antirez.com/post/redis-persistence-demystified.html
+#
+# If unsure, use "everysec".
+
+# appendfsync always
+appendfsync everysec
+# appendfsync no
+
+# When the AOF fsync policy is set to always or everysec, and a background
+# saving process (a background save or AOF log background rewriting) is
+# performing a lot of I/O against the disk, in some Linux configurations
+# Redis may block too long on the fsync() call. Note that there is no fix for
+# this currently, as even performing fsync in a different thread will block
+# our synchronous write(2) call.
+#
+# In order to mitigate this problem it's possible to use the following option
+# that will prevent fsync() from being called in the main process while a
+# BGSAVE or BGREWRITEAOF is in progress.
+#
+# This means that while another child is saving, the durability of Redis is
+# the same as "appendfsync none". In practical terms, this means that it is
+# possible to lose up to 30 seconds of log in the worst scenario (with the
+# default Linux settings).
+#
+# If you have latency problems turn this to "yes". Otherwise leave it as
+# "no" that is the safest pick from the point of view of durability.
+
+no-appendfsync-on-rewrite no
+
+# Automatic rewrite of the append only file.
+# Redis is able to automatically rewrite the log file implicitly calling
+# BGREWRITEAOF when the AOF log size grows by the specified percentage.
+#
+# This is how it works: Redis remembers the size of the AOF file after the
+# latest rewrite (if no rewrite has happened since the restart, the size of
+# the AOF at startup is used).
+#
+# This base size is compared to the current size. If the current size is
+# bigger than the specified percentage, the rewrite is triggered. Also
+# you need to specify a minimal size for the AOF file to be rewritten, this
+# is useful to avoid rewriting the AOF file even if the percentage increase
+# is reached but it is still pretty small.
+#
+# Specify a percentage of zero in order to disable the automatic AOF
+# rewrite feature.
+
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+
+# An AOF file may be found to be truncated at the end during the Redis
+# startup process, when the AOF data gets loaded back into memory.
+# This may happen when the system where Redis is running
+# crashes, especially when an ext4 filesystem is mounted without the
+# data=ordered option (however this can't happen when Redis itself
+# crashes or aborts but the operating system still works correctly).
+#
+# Redis can either exit with an error when this happens, or load as much
+# data as possible (the default now) and start if the AOF file is found
+# to be truncated at the end. The following option controls this behavior.
+#
+# If aof-load-truncated is set to yes, a truncated AOF file is loaded and
+# the Redis server starts emitting a log to inform the user of the event.
+# Otherwise if the option is set to no, the server aborts with an error
+# and refuses to start. When the option is set to no, the user requires
+# to fix the AOF file using the "redis-check-aof" utility before to restart
+# the server.
+#
+# Note that if the AOF file will be found to be corrupted in the middle
+# the server will still exit with an error. This option only applies when
+# Redis will try to read more data from the AOF file but not enough bytes
+# will be found.
+aof-load-truncated yes
+
+################################ LUA SCRIPTING  ###############################
+
+# Max execution time of a Lua script in milliseconds.
+#
+# If the maximum execution time is reached Redis will log that a script is
+# still in execution after the maximum allowed time and will start to
+# reply to queries with an error.
+#
+# When a long running script exceeds the maximum execution time only the
+# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be
+# used to stop a script that did not yet called write commands. The second
+# is the only way to shut down the server in the case a write command was
+# already issued by the script but the user doesn't want to wait for the natural
+# termination of the script.
+#
+# Set it to 0 or a negative value for unlimited execution without warnings.
+lua-time-limit 5000
+
+################################ REDIS CLUSTER  ###############################
+#
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however
+# in order to mark it as "mature" we need to wait for a non trivial percentage
+# of users to deploy it in production.
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
+# started as cluster nodes can. In order to start a Redis instance as a
+# cluster node enable the cluster support uncommenting the following:
+#
+# cluster-enabled yes
+
+# Every cluster node has a cluster configuration file. This file is not
+# intended to be edited by hand. It is created and updated by Redis nodes.
+# Every Redis Cluster node requires a different cluster configuration file.
+# Make sure that instances running in the same system do not have
+# overlapping cluster configuration file names.
+#
+# cluster-config-file nodes-6379.conf
+
+# Cluster node timeout is the amount of milliseconds a node must be unreachable
+# for it to be considered in failure state.
+# Most other internal time limits are multiple of the node timeout.
+#
+# cluster-node-timeout 15000
+
+# A slave of a failing master will avoid to start a failover if its data
+# looks too old.
+#
+# There is no simple way for a slave to actually have a exact measure of
+# its "data age", so the following two checks are performed:
+#
+# 1) If there are multiple slaves able to failover, they exchange messages
+#    in order to try to give an advantage to the slave with the best
+#    replication offset (more data from the master processed).
+#    Slaves will try to get their rank by offset, and apply to the start
+#    of the failover a delay proportional to their rank.
+#
+# 2) Every single slave computes the time of the last interaction with
+#    its master. This can be the last ping or command received (if the master
+#    is still in the "connected" state), or the time that elapsed since the
+#    disconnection with the master (if the replication link is currently down).
+#    If the last interaction is too old, the slave will not try to failover
+#    at all.
+#
+# The point "2" can be tuned by user. Specifically a slave will not perform
+# the failover if, since the last interaction with the master, the time
+# elapsed is greater than:
+#
+#   (node-timeout * slave-validity-factor) + repl-ping-slave-period
+#
+# So for example if node-timeout is 30 seconds, and the slave-validity-factor
+# is 10, and assuming a default repl-ping-slave-period of 10 seconds, the
+# slave will not try to failover if it was not able to talk with the master
+# for longer than 310 seconds.
+#
+# A large slave-validity-factor may allow slaves with too old data to failover
+# a master, while a too small value may prevent the cluster from being able to
+# elect a slave at all.
+#
+# For maximum availability, it is possible to set the slave-validity-factor
+# to a value of 0, which means, that slaves will always try to failover the
+# master regardless of the last time they interacted with the master.
+# (However they'll always try to apply a delay proportional to their
+# offset rank).
+#
+# Zero is the only value able to guarantee that when all the partitions heal
+# the cluster will always be able to continue.
+#
+# cluster-slave-validity-factor 10
+
+# Cluster slaves are able to migrate to orphaned masters, that are masters
+# that are left without working slaves. This improves the cluster ability
+# to resist to failures as otherwise an orphaned master can't be failed over
+# in case of failure if it has no working slaves.
+#
+# Slaves migrate to orphaned masters only if there are still at least a
+# given number of other working slaves for their old master. This number
+# is the "migration barrier". A migration barrier of 1 means that a slave
+# will migrate only if there is at least 1 other working slave for its master
+# and so forth. It usually reflects the number of slaves you want for every
+# master in your cluster.
+#
+# Default is 1 (slaves migrate only if their masters remain with at least
+# one slave). To disable migration just set it to a very large value.
+# A value of 0 can be set but is useful only for debugging and dangerous
+# in production.
+#
+# cluster-migration-barrier 1
+
+# By default Redis Cluster nodes stop accepting queries if they detect there
+# is at least an hash slot uncovered (no available node is serving it).
+# This way if the cluster is partially down (for example a range of hash slots
+# are no longer covered) all the cluster becomes, eventually, unavailable.
+# It automatically returns available as soon as all the slots are covered again.
+#
+# However sometimes you want the subset of the cluster which is working,
+# to continue to accept queries for the part of the key space that is still
+# covered. In order to do so, just set the cluster-require-full-coverage
+# option to no.
+#
+# cluster-require-full-coverage yes
+
+# In order to setup your cluster make sure to read the documentation
+# available at http://redis.io web site.
+
+################################## SLOW LOG ###################################
+
+# The Redis Slow Log is a system to log queries that exceeded a specified
+# execution time. The execution time does not include the I/O operations
+# like talking with the client, sending the reply and so forth,
+# but just the time needed to actually execute the command (this is the only
+# stage of command execution where the thread is blocked and can not serve
+# other requests in the meantime).
+#
+# You can configure the slow log with two parameters: one tells Redis
+# what is the execution time, in microseconds, to exceed in order for the
+# command to get logged, and the other parameter is the length of the
+# slow log. When a new command is logged the oldest one is removed from the
+# queue of logged commands.
+
+# The following time is expressed in microseconds, so 1000000 is equivalent
+# to one second. Note that a negative number disables the slow log, while
+# a value of zero forces the logging of every command.
+slowlog-log-slower-than 10000
+
+# There is no limit to this length. Just be aware that it will consume memory.
+# You can reclaim memory used by the slow log with SLOWLOG RESET.
+slowlog-max-len 128
+
+################################ LATENCY MONITOR ##############################
+
+# The Redis latency monitoring subsystem samples different operations
+# at runtime in order to collect data related to possible sources of
+# latency of a Redis instance.
+#
+# Via the LATENCY command this information is available to the user that can
+# print graphs and obtain reports.
+#
+# The system only logs operations that were performed in a time equal or
+# greater than the amount of milliseconds specified via the
+# latency-monitor-threshold configuration directive. When its value is set
+# to zero, the latency monitor is turned off.
+#
+# By default latency monitoring is disabled since it is mostly not needed
+# if you don't have latency issues, and collecting data has a performance
+# impact, that while very small, can be measured under big load. Latency
+# monitoring can easily be enabled at runtime using the command
+# "CONFIG SET latency-monitor-threshold <milliseconds>" if needed.
+latency-monitor-threshold 0
+
+############################# EVENT NOTIFICATION ##############################
+
+# Redis can notify Pub/Sub clients about events happening in the key space.
+# This feature is documented at http://redis.io/topics/notifications
+#
+# For instance if keyspace events notification is enabled, and a client
+# performs a DEL operation on key "foo" stored in the Database 0, two
+# messages will be published via Pub/Sub:
+#
+# PUBLISH __keyspace@0__:foo del
+# PUBLISH __keyevent@0__:del foo
+#
+# It is possible to select the events that Redis will notify among a set
+# of classes. Every class is identified by a single character:
+#
+#  K     Keyspace events, published with __keyspace@<db>__ prefix.
+#  E     Keyevent events, published with __keyevent@<db>__ prefix.
+#  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
+#  $     String commands
+#  l     List commands
+#  s     Set commands
+#  h     Hash commands
+#  z     Sorted set commands
+#  x     Expired events (events generated every time a key expires)
+#  e     Evicted events (events generated when a key is evicted for maxmemory)
+#  A     Alias for g$lshzxe, so that the "AKE" string means all the events.
+#
+#  The "notify-keyspace-events" takes as argument a string that is composed
+#  of zero or multiple characters. The empty string means that notifications
+#  are disabled.
+#
+#  Example: to enable list and generic events, from the point of view of the
+#           event name, use:
+#
+#  notify-keyspace-events Elg
+#
+#  Example 2: to get the stream of the expired keys subscribing to channel
+#             name __keyevent@0__:expired use:
+#
+#  notify-keyspace-events Ex
+#
+#  By default all notifications are disabled because most users don't need
+#  this feature and the feature has some overhead. Note that if you don't
+#  specify at least one of K or E, no events will be delivered.
+notify-keyspace-events Ex
+
+############################### ADVANCED CONFIG ###############################
+
+# Hashes are encoded using a memory efficient data structure when they have a
+# small number of entries, and the biggest entry does not exceed a given
+# threshold. These thresholds can be configured using the following directives.
+hash-max-ziplist-entries 512
+hash-max-ziplist-value 64
+
+# Similarly to hashes, small lists are also encoded in a special way in order
+# to save a lot of space. The special representation is only used when
+# you are under the following limits:
+list-max-ziplist-entries 512
+list-max-ziplist-value 64
+
+# Sets have a special encoding in just one case: when a set is composed
+# of just strings that happen to be integers in radix 10 in the range
+# of 64 bit signed integers.
+# The following configuration setting sets the limit in the size of the
+# set in order to use this special memory saving encoding.
+set-max-intset-entries 512
+
+# Similarly to hashes and lists, sorted sets are also specially encoded in
+# order to save a lot of space. This encoding is only used when the length and
+# elements of a sorted set are below the following limits:
+zset-max-ziplist-entries 128
+zset-max-ziplist-value 64
+
+# HyperLogLog sparse representation bytes limit. The limit includes the
+# 16 bytes header. When an HyperLogLog using the sparse representation crosses
+# this limit, it is converted into the dense representation.
+#
+# A value greater than 16000 is totally useless, since at that point the
+# dense representation is more memory efficient.
+#
+# The suggested value is ~ 3000 in order to have the benefits of
+# the space efficient encoding without slowing down too much PFADD,
+# which is O(N) with the sparse encoding. The value can be raised to
+# ~ 10000 when CPU is not a concern, but space is, and the data set is
+# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
+hll-sparse-max-bytes 3000
+
+# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
+# order to help rehashing the main Redis hash table (the one mapping top-level
+# keys to values). The hash table implementation Redis uses (see dict.c)
+# performs a lazy rehashing: the more operation you run into a hash table
+# that is rehashing, the more rehashing "steps" are performed, so if the
+# server is idle the rehashing is never complete and some more memory is used
+# by the hash table.
+#
+# The default is to use this millisecond 10 times every second in order to
+# actively rehash the main dictionaries, freeing memory when possible.
+#
+# If unsure:
+# use "activerehashing no" if you have hard latency requirements and it is
+# not a good thing in your environment that Redis can reply from time to time
+# to queries with 2 milliseconds delay.
+#
+# use "activerehashing yes" if you don't have such hard requirements but
+# want to free memory asap when possible.
+activerehashing yes
+
+# The client output buffer limits can be used to force disconnection of clients
+# that are not reading data from the server fast enough for some reason (a
+# common reason is that a Pub/Sub client can't consume messages as fast as the
+# publisher can produce them).
+#
+# The limit can be set differently for the three different classes of clients:
+#
+# normal -> normal clients including MONITOR clients
+# slave  -> slave clients
+# pubsub -> clients subscribed to at least one pubsub channel or pattern
+#
+# The syntax of every client-output-buffer-limit directive is the following:
+#
+# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
+#
+# A client is immediately disconnected once the hard limit is reached, or if
+# the soft limit is reached and remains reached for the specified number of
+# seconds (continuously).
+# So for instance if the hard limit is 32 megabytes and the soft limit is
+# 16 megabytes / 10 seconds, the client will get disconnected immediately
+# if the size of the output buffers reach 32 megabytes, but will also get
+# disconnected if the client reaches 16 megabytes and continuously overcomes
+# the limit for 10 seconds.
+#
+# By default normal clients are not limited because they don't receive data
+# without asking (in a push way), but just after a request, so only
+# asynchronous clients may create a scenario where data is requested faster
+# than it can read.
+#
+# Instead there is a default limit for pubsub and slave clients, since
+# subscribers and slaves receive data in a push fashion.
+#
+# Both the hard or the soft limit can be disabled by setting them to zero.
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit slave 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+
+# Redis calls an internal function to perform many background tasks, like
+# closing connections of clients in timeout, purging expired keys that are
+# never requested, and so forth.
+#
+# Not all tasks are performed with the same frequency, but Redis checks for
+# tasks to perform according to the specified "hz" value.
+#
+# By default "hz" is set to 10. Raising the value will use more CPU when
+# Redis is idle, but at the same time will make Redis more responsive when
+# there are many keys expiring at the same time, and timeouts may be
+# handled with more precision.
+#
+# The range is between 1 and 500, however a value over 100 is usually not
+# a good idea. Most users should use the default of 10 and raise this up to
+# 100 only in environments where very low latency is required.
+hz 10
+
+# When a child rewrites the AOF file, if the following option is enabled
+# the file will be fsync-ed every 32 MB of data generated. This is useful
+# in order to commit the file to the disk more incrementally and avoid
+# big latency spikes.
+aof-rewrite-incremental-fsync yes

+ 944 - 0
docker/compose/xyz/conf/redis/6380.conf

@@ -0,0 +1,944 @@
+## Generated by install_server.sh ##
+# Redis configuration file example.
+#
+# Note that in order to read the configuration file, Redis must be
+# started with the file path as first argument:
+#
+# ./redis-server /path/to/redis.conf
+
+# Note on units: when memory size is needed, it is possible to specify
+# it in the usual form of 1k 5GB 4M and so forth:
+#
+# 1k => 1000 bytes
+# 1kb => 1024 bytes
+# 1m => 1000000 bytes
+# 1mb => 1024*1024 bytes
+# 1g => 1000000000 bytes
+# 1gb => 1024*1024*1024 bytes
+#
+# units are case insensitive so 1GB 1Gb 1gB are all the same.
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here.  This is useful if you
+# have a standard template that goes to all Redis servers but also need
+# to customize a few per-server settings.  Include files can include
+# other files, so use this wisely.
+#
+# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
+# from admin or Redis Sentinel. Since Redis always uses the last processed
+# line as value of a configuration directive, you'd better put includes
+# at the beginning of this file to avoid overwriting config change at runtime.
+#
+# If instead you are interested in using includes to override configuration
+# options, it is better to use include as the last line.
+#
+# include /path/to/local.conf
+# include /path/to/other.conf
+
+################################ GENERAL  #####################################
+
+# By default Redis does not run as a daemon. Use 'yes' if you need it.
+# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
+daemonize yes
+
+# When running daemonized, Redis writes a pid file in /var/run/redis.pid by
+# default. You can specify a custom pid file location here.
+pidfile /var/run/redis.pid
+
+# Accept connections on the specified port, default is 6379.
+# If port 0 is specified Redis will not listen on a TCP socket.
+port 6380
+
+# TCP listen() backlog.
+#
+# In high requests-per-second environments you need an high backlog in order
+# to avoid slow clients connections issues. Note that the Linux kernel
+# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
+# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
+# in order to get the desired effect.
+tcp-backlog 511
+
+# By default Redis listens for connections from all the network interfaces
+# available on the server. It is possible to listen to just one or multiple
+# interfaces using the "bind" configuration directive, followed by one or
+# more IP addresses.
+#
+# Examples:
+#
+# bind 192.168.1.100 10.0.0.1
+bind 0.0.0.0
+
+# Specify the path for the Unix socket that will be used to listen for
+# incoming connections. There is no default, so Redis will not listen
+# on a unix socket when not specified.
+#
+# unixsocket /tmp/redis.sock
+# unixsocketperm 700
+
+# Close the connection after a client is idle for N seconds (0 to disable)
+timeout 0
+
+# TCP keepalive.
+#
+# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
+# of communication. This is useful for two reasons:
+#
+# 1) Detect dead peers.
+# 2) Take the connection alive from the point of view of network
+#    equipment in the middle.
+#
+# On Linux, the specified value (in seconds) is the period used to send ACKs.
+# Note that to close the connection the double of the time is needed.
+# On other kernels the period depends on the kernel configuration.
+#
+# A reasonable value for this option is 60 seconds.
+tcp-keepalive 0
+
+# Specify the server verbosity level.
+# This can be one of:
+# debug (a lot of information, useful for development/testing)
+# verbose (many rarely useful info, but not a mess like the debug level)
+# notice (moderately verbose, what you want in production probably)
+# warning (only very important / critical messages are logged)
+loglevel notice
+
+# Specify the log file name. Also the empty string can be used to force
+# Redis to log on the standard output. Note that if you use standard
+# output for logging but daemonize, logs will be sent to /dev/null
+logfile /var/redis/redis-6380.log
+
+# To enable logging to the system logger, just set 'syslog-enabled' to yes,
+# and optionally update the other syslog parameters to suit your needs.
+# syslog-enabled no
+
+# Specify the syslog identity.
+# syslog-ident redis
+
+# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
+# syslog-facility local0
+
+# Set the number of databases. The default database is DB 0, you can select
+# a different one on a per-connection basis using SELECT <dbid> where
+# dbid is a number between 0 and 'databases'-1
+databases 16
+
+################################ SNAPSHOTTING  ################################
+#
+# Save the DB on disk:
+#
+#   save <seconds> <changes>
+#
+#   Will save the DB if both the given number of seconds and the given
+#   number of write operations against the DB occurred.
+#
+#   In the example below the behaviour will be to save:
+#   after 900 sec (15 min) if at least 1 key changed
+#   after 300 sec (5 min) if at least 10 keys changed
+#   after 60 sec if at least 10000 keys changed
+#
+#   Note: you can disable saving completely by commenting out all "save" lines.
+#
+#   It is also possible to remove all the previously configured save
+#   points by adding a save directive with a single empty string argument
+#   like in the following example:
+#
+#   save ""
+
+save 900 1
+save 300 10
+save 60 10000
+
+# By default Redis will stop accepting writes if RDB snapshots are enabled
+# (at least one save point) and the latest background save failed.
+# This will make the user aware (in a hard way) that data is not persisting
+# on disk properly, otherwise chances are that no one will notice and some
+# disaster will happen.
+#
+# If the background saving process will start working again Redis will
+# automatically allow writes again.
+#
+# However if you have setup your proper monitoring of the Redis server
+# and persistence, you may want to disable this feature so that Redis will
+# continue to work as usual even if there are problems with disk,
+# permissions, and so forth.
+stop-writes-on-bgsave-error yes
+
+# Compress string objects using LZF when dump .rdb databases?
+# For default that's set to 'yes' as it's almost always a win.
+# If you want to save some CPU in the saving child set it to 'no' but
+# the dataset will likely be bigger if you have compressible values or keys.
+rdbcompression yes
+
+# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
+# This makes the format more resistant to corruption but there is a performance
+# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
+# for maximum performances.
+#
+# RDB files created with checksum disabled have a checksum of zero that will
+# tell the loading code to skip the check.
+rdbchecksum yes
+
+# The filename where to dump the DB
+dbfilename dump.rdb
+
+# The working directory.
+#
+# The DB will be written inside this directory, with the filename specified
+# above using the 'dbfilename' configuration directive.
+#
+# The Append Only File will also be created inside this directory.
+#
+# Note that you must specify a directory here, not a file name.
+dir /var/redis
+
+################################# REPLICATION #################################
+
+# Master-Slave replication. Use slaveof to make a Redis instance a copy of
+# another Redis server. A few things to understand ASAP about Redis replication.
+#
+# 1) Redis replication is asynchronous, but you can configure a master to
+#    stop accepting writes if it appears to be not connected with at least
+#    a given number of slaves.
+# 2) Redis slaves are able to perform a partial resynchronization with the
+#    master if the replication link is lost for a relatively small amount of
+#    time. You may want to configure the replication backlog size (see the next
+#    sections of this file) with a sensible value depending on your needs.
+# 3) Replication is automatic and does not need user intervention. After a
+#    network partition slaves automatically try to reconnect to masters
+#    and resynchronize with them.
+#
+# slaveof <masterip> <masterport>
+
+# If the master is password protected (using the "requirepass" configuration
+# directive below) it is possible to tell the slave to authenticate before
+# starting the replication synchronization process, otherwise the master will
+# refuse the slave request.
+#
+# masterauth <master-password>
+
+# When a slave loses its connection with the master, or when the replication
+# is still in progress, the slave can act in two different ways:
+#
+# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
+#    still reply to client requests, possibly with out of date data, or the
+#    data set may just be empty if this is the first synchronization.
+#
+# 2) if slave-serve-stale-data is set to 'no' the slave will reply with
+#    an error "SYNC with master in progress" to all the kind of commands
+#    but to INFO and SLAVEOF.
+#
+slave-serve-stale-data yes
+
+# You can configure a slave instance to accept writes or not. Writing against
+# a slave instance may be useful to store some ephemeral data (because data
+# written on a slave will be easily deleted after resync with the master) but
+# may also cause problems if clients are writing to it because of a
+# misconfiguration.
+#
+# Since Redis 2.6 by default slaves are read-only.
+#
+# Note: read only slaves are not designed to be exposed to untrusted clients
+# on the internet. It's just a protection layer against misuse of the instance.
+# Still a read only slave exports by default all the administrative commands
+# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
+# security of read only slaves using 'rename-command' to shadow all the
+# administrative / dangerous commands.
+slave-read-only yes
+
+# Replication SYNC strategy: disk or socket.
+#
+# -------------------------------------------------------
+# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY
+# -------------------------------------------------------
+#
+# New slaves and reconnecting slaves that are not able to continue the replication
+# process just receiving differences, need to do what is called a "full
+# synchronization". An RDB file is transmitted from the master to the slaves.
+# The transmission can happen in two different ways:
+#
+# 1) Disk-backed: The Redis master creates a new process that writes the RDB
+#                 file on disk. Later the file is transferred by the parent
+#                 process to the slaves incrementally.
+# 2) Diskless: The Redis master creates a new process that directly writes the
+#              RDB file to slave sockets, without touching the disk at all.
+#
+# With disk-backed replication, while the RDB file is generated, more slaves
+# can be queued and served with the RDB file as soon as the current child producing
+# the RDB file finishes its work. With diskless replication instead once
+# the transfer starts, new slaves arriving will be queued and a new transfer
+# will start when the current one terminates.
+#
+# When diskless replication is used, the master waits a configurable amount of
+# time (in seconds) before starting the transfer in the hope that multiple slaves
+# will arrive and the transfer can be parallelized.
+#
+# With slow disks and fast (large bandwidth) networks, diskless replication
+# works better.
+repl-diskless-sync no
+
+# When diskless replication is enabled, it is possible to configure the delay
+# the server waits in order to spawn the child that transfers the RDB via socket
+# to the slaves.
+#
+# This is important since once the transfer starts, it is not possible to serve
+# new slaves arriving, that will be queued for the next RDB transfer, so the server
+# waits a delay in order to let more slaves arrive.
+#
+# The delay is specified in seconds, and by default is 5 seconds. To disable
+# it entirely just set it to 0 seconds and the transfer will start ASAP.
+repl-diskless-sync-delay 5
+
+# Slaves send PINGs to server in a predefined interval. It's possible to change
+# this interval with the repl_ping_slave_period option. The default value is 10
+# seconds.
+#
+# repl-ping-slave-period 10
+
+# The following option sets the replication timeout for:
+#
+# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
+# 2) Master timeout from the point of view of slaves (data, pings).
+# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
+#
+# It is important to make sure that this value is greater than the value
+# specified for repl-ping-slave-period otherwise a timeout will be detected
+# every time there is low traffic between the master and the slave.
+#
+# repl-timeout 60
+
+# Disable TCP_NODELAY on the slave socket after SYNC?
+#
+# If you select "yes" Redis will use a smaller number of TCP packets and
+# less bandwidth to send data to slaves. But this can add a delay for
+# the data to appear on the slave side, up to 40 milliseconds with
+# Linux kernels using a default configuration.
+#
+# If you select "no" the delay for data to appear on the slave side will
+# be reduced but more bandwidth will be used for replication.
+#
+# By default we optimize for low latency, but in very high traffic conditions
+# or when the master and slaves are many hops away, turning this to "yes" may
+# be a good idea.
+repl-disable-tcp-nodelay no
+
+# Set the replication backlog size. The backlog is a buffer that accumulates
+# slave data when slaves are disconnected for some time, so that when a slave
+# wants to reconnect again, often a full resync is not needed, but a partial
+# resync is enough, just passing the portion of data the slave missed while
+# disconnected.
+#
+# The bigger the replication backlog, the longer the time the slave can be
+# disconnected and later be able to perform a partial resynchronization.
+#
+# The backlog is only allocated once there is at least a slave connected.
+#
+# repl-backlog-size 1mb
+
+# After a master has no longer connected slaves for some time, the backlog
+# will be freed. The following option configures the amount of seconds that
+# need to elapse, starting from the time the last slave disconnected, for
+# the backlog buffer to be freed.
+#
+# A value of 0 means to never release the backlog.
+#
+# repl-backlog-ttl 3600
+
+# The slave priority is an integer number published by Redis in the INFO output.
+# It is used by Redis Sentinel in order to select a slave to promote into a
+# master if the master is no longer working correctly.
+#
+# A slave with a low priority number is considered better for promotion, so
+# for instance if there are three slaves with priority 10, 100, 25 Sentinel will
+# pick the one with priority 10, that is the lowest.
+#
+# However a special priority of 0 marks the slave as not able to perform the
+# role of master, so a slave with priority of 0 will never be selected by
+# Redis Sentinel for promotion.
+#
+# By default the priority is 100.
+slave-priority 100
+
+# It is possible for a master to stop accepting writes if there are less than
+# N slaves connected, having a lag less or equal than M seconds.
+#
+# The N slaves need to be in "online" state.
+#
+# The lag in seconds, that must be <= the specified value, is calculated from
+# the last ping received from the slave, that is usually sent every second.
+#
+# This option does not GUARANTEE that N replicas will accept the write, but
+# will limit the window of exposure for lost writes in case not enough slaves
+# are available, to the specified number of seconds.
+#
+# For example to require at least 3 slaves with a lag <= 10 seconds use:
+#
+# min-slaves-to-write 3
+# min-slaves-max-lag 10
+#
+# Setting one or the other to 0 disables the feature.
+#
+# By default min-slaves-to-write is set to 0 (feature disabled) and
+# min-slaves-max-lag is set to 10.
+
+################################## SECURITY ###################################
+
+# Require clients to issue AUTH <PASSWORD> before processing any other
+# commands.  This might be useful in environments in which you do not trust
+# others with access to the host running redis-server.
+#
+# This should stay commented out for backward compatibility and because most
+# people do not need auth (e.g. they run their own servers).
+#
+# Warning: since Redis is pretty fast an outside user can try up to
+# 150k passwords per second against a good box. This means that you should
+# use a very strong password otherwise it will be very easy to break.
+#
+# requirepass foobared
+
+# Command renaming.
+#
+# It is possible to change the name of dangerous commands in a shared
+# environment. For instance the CONFIG command may be renamed into something
+# hard to guess so that it will still be available for internal-use tools
+# but not available for general clients.
+#
+# Example:
+#
+# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
+#
+# It is also possible to completely kill a command by renaming it into
+# an empty string:
+#
+# rename-command CONFIG ""
+#
+# Please note that changing the name of commands that are logged into the
+# AOF file or transmitted to slaves may cause problems.
+
+################################### LIMITS ####################################
+
+# Set the max number of connected clients at the same time. By default
+# this limit is set to 10000 clients, however if the Redis server is not
+# able to configure the process file limit to allow for the specified limit
+# the max number of allowed clients is set to the current file limit
+# minus 32 (as Redis reserves a few file descriptors for internal uses).
+#
+# Once the limit is reached Redis will close all the new connections sending
+# an error 'max number of clients reached'.
+#
+# maxclients 10000
+
+# Don't use more memory than the specified amount of bytes.
+# When the memory limit is reached Redis will try to remove keys
+# according to the eviction policy selected (see maxmemory-policy).
+#
+# If Redis can't remove keys according to the policy, or if the policy is
+# set to 'noeviction', Redis will start to reply with errors to commands
+# that would use more memory, like SET, LPUSH, and so on, and will continue
+# to reply to read-only commands like GET.
+#
+# This option is usually useful when using Redis as an LRU cache, or to set
+# a hard memory limit for an instance (using the 'noeviction' policy).
+#
+# WARNING: If you have slaves attached to an instance with maxmemory on,
+# the size of the output buffers needed to feed the slaves are subtracted
+# from the used memory count, so that network problems / resyncs will
+# not trigger a loop where keys are evicted, and in turn the output
+# buffer of slaves is full with DELs of keys evicted triggering the deletion
+# of more keys, and so forth until the database is completely emptied.
+#
+# In short... if you have slaves attached it is suggested that you set a lower
+# limit for maxmemory so that there is some free RAM on the system for slave
+# output buffers (but this is not needed if the policy is 'noeviction').
+#
+# maxmemory <bytes>
+
+# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
+# is reached. You can select among five behaviors:
+#
+# volatile-lru -> remove the key with an expire set using an LRU algorithm
+# allkeys-lru -> remove any key according to the LRU algorithm
+# volatile-random -> remove a random key with an expire set
+# allkeys-random -> remove a random key, any key
+# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
+# noeviction -> don't expire at all, just return an error on write operations
+#
+# Note: with any of the above policies, Redis will return an error on write
+#       operations, when there are no suitable keys for eviction.
+#
+#       At the date of writing these commands are: set setnx setex append
+#       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
+#       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
+#       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
+#       getset mset msetnx exec sort
+#
+# The default is:
+#
+# maxmemory-policy noeviction
+
+# LRU and minimal TTL algorithms are not precise algorithms but approximated
+# algorithms (in order to save memory), so you can tune it for speed or
+# accuracy. For default Redis will check five keys and pick the one that was
+# used less recently, you can change the sample size using the following
+# configuration directive.
+#
+# The default of 5 produces good enough results. 10 Approximates very closely
+# true LRU but costs a bit more CPU. 3 is very fast but not very accurate.
+#
+# maxmemory-samples 5
+
+############################## APPEND ONLY MODE ###############################
+
+# By default Redis asynchronously dumps the dataset on disk. This mode is
+# good enough in many applications, but an issue with the Redis process or
+# a power outage may result into a few minutes of writes lost (depending on
+# the configured save points).
+#
+# The Append Only File is an alternative persistence mode that provides
+# much better durability. For instance using the default data fsync policy
+# (see later in the config file) Redis can lose just one second of writes in a
+# dramatic event like a server power outage, or a single write if something
+# wrong with the Redis process itself happens, but the operating system is
+# still running correctly.
+#
+# AOF and RDB persistence can be enabled at the same time without problems.
+# If the AOF is enabled on startup Redis will load the AOF, that is the file
+# with the better durability guarantees.
+#
+# Please check http://redis.io/topics/persistence for more information.
+
+appendonly no
+
+# The name of the append only file (default: "appendonly.aof")
+
+appendfilename "appendonly.aof"
+
+# The fsync() call tells the Operating System to actually write data on disk
+# instead of waiting for more data in the output buffer. Some OS will really flush
+# data on disk, some other OS will just try to do it ASAP.
+#
+# Redis supports three different modes:
+#
+# no: don't fsync, just let the OS flush the data when it wants. Faster.
+# always: fsync after every write to the append only log. Slow, Safest.
+# everysec: fsync only one time every second. Compromise.
+#
+# The default is "everysec", as that's usually the right compromise between
+# speed and data safety. It's up to you to understand if you can relax this to
+# "no" that will let the operating system flush the output buffer when
+# it wants, for better performances (but if you can live with the idea of
+# some data loss consider the default persistence mode that's snapshotting),
+# or on the contrary, use "always" that's very slow but a bit safer than
+# everysec.
+#
+# More details please check the following article:
+# http://antirez.com/post/redis-persistence-demystified.html
+#
+# If unsure, use "everysec".
+
+# appendfsync always
+appendfsync everysec
+# appendfsync no
+
+# When the AOF fsync policy is set to always or everysec, and a background
+# saving process (a background save or AOF log background rewriting) is
+# performing a lot of I/O against the disk, in some Linux configurations
+# Redis may block too long on the fsync() call. Note that there is no fix for
+# this currently, as even performing fsync in a different thread will block
+# our synchronous write(2) call.
+#
+# In order to mitigate this problem it's possible to use the following option
+# that will prevent fsync() from being called in the main process while a
+# BGSAVE or BGREWRITEAOF is in progress.
+#
+# This means that while another child is saving, the durability of Redis is
+# the same as "appendfsync none". In practical terms, this means that it is
+# possible to lose up to 30 seconds of log in the worst scenario (with the
+# default Linux settings).
+#
+# If you have latency problems turn this to "yes". Otherwise leave it as
+# "no" that is the safest pick from the point of view of durability.
+
+no-appendfsync-on-rewrite no
+
+# Automatic rewrite of the append only file.
+# Redis is able to automatically rewrite the log file implicitly calling
+# BGREWRITEAOF when the AOF log size grows by the specified percentage.
+#
+# This is how it works: Redis remembers the size of the AOF file after the
+# latest rewrite (if no rewrite has happened since the restart, the size of
+# the AOF at startup is used).
+#
+# This base size is compared to the current size. If the current size is
+# bigger than the specified percentage, the rewrite is triggered. Also
+# you need to specify a minimal size for the AOF file to be rewritten, this
+# is useful to avoid rewriting the AOF file even if the percentage increase
+# is reached but it is still pretty small.
+#
+# Specify a percentage of zero in order to disable the automatic AOF
+# rewrite feature.
+
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+
+# An AOF file may be found to be truncated at the end during the Redis
+# startup process, when the AOF data gets loaded back into memory.
+# This may happen when the system where Redis is running
+# crashes, especially when an ext4 filesystem is mounted without the
+# data=ordered option (however this can't happen when Redis itself
+# crashes or aborts but the operating system still works correctly).
+#
+# Redis can either exit with an error when this happens, or load as much
+# data as possible (the default now) and start if the AOF file is found
+# to be truncated at the end. The following option controls this behavior.
+#
+# If aof-load-truncated is set to yes, a truncated AOF file is loaded and
+# the Redis server starts emitting a log to inform the user of the event.
+# Otherwise if the option is set to no, the server aborts with an error
+# and refuses to start. When the option is set to no, the user requires
+# to fix the AOF file using the "redis-check-aof" utility before to restart
+# the server.
+#
+# Note that if the AOF file will be found to be corrupted in the middle
+# the server will still exit with an error. This option only applies when
+# Redis will try to read more data from the AOF file but not enough bytes
+# will be found.
+aof-load-truncated yes
+
+################################ LUA SCRIPTING  ###############################
+
+# Max execution time of a Lua script in milliseconds.
+#
+# If the maximum execution time is reached Redis will log that a script is
+# still in execution after the maximum allowed time and will start to
+# reply to queries with an error.
+#
+# When a long running script exceeds the maximum execution time only the
+# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be
+# used to stop a script that did not yet called write commands. The second
+# is the only way to shut down the server in the case a write command was
+# already issued by the script but the user doesn't want to wait for the natural
+# termination of the script.
+#
+# Set it to 0 or a negative value for unlimited execution without warnings.
+lua-time-limit 5000
+
+################################ REDIS CLUSTER  ###############################
+#
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however
+# in order to mark it as "mature" we need to wait for a non trivial percentage
+# of users to deploy it in production.
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
+# started as cluster nodes can. In order to start a Redis instance as a
+# cluster node enable the cluster support uncommenting the following:
+#
+# cluster-enabled yes
+
+# Every cluster node has a cluster configuration file. This file is not
+# intended to be edited by hand. It is created and updated by Redis nodes.
+# Every Redis Cluster node requires a different cluster configuration file.
+# Make sure that instances running in the same system do not have
+# overlapping cluster configuration file names.
+#
+# cluster-config-file nodes-6379.conf
+
+# Cluster node timeout is the amount of milliseconds a node must be unreachable
+# for it to be considered in failure state.
+# Most other internal time limits are multiple of the node timeout.
+#
+# cluster-node-timeout 15000
+
+# A slave of a failing master will avoid to start a failover if its data
+# looks too old.
+#
+# There is no simple way for a slave to actually have a exact measure of
+# its "data age", so the following two checks are performed:
+#
+# 1) If there are multiple slaves able to failover, they exchange messages
+#    in order to try to give an advantage to the slave with the best
+#    replication offset (more data from the master processed).
+#    Slaves will try to get their rank by offset, and apply to the start
+#    of the failover a delay proportional to their rank.
+#
+# 2) Every single slave computes the time of the last interaction with
+#    its master. This can be the last ping or command received (if the master
+#    is still in the "connected" state), or the time that elapsed since the
+#    disconnection with the master (if the replication link is currently down).
+#    If the last interaction is too old, the slave will not try to failover
+#    at all.
+#
+# The point "2" can be tuned by user. Specifically a slave will not perform
+# the failover if, since the last interaction with the master, the time
+# elapsed is greater than:
+#
+#   (node-timeout * slave-validity-factor) + repl-ping-slave-period
+#
+# So for example if node-timeout is 30 seconds, and the slave-validity-factor
+# is 10, and assuming a default repl-ping-slave-period of 10 seconds, the
+# slave will not try to failover if it was not able to talk with the master
+# for longer than 310 seconds.
+#
+# A large slave-validity-factor may allow slaves with too old data to failover
+# a master, while a too small value may prevent the cluster from being able to
+# elect a slave at all.
+#
+# For maximum availability, it is possible to set the slave-validity-factor
+# to a value of 0, which means, that slaves will always try to failover the
+# master regardless of the last time they interacted with the master.
+# (However they'll always try to apply a delay proportional to their
+# offset rank).
+#
+# Zero is the only value able to guarantee that when all the partitions heal
+# the cluster will always be able to continue.
+#
+# cluster-slave-validity-factor 10
+
+# Cluster slaves are able to migrate to orphaned masters, that are masters
+# that are left without working slaves. This improves the cluster ability
+# to resist to failures as otherwise an orphaned master can't be failed over
+# in case of failure if it has no working slaves.
+#
+# Slaves migrate to orphaned masters only if there are still at least a
+# given number of other working slaves for their old master. This number
+# is the "migration barrier". A migration barrier of 1 means that a slave
+# will migrate only if there is at least 1 other working slave for its master
+# and so forth. It usually reflects the number of slaves you want for every
+# master in your cluster.
+#
+# Default is 1 (slaves migrate only if their masters remain with at least
+# one slave). To disable migration just set it to a very large value.
+# A value of 0 can be set but is useful only for debugging and dangerous
+# in production.
+#
+# cluster-migration-barrier 1
+
+# By default Redis Cluster nodes stop accepting queries if they detect there
+# is at least an hash slot uncovered (no available node is serving it).
+# This way if the cluster is partially down (for example a range of hash slots
+# are no longer covered) all the cluster becomes, eventually, unavailable.
+# It automatically returns available as soon as all the slots are covered again.
+#
+# However sometimes you want the subset of the cluster which is working,
+# to continue to accept queries for the part of the key space that is still
+# covered. In order to do so, just set the cluster-require-full-coverage
+# option to no.
+#
+# cluster-require-full-coverage yes
+
+# In order to setup your cluster make sure to read the documentation
+# available at http://redis.io web site.
+
+################################## SLOW LOG ###################################
+
+# The Redis Slow Log is a system to log queries that exceeded a specified
+# execution time. The execution time does not include the I/O operations
+# like talking with the client, sending the reply and so forth,
+# but just the time needed to actually execute the command (this is the only
+# stage of command execution where the thread is blocked and can not serve
+# other requests in the meantime).
+#
+# You can configure the slow log with two parameters: one tells Redis
+# what is the execution time, in microseconds, to exceed in order for the
+# command to get logged, and the other parameter is the length of the
+# slow log. When a new command is logged the oldest one is removed from the
+# queue of logged commands.
+
+# The following time is expressed in microseconds, so 1000000 is equivalent
+# to one second. Note that a negative number disables the slow log, while
+# a value of zero forces the logging of every command.
+slowlog-log-slower-than 10000
+
+# There is no limit to this length. Just be aware that it will consume memory.
+# You can reclaim memory used by the slow log with SLOWLOG RESET.
+slowlog-max-len 128
+
+################################ LATENCY MONITOR ##############################
+
+# The Redis latency monitoring subsystem samples different operations
+# at runtime in order to collect data related to possible sources of
+# latency of a Redis instance.
+#
+# Via the LATENCY command this information is available to the user that can
+# print graphs and obtain reports.
+#
+# The system only logs operations that were performed in a time equal or
+# greater than the amount of milliseconds specified via the
+# latency-monitor-threshold configuration directive. When its value is set
+# to zero, the latency monitor is turned off.
+#
+# By default latency monitoring is disabled since it is mostly not needed
+# if you don't have latency issues, and collecting data has a performance
+# impact, that while very small, can be measured under big load. Latency
+# monitoring can easily be enabled at runtime using the command
+# "CONFIG SET latency-monitor-threshold <milliseconds>" if needed.
+latency-monitor-threshold 0
+
+############################# EVENT NOTIFICATION ##############################
+
+# Redis can notify Pub/Sub clients about events happening in the key space.
+# This feature is documented at http://redis.io/topics/notifications
+#
+# For instance if keyspace events notification is enabled, and a client
+# performs a DEL operation on key "foo" stored in the Database 0, two
+# messages will be published via Pub/Sub:
+#
+# PUBLISH __keyspace@0__:foo del
+# PUBLISH __keyevent@0__:del foo
+#
+# It is possible to select the events that Redis will notify among a set
+# of classes. Every class is identified by a single character:
+#
+#  K     Keyspace events, published with __keyspace@<db>__ prefix.
+#  E     Keyevent events, published with __keyevent@<db>__ prefix.
+#  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
+#  $     String commands
+#  l     List commands
+#  s     Set commands
+#  h     Hash commands
+#  z     Sorted set commands
+#  x     Expired events (events generated every time a key expires)
+#  e     Evicted events (events generated when a key is evicted for maxmemory)
+#  A     Alias for g$lshzxe, so that the "AKE" string means all the events.
+#
+#  The "notify-keyspace-events" takes as argument a string that is composed
+#  of zero or multiple characters. The empty string means that notifications
+#  are disabled.
+#
+#  Example: to enable list and generic events, from the point of view of the
+#           event name, use:
+#
+#  notify-keyspace-events Elg
+#
+#  Example 2: to get the stream of the expired keys subscribing to channel
+#             name __keyevent@0__:expired use:
+#
+#  notify-keyspace-events Ex
+#
+#  By default all notifications are disabled because most users don't need
+#  this feature and the feature has some overhead. Note that if you don't
+#  specify at least one of K or E, no events will be delivered.
+notify-keyspace-events Ex
+
+############################### ADVANCED CONFIG ###############################
+
+# Hashes are encoded using a memory efficient data structure when they have a
+# small number of entries, and the biggest entry does not exceed a given
+# threshold. These thresholds can be configured using the following directives.
+hash-max-ziplist-entries 512
+hash-max-ziplist-value 64
+
+# Similarly to hashes, small lists are also encoded in a special way in order
+# to save a lot of space. The special representation is only used when
+# you are under the following limits:
+list-max-ziplist-entries 512
+list-max-ziplist-value 64
+
+# Sets have a special encoding in just one case: when a set is composed
+# of just strings that happen to be integers in radix 10 in the range
+# of 64 bit signed integers.
+# The following configuration setting sets the limit in the size of the
+# set in order to use this special memory saving encoding.
+set-max-intset-entries 512
+
+# Similarly to hashes and lists, sorted sets are also specially encoded in
+# order to save a lot of space. This encoding is only used when the length and
+# elements of a sorted set are below the following limits:
+zset-max-ziplist-entries 128
+zset-max-ziplist-value 64
+
+# HyperLogLog sparse representation bytes limit. The limit includes the
+# 16 bytes header. When an HyperLogLog using the sparse representation crosses
+# this limit, it is converted into the dense representation.
+#
+# A value greater than 16000 is totally useless, since at that point the
+# dense representation is more memory efficient.
+#
+# The suggested value is ~ 3000 in order to have the benefits of
+# the space efficient encoding without slowing down too much PFADD,
+# which is O(N) with the sparse encoding. The value can be raised to
+# ~ 10000 when CPU is not a concern, but space is, and the data set is
+# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
+hll-sparse-max-bytes 3000
+
+# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
+# order to help rehashing the main Redis hash table (the one mapping top-level
+# keys to values). The hash table implementation Redis uses (see dict.c)
+# performs a lazy rehashing: the more operation you run into a hash table
+# that is rehashing, the more rehashing "steps" are performed, so if the
+# server is idle the rehashing is never complete and some more memory is used
+# by the hash table.
+#
+# The default is to use this millisecond 10 times every second in order to
+# actively rehash the main dictionaries, freeing memory when possible.
+#
+# If unsure:
+# use "activerehashing no" if you have hard latency requirements and it is
+# not a good thing in your environment that Redis can reply from time to time
+# to queries with 2 milliseconds delay.
+#
+# use "activerehashing yes" if you don't have such hard requirements but
+# want to free memory asap when possible.
+activerehashing yes
+
+# The client output buffer limits can be used to force disconnection of clients
+# that are not reading data from the server fast enough for some reason (a
+# common reason is that a Pub/Sub client can't consume messages as fast as the
+# publisher can produce them).
+#
+# The limit can be set differently for the three different classes of clients:
+#
+# normal -> normal clients including MONITOR clients
+# slave  -> slave clients
+# pubsub -> clients subscribed to at least one pubsub channel or pattern
+#
+# The syntax of every client-output-buffer-limit directive is the following:
+#
+# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
+#
+# A client is immediately disconnected once the hard limit is reached, or if
+# the soft limit is reached and remains reached for the specified number of
+# seconds (continuously).
+# So for instance if the hard limit is 32 megabytes and the soft limit is
+# 16 megabytes / 10 seconds, the client will get disconnected immediately
+# if the size of the output buffers reach 32 megabytes, but will also get
+# disconnected if the client reaches 16 megabytes and continuously overcomes
+# the limit for 10 seconds.
+#
+# By default normal clients are not limited because they don't receive data
+# without asking (in a push way), but just after a request, so only
+# asynchronous clients may create a scenario where data is requested faster
+# than it can read.
+#
+# Instead there is a default limit for pubsub and slave clients, since
+# subscribers and slaves receive data in a push fashion.
+#
+# Both the hard or the soft limit can be disabled by setting them to zero.
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit slave 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+
+# Redis calls an internal function to perform many background tasks, like
+# closing connections of clients in timeout, purging expired keys that are
+# never requested, and so forth.
+#
+# Not all tasks are performed with the same frequency, but Redis checks for
+# tasks to perform according to the specified "hz" value.
+#
+# By default "hz" is set to 10. Raising the value will use more CPU when
+# Redis is idle, but at the same time will make Redis more responsive when
+# there are many keys expiring at the same time, and timeouts may be
+# handled with more precision.
+#
+# The range is between 1 and 500, however a value over 100 is usually not
+# a good idea. Most users should use the default of 10 and raise this up to
+# 100 only in environments where very low latency is required.
+hz 10
+
+# When a child rewrites the AOF file, if the following option is enabled
+# the file will be fsync-ed every 32 MB of data generated. This is useful
+# in order to commit the file to the disk more incrementally and avoid
+# big latency spikes.
+aof-rewrite-incremental-fsync yes

+ 47 - 0
docker/compose/xyz/stat/docker-compose.yml

@@ -0,0 +1,47 @@
+version: "3.7"
+
+services:
+  readersrv:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-reader"
+    command: ['python','reader.py', '-h', '172.26.105.125', '-p', '6379']
+
+  mchreadersrv:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-mchreader"
+    command: ['python','mchreader.py', '-h', '172.26.105.125', '-p', '6379']
+
+  ratiosrv:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - /mnt/shoplog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-ratio"
+    command: ['python','ratio.py', '-h', '172.26.105.125', '-p', '6379']
+
+  flasksrv:
+    image: pycpu:3.7.10
+    ports:
+      - "5000:5000"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-flask"
+    command: ['python','app.py']

+ 36 - 0
docker/compose/xyz/storage/docker-compose.yml

@@ -0,0 +1,36 @@
+version: "3.7"
+
+services:
+  redisrv:
+    image: redis:alpine
+    ports:
+      - "6379:6379"
+    volumes:
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/redis/6379.conf:/etc/redis/redis.conf
+      - /mnt/redisdata:/data
+    container_name: "panda-redis"
+    command: [redis-server,"/etc/redis/redis.conf"]
+
+  crontabsrv:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - ../conf/crontab/root:/var/spool/cron/crontabs/root
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "panda-crontab"
+    command: [crond,"-f"]
+
+  cronsec:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "panda-cronsec"
+    command: [php,"/var/www/html/crontab/index.php",'minutes','second_queue']

+ 0 - 130
docker/compose/xyzt-acc/docker-compose.yml

@@ -1,130 +0,0 @@
-version: "3.7"
-
-services:
-  nginxsrv:
-    image: nginx:alpine
-    ports:
-      - "8080:80"
-    volumes:
-      - ../../../:/var/www/html
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - /nfs/upload:/var/www/html/data/upload
-      - /nfs/tmerchant:/var/www/html/merchant
-      - ../../conf/nginx/nginx-xyztest-http.conf:/etc/nginx/nginx.conf:ro
-    container_name: "panda-nginx"
-    command: [nginx,'-g','daemon off;']
-    extra_hosts:
-      - "docker.hostip:172.17.0.1"
-      - "eth.hostip:172.26.105.127"
-
-  redisrv:
-    image: redis:alpine
-    ports:
-      - "6379:6379"
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../conf/redis/6379.conf:/etc/redis/redis.conf
-      - /mnt/redisdata:/data
-    container_name: "panda-redis"
-    command: [redis-server,"/etc/redis/redis.conf"]
-
-  mobilesrv:
-    image: php-zts:7.3.18
-    ports:
-      - "9100:9100"
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/mobile-spwan-start:/usr/local/bin/docker-spwan-start
-    container_name: "panda-mobile"
-    command: ['docker-spwan-start']
-    depends_on:
-      - "redisrv"
-
-  raccsrv:
-    image: php-zts:7.3.18
-    ports:
-      - "9101:9101"
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/racc-spwan-start-lz:/usr/local/bin/docker-spwan-start
-    container_name: "panda-racc"
-    command: [docker-spwan-start]
-    depends_on:
-      - "redisrv"
-
-  mchsrv:
-    image: php-zts:7.3.18
-    ports:
-      - "9102:9102"
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/mch-spwan-start-lz:/usr/local/bin/docker-spwan-start
-    container_name: "panda-merchant"
-    command: [docker-spwan-start]
-    depends_on:
-       - "redisrv"
-
-  websrv:
-    image: php-fpm:alpine
-    ports:
-      - "9000:9000"
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-      - ../../conf/php-fpm/php-fpm.conf:/usr/local/etc/php-fpm.conf
-    container_name: "panda-web"
-    command: [php-fpm]
-    depends_on:
-      - "redisrv"
-
-  crontabsrv:
-    image: php-zts-debug:7.3.18
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-      - ../../conf/crontab/root:/var/spool/cron/crontabs/root
-    container_name: "panda-crontab"
-    command: [crond,"-f"]
-    depends_on:
-      - "redisrv"
-
-  cronsec:
-    image: php-zts-debug:7.3.18
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-    container_name: "panda-cronsec"
-    command: [php,"/var/www/html/crontab/index.php",'minutes','second_queue']
-
-  phpcli:
-    image: php-zts-debug:7.3.18
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-      - ../../../:/var/www/html
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-    container_name: "panda-php"
-    depends_on:
-      - "redisrv"

+ 0 - 39
docker/compose/xyzt-worker/docker-compose.yml

@@ -1,39 +0,0 @@
-version: "3.7"
-
-services:
-  cordsrv:
-    image: php-swool-redis:latest
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/xyzt-php-swoole.ini:/usr/local/etc/php/php.ini
-    container_name: "worker-codispatcher"
-    command: [php,"/var/www/html/rdispatcher/codispatcher.php","16"]
-    deploy:
-      resources:
-        limits:
-          cpus: '8'
-
-  queuesrv:
-    image: php-zts-debug:7.3.18
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-    container_name: "worker-queue"
-    command: [php,"/var/www/html/queue/index.php", "queue", "index"]
-
-  searcher:
-    image: php-zts-debug:7.3.18
-    volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
-      - /nfs/upload:/var/www/html/data/upload
-      - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/xyzt-175-php.ini:/usr/local/etc/php/php.ini
-    container_name: "worker-searcher"
-    command: [php, "/var/www/html/searcher.php"]

+ 30 - 0
docker/compose/xyzt/admin/docker-compose.yml

@@ -0,0 +1,30 @@
+version: "3.7"
+
+services:
+  mchsrv:
+    image: php-zts:7.3.18
+    ports:
+      - "9102:9102"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - ../conf/php/mch-spwan-start:/usr/local/bin/docker-spwan-start
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+    container_name: "panda-merchant"
+    command: [docker-spwan-start]
+
+  websrv:
+    image: php-fpm:alpine
+    ports:
+      - "9000:9000"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - ../conf/php-fpm/php-fpm.conf:/usr/local/etc/php-fpm.conf
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+    container_name: "panda-web"
+    command: [php-fpm]

+ 78 - 0
docker/compose/xyzt/arw/docker-compose.yml

@@ -0,0 +1,78 @@
+version: "3.7"
+
+services:
+  nginxsrv:
+    image: nginx:alpine
+    ports:
+      - "8080:80"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /nfs/tmerchant:/var/www/html/merchant
+    container_name: "panda-nginx"
+    command: [nginx,'-g','daemon off;']
+    extra_hosts:
+      - "docker.hostip:172.17.0.1"
+
+  mobilesrv:
+    image: php-zts:7.3.18
+    ports:
+      - "9100:9100"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+      - ../conf/php/mobile-spwan-start:/usr/local/bin/docker-spwan-start
+    container_name: "panda-mobile"
+    command: ['docker-spwan-start']
+
+  cordsrv:
+    image: php-swool-redis:latest
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php-swoole.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+    container_name: "worker-codispatcher"
+    command: [php,"/var/www/html/rdispatcher/codispatcher.php","16"]
+    deploy:
+      resources:
+        limits:
+          cpus: '8'
+
+  queuesrv:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+    container_name: "worker-queue"
+    command: [php,"/var/www/html/queue/index.php", "queue", "index"]
+
+  searcher:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+    container_name: "worker-searcher"
+    command: [php, "/var/www/html/searcher.php"]
+
+  phpcli:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+    container_name: "panda-php"

+ 4 - 0
docker/compose/xyzt/arw/restart_all.sh

@@ -0,0 +1,4 @@
+docker-compose stop -t 1200 cordsrv
+docker-compose down
+docker-compose up -d
+docker-compose ps

+ 3 - 0
docker/compose/xyzt/arw/restart_cordsrv.sh

@@ -0,0 +1,3 @@
+docker-compose stop -t 1200 cordsrv
+docker-compose up -d cordsrv
+docker-compose ps

+ 3 - 0
docker/compose/xyzt/arw/stop_all.sh

@@ -0,0 +1,3 @@
+docker-compose stop -t 1200 cordsrv
+docker-compose down
+docker-compose ps

+ 18 - 0
docker/compose/xyzt/conf/crontab/root

@@ -0,0 +1,18 @@
+# do daily/weekly/monthly maintenance
+# min	hour	day	month	weekday	command
+*/15	*	*	*	*	run-parts /etc/periodic/15min
+0	*	*	*	*	run-parts /etc/periodic/hourly
+0	2	*	*	*	run-parts /etc/periodic/daily
+0	3	*	*	6	run-parts /etc/periodic/weekly
+0	5	1	*	*	run-parts /etc/periodic/monthly
+#0   3   *   *   *   php /var/www/html/crontab/index.php date index
+0   4   *   *   *   php /var/www/html/crontab/index.php date forth_clock
+#0   9   *   *   *   php /var/www/html/crontab/index.php date nine_clock
+#0   10  *   *   *   php /var/www/html/crontab/index.php date ten_clock
+*    *   *   *   *   php /var/www/html/crontab/index.php minutes index
+#0   10-20/1 *   *   *   php /var/www/html/crontab/index.php hour index
+#0   3   1   */1 *   php /var/www/html/crontab/index.php month index
+*    *   *   *   *   echo "test" >> /var/test.log
+
+#0   1   *   *   *   php /var/www/html/crontab/index.php date _order_stats
+

二進制
docker/compose/xyzt/conf/etc/localtime


+ 127 - 0
docker/compose/xyzt/conf/nginx/nginx.conf

@@ -0,0 +1,127 @@
+user nginx;
+worker_processes  8;
+error_log   /var/error.log  info;
+worker_rlimit_nofile 10240;
+
+events {
+    worker_connections  8192;
+    multi_accept on;
+    use epoll;
+}
+
+http 
+{
+    include       mime.types;
+    default_type  application/octet-stream;
+    fastcgi_buffer_size 32k;
+    fastcgi_buffers 8 32k;
+    underscores_in_headers on;
+    client_max_body_size 1024M;
+    tcp_nopush on;
+
+    sendfile            on;
+    keepalive_timeout   65;
+
+    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                      '$status $body_bytes_sent "$http_referer" '
+                      '"$http_user_agent" "$http_x_forwarded_for"';
+
+    server 
+    {
+    	listen       80;
+        set  $folder_name /var/www/html;
+        server_name test.xyzshops.cn;
+        root $folder_name;
+        index index.html index.php; 
+    	client_max_body_size 100m;
+    	proxy_connect_timeout 500s;
+        proxy_read_timeout 500s;
+        proxy_send_timeout 500s;
+        fastcgi_connect_timeout 75;
+        fastcgi_read_timeout 600;   
+        fastcgi_send_timeout 600;
+
+        set_real_ip_from 100.64.0.0/10;
+        real_ip_header X-Forwarded-For;
+
+        charset utf-8;
+        
+        location /logs {
+            deny all;
+            return 403;
+        }
+
+        location /data/log {
+            deny all;
+            return 403;
+        }
+        location / {
+            index  index.html index.htm index.php;
+        }
+        
+        location /mshop {
+            root $folder_name;
+            autoindex on;        
+            index  index.html index.htm index.php;
+	        try_files $uri $uri/ /mshop/index.html;
+        }
+
+        location /plot {
+            root $folder_name;
+            proxy_pass         http://docker.hostip:5000;
+            proxy_redirect     off;
+
+            proxy_set_header   Host                 $host;
+            proxy_set_header   X-Real-IP            $remote_addr;
+            proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
+            proxy_set_header   X-Forwarded-Proto    $scheme;
+        }
+
+        location /merchant {
+            root $folder_name;
+            autoindex on;
+            index  index.html index.htm index.php;
+            try_files $uri $uri/ /merchant/index.html;
+        }
+
+        location ~ /mobile/[/\w]+\.php$ {
+            root           $folder_name;
+            fastcgi_pass   docker.hostip:9100;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            fastcgi_param  SIGN $http_sign;
+            include fastcgi_params;
+        }
+
+        location ~ /mobile/[/\w]+\.html$ {
+            try_files $uri $uri/ /mobile/index.html;
+        }
+
+        location ~ /racc/[/\w]+\.php$ {
+            root           $folder_name;
+            fastcgi_pass   docker.hostip:9101;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            fastcgi_param  SIGN $http_sign;
+            include fastcgi_params;
+        }
+
+        location ~ /mchsrv/[/\w]+\.php$ {
+            root           $folder_name;
+            fastcgi_pass   172.26.105.127:9102;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            fastcgi_param SIGN $http_sign;
+            include fastcgi_params;
+        }
+
+        location ~ \.php$ {
+	        add_header Cache-Control no-store;
+            root           $folder_name;
+            fastcgi_pass   172.26.105.127:9000;
+            fastcgi_index  index.php;
+            fastcgi_param  SCRIPT_FILENAME  $folder_name$fastcgi_script_name;
+            include        fastcgi_params;
+        }
+    }
+}

+ 143 - 0
docker/compose/xyzt/conf/php-fpm/php-fpm.conf

@@ -0,0 +1,143 @@
+;;;;;;;;;;;;;;;;;;;;;
+; FPM Configuration ;
+;;;;;;;;;;;;;;;;;;;;;
+
+; All relative paths in this configuration file are relative to PHP's install
+; prefix (/usr/local). This prefix can be dynamically changed by using the
+; '-p' argument from the command line.
+
+;;;;;;;;;;;;;;;;;;
+; Global Options ;
+;;;;;;;;;;;;;;;;;;
+
+[global]
+; Pid file
+; Note: the default prefix is /usr/local/var
+; Default Value: none
+;pid = run/php-fpm.pid
+
+; Error log file
+; If it's set to "syslog", log is sent to syslogd instead of being written
+; into a local file.
+; Note: the default prefix is /usr/local/var
+; Default Value: log/php-fpm.log
+;error_log = log/php-fpm.log
+
+; syslog_facility is used to specify what type of program is logging the
+; message. This lets syslogd specify that messages from different facilities
+; will be handled differently.
+; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON)
+; Default Value: daemon
+;syslog.facility = daemon
+
+; syslog_ident is prepended to every message. If you have multiple FPM
+; instances running on the same server, you can change the default value
+; which must suit common needs.
+; Default Value: php-fpm
+;syslog.ident = php-fpm
+
+; Log level
+; Possible Values: alert, error, warning, notice, debug
+; Default Value: notice
+;log_level = notice
+
+; Log limit on number of characters in the single line (log entry). If the
+; line is over the limit, it is wrapped on multiple lines. The limit is for
+; all logged characters including message prefix and suffix if present. However
+; the new line character does not count into it as it is present only when
+; logging to a file descriptor. It means the new line character is not present
+; when logging to syslog.
+; Default Value: 1024
+;log_limit = 4096
+
+; Log buffering specifies if the log line is buffered which means that the
+; line is written in a single write operation. If the value is false, then the
+; data is written directly into the file descriptor. It is an experimental
+; option that can potentionaly improve logging performance and memory usage
+; for some heavy logging scenarios. This option is ignored if logging to syslog
+; as it has to be always buffered.
+; Default value: yes
+;log_buffering = no
+
+; If this number of child processes exit with SIGSEGV or SIGBUS within the time
+; interval set by emergency_restart_interval then FPM will restart. A value
+; of '0' means 'Off'.
+; Default Value: 0
+;emergency_restart_threshold = 0
+
+; Interval of time used by emergency_restart_interval to determine when
+; a graceful restart will be initiated.  This can be useful to work around
+; accidental corruptions in an accelerator's shared memory.
+; Available Units: s(econds), m(inutes), h(ours), or d(ays)
+; Default Unit: seconds
+; Default Value: 0
+;emergency_restart_interval = 0
+
+; Time limit for child processes to wait for a reaction on signals from master.
+; Available units: s(econds), m(inutes), h(ours), or d(ays)
+; Default Unit: seconds
+; Default Value: 0
+;process_control_timeout = 0
+
+; The maximum number of processes FPM will fork. This has been designed to control
+; the global number of processes when using dynamic PM within a lot of pools.
+; Use it with caution.
+; Note: A value of 0 indicates no limit
+; Default Value: 0
+; process.max = 128
+
+; Specify the nice(2) priority to apply to the master process (only if set)
+; The value can vary from -19 (highest priority) to 20 (lowest priority)
+; Note: - It will only work if the FPM master process is launched as root
+;       - The pool process will inherit the master process priority
+;         unless specified otherwise
+; Default Value: no set
+; process.priority = -19
+
+; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging.
+; Default Value: yes
+;daemonize = yes
+
+; Set open file descriptor rlimit for the master process.
+; Default Value: system defined value
+;rlimit_files = 1024
+
+; Set max core size rlimit for the master process.
+; Possible Values: 'unlimited' or an integer greater or equal to 0
+; Default Value: system defined value
+;rlimit_core = 0
+
+; Specify the event mechanism FPM will use. The following is available:
+; - select     (any POSIX os)
+; - poll       (any POSIX os)
+; - epoll      (linux >= 2.5.44)
+; - kqueue     (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0)
+; - /dev/poll  (Solaris >= 7)
+; - port       (Solaris >= 10)
+; Default Value: not set (auto detection)
+;events.mechanism = epoll
+
+; When FPM is built with systemd integration, specify the interval,
+; in seconds, between health report notification to systemd.
+; Set to 0 to disable.
+; Available Units: s(econds), m(inutes), h(ours)
+; Default Unit: seconds
+; Default value: 10
+;systemd_interval = 10
+
+;;;;;;;;;;;;;;;;;;;;
+; Pool Definitions ;
+;;;;;;;;;;;;;;;;;;;;
+
+; Multiple pools of child processes may be started with different listening
+; ports and different management options.  The name of the pool will be
+; used in logs and stats. There is no limitation on the number of pools which
+; FPM can handle. Your system will tell you anyway :)
+
+; Include one or more files. If glob(3) exists, it is used to include a bunch of
+; files from a glob(3) pattern. This directive can be used everywhere in the
+; file.
+; Relative path can also be used. They will be prefixed by:
+;  - the global prefix if it's been set (-p argument)
+;  - /usr/local otherwise
+include=etc/php-fpm.d/*.conf

+ 12 - 0
docker/compose/xyzt/conf/php/mch-spwan-start

@@ -0,0 +1,12 @@
+#!/bin/sh
+set -e
+spawn-fcgi -a 0.0.0.0 -p 9102 -F 1 -f "php /var/www/html/mchsrv/mchsrv_run.php"
+
+
+time=$(date "+%Y%m%d")
+
+if [ ! -f "/var/www/html/data/log/${time}-mchsrv.log" ]; then
+    touch "/var/www/html/data/log/${time}-mchsrv.log"
+fi
+
+tail -f "/var/www/html/data/log/${time}-mchsrv.log"

+ 11 - 0
docker/compose/xyzt/conf/php/mobile-spwan-start

@@ -0,0 +1,11 @@
+#!/bin/sh
+set -e
+spawn-fcgi -a 0.0.0.0 -p 9100 -F 20 -f "php /var/www/html/mobile/mobile_run.php"
+
+time=$(date "+%Y%m%d")
+
+if [ ! -f "/var/www/html/data/log/${time}-mobile.log" ]; then
+    touch "/var/www/html/data/log/${time}-mobile.log"
+fi
+
+tail -f "/var/www/html/data/log/${time}-mobile.log"

文件差異過大導致無法顯示
+ 1944 - 0
docker/compose/xyzt/conf/php/php-swoole.ini


文件差異過大導致無法顯示
+ 1942 - 0
docker/compose/xyzt/conf/php/php.ini


+ 944 - 0
docker/compose/xyzt/conf/redis/6379.conf

@@ -0,0 +1,944 @@
+## Generated by install_server.sh ##
+# Redis configuration file example.
+#
+# Note that in order to read the configuration file, Redis must be
+# started with the file path as first argument:
+#
+# ./redis-server /path/to/redis.conf
+
+# Note on units: when memory size is needed, it is possible to specify
+# it in the usual form of 1k 5GB 4M and so forth:
+#
+# 1k => 1000 bytes
+# 1kb => 1024 bytes
+# 1m => 1000000 bytes
+# 1mb => 1024*1024 bytes
+# 1g => 1000000000 bytes
+# 1gb => 1024*1024*1024 bytes
+#
+# units are case insensitive so 1GB 1Gb 1gB are all the same.
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here.  This is useful if you
+# have a standard template that goes to all Redis servers but also need
+# to customize a few per-server settings.  Include files can include
+# other files, so use this wisely.
+#
+# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
+# from admin or Redis Sentinel. Since Redis always uses the last processed
+# line as value of a configuration directive, you'd better put includes
+# at the beginning of this file to avoid overwriting config change at runtime.
+#
+# If instead you are interested in using includes to override configuration
+# options, it is better to use include as the last line.
+#
+# include /path/to/local.conf
+# include /path/to/other.conf
+
+################################ GENERAL  #####################################
+
+# By default Redis does not run as a daemon. Use 'yes' if you need it.
+# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
+daemonize no
+
+# When running daemonized, Redis writes a pid file in /var/run/redis.pid by
+# default. You can specify a custom pid file location here.
+pidfile /var/run/redis.pid
+
+# Accept connections on the specified port, default is 6379.
+# If port 0 is specified Redis will not listen on a TCP socket.
+port 6379
+
+# TCP listen() backlog.
+#
+# In high requests-per-second environments you need an high backlog in order
+# to avoid slow clients connections issues. Note that the Linux kernel
+# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
+# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
+# in order to get the desired effect.
+tcp-backlog 511
+
+# By default Redis listens for connections from all the network interfaces
+# available on the server. It is possible to listen to just one or multiple
+# interfaces using the "bind" configuration directive, followed by one or
+# more IP addresses.
+#
+# Examples:
+#
+# bind 192.168.1.100 10.0.0.1
+bind 0.0.0.0
+
+# Specify the path for the Unix socket that will be used to listen for
+# incoming connections. There is no default, so Redis will not listen
+# on a unix socket when not specified.
+#
+# unixsocket /tmp/redis.sock
+# unixsocketperm 700
+
+# Close the connection after a client is idle for N seconds (0 to disable)
+timeout 0
+
+# TCP keepalive.
+#
+# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
+# of communication. This is useful for two reasons:
+#
+# 1) Detect dead peers.
+# 2) Take the connection alive from the point of view of network
+#    equipment in the middle.
+#
+# On Linux, the specified value (in seconds) is the period used to send ACKs.
+# Note that to close the connection the double of the time is needed.
+# On other kernels the period depends on the kernel configuration.
+#
+# A reasonable value for this option is 60 seconds.
+tcp-keepalive 0
+
+# Specify the server verbosity level.
+# This can be one of:
+# debug (a lot of information, useful for development/testing)
+# verbose (many rarely useful info, but not a mess like the debug level)
+# notice (moderately verbose, what you want in production probably)
+# warning (only very important / critical messages are logged)
+loglevel notice
+
+# Specify the log file name. Also the empty string can be used to force
+# Redis to log on the standard output. Note that if you use standard
+# output for logging but daemonize, logs will be sent to /dev/null
+logfile redis.log
+
+# To enable logging to the system logger, just set 'syslog-enabled' to yes,
+# and optionally update the other syslog parameters to suit your needs.
+# syslog-enabled no
+
+# Specify the syslog identity.
+# syslog-ident redis
+
+# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
+# syslog-facility local0
+
+# Set the number of databases. The default database is DB 0, you can select
+# a different one on a per-connection basis using SELECT <dbid> where
+# dbid is a number between 0 and 'databases'-1
+databases 16
+
+################################ SNAPSHOTTING  ################################
+#
+# Save the DB on disk:
+#
+#   save <seconds> <changes>
+#
+#   Will save the DB if both the given number of seconds and the given
+#   number of write operations against the DB occurred.
+#
+#   In the example below the behaviour will be to save:
+#   after 900 sec (15 min) if at least 1 key changed
+#   after 300 sec (5 min) if at least 10 keys changed
+#   after 60 sec if at least 10000 keys changed
+#
+#   Note: you can disable saving completely by commenting out all "save" lines.
+#
+#   It is also possible to remove all the previously configured save
+#   points by adding a save directive with a single empty string argument
+#   like in the following example:
+#
+#   save ""
+
+save 900 1
+save 300 10
+save 60 10000
+
+# By default Redis will stop accepting writes if RDB snapshots are enabled
+# (at least one save point) and the latest background save failed.
+# This will make the user aware (in a hard way) that data is not persisting
+# on disk properly, otherwise chances are that no one will notice and some
+# disaster will happen.
+#
+# If the background saving process will start working again Redis will
+# automatically allow writes again.
+#
+# However if you have setup your proper monitoring of the Redis server
+# and persistence, you may want to disable this feature so that Redis will
+# continue to work as usual even if there are problems with disk,
+# permissions, and so forth.
+stop-writes-on-bgsave-error no
+
+# Compress string objects using LZF when dump .rdb databases?
+# For default that's set to 'yes' as it's almost always a win.
+# If you want to save some CPU in the saving child set it to 'no' but
+# the dataset will likely be bigger if you have compressible values or keys.
+rdbcompression yes
+
+# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
+# This makes the format more resistant to corruption but there is a performance
+# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
+# for maximum performances.
+#
+# RDB files created with checksum disabled have a checksum of zero that will
+# tell the loading code to skip the check.
+rdbchecksum yes
+
+# The filename where to dump the DB
+dbfilename dump.rdb
+
+# The working directory.
+#
+# The DB will be written inside this directory, with the filename specified
+# above using the 'dbfilename' configuration directive.
+#
+# The Append Only File will also be created inside this directory.
+#
+# Note that you must specify a directory here, not a file name.
+dir /data
+
+################################# REPLICATION #################################
+
+# Master-Slave replication. Use slaveof to make a Redis instance a copy of
+# another Redis server. A few things to understand ASAP about Redis replication.
+#
+# 1) Redis replication is asynchronous, but you can configure a master to
+#    stop accepting writes if it appears to be not connected with at least
+#    a given number of slaves.
+# 2) Redis slaves are able to perform a partial resynchronization with the
+#    master if the replication link is lost for a relatively small amount of
+#    time. You may want to configure the replication backlog size (see the next
+#    sections of this file) with a sensible value depending on your needs.
+# 3) Replication is automatic and does not need user intervention. After a
+#    network partition slaves automatically try to reconnect to masters
+#    and resynchronize with them.
+#
+# slaveof <masterip> <masterport>
+
+# If the master is password protected (using the "requirepass" configuration
+# directive below) it is possible to tell the slave to authenticate before
+# starting the replication synchronization process, otherwise the master will
+# refuse the slave request.
+#
+# masterauth <master-password>
+
+# When a slave loses its connection with the master, or when the replication
+# is still in progress, the slave can act in two different ways:
+#
+# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
+#    still reply to client requests, possibly with out of date data, or the
+#    data set may just be empty if this is the first synchronization.
+#
+# 2) if slave-serve-stale-data is set to 'no' the slave will reply with
+#    an error "SYNC with master in progress" to all the kind of commands
+#    but to INFO and SLAVEOF.
+#
+slave-serve-stale-data yes
+
+# You can configure a slave instance to accept writes or not. Writing against
+# a slave instance may be useful to store some ephemeral data (because data
+# written on a slave will be easily deleted after resync with the master) but
+# may also cause problems if clients are writing to it because of a
+# misconfiguration.
+#
+# Since Redis 2.6 by default slaves are read-only.
+#
+# Note: read only slaves are not designed to be exposed to untrusted clients
+# on the internet. It's just a protection layer against misuse of the instance.
+# Still a read only slave exports by default all the administrative commands
+# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
+# security of read only slaves using 'rename-command' to shadow all the
+# administrative / dangerous commands.
+slave-read-only yes
+
+# Replication SYNC strategy: disk or socket.
+#
+# -------------------------------------------------------
+# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY
+# -------------------------------------------------------
+#
+# New slaves and reconnecting slaves that are not able to continue the replication
+# process just receiving differences, need to do what is called a "full
+# synchronization". An RDB file is transmitted from the master to the slaves.
+# The transmission can happen in two different ways:
+#
+# 1) Disk-backed: The Redis master creates a new process that writes the RDB
+#                 file on disk. Later the file is transferred by the parent
+#                 process to the slaves incrementally.
+# 2) Diskless: The Redis master creates a new process that directly writes the
+#              RDB file to slave sockets, without touching the disk at all.
+#
+# With disk-backed replication, while the RDB file is generated, more slaves
+# can be queued and served with the RDB file as soon as the current child producing
+# the RDB file finishes its work. With diskless replication instead once
+# the transfer starts, new slaves arriving will be queued and a new transfer
+# will start when the current one terminates.
+#
+# When diskless replication is used, the master waits a configurable amount of
+# time (in seconds) before starting the transfer in the hope that multiple slaves
+# will arrive and the transfer can be parallelized.
+#
+# With slow disks and fast (large bandwidth) networks, diskless replication
+# works better.
+repl-diskless-sync no
+
+# When diskless replication is enabled, it is possible to configure the delay
+# the server waits in order to spawn the child that transfers the RDB via socket
+# to the slaves.
+#
+# This is important since once the transfer starts, it is not possible to serve
+# new slaves arriving, that will be queued for the next RDB transfer, so the server
+# waits a delay in order to let more slaves arrive.
+#
+# The delay is specified in seconds, and by default is 5 seconds. To disable
+# it entirely just set it to 0 seconds and the transfer will start ASAP.
+repl-diskless-sync-delay 5
+
+# Slaves send PINGs to server in a predefined interval. It's possible to change
+# this interval with the repl_ping_slave_period option. The default value is 10
+# seconds.
+#
+# repl-ping-slave-period 10
+
+# The following option sets the replication timeout for:
+#
+# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
+# 2) Master timeout from the point of view of slaves (data, pings).
+# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
+#
+# It is important to make sure that this value is greater than the value
+# specified for repl-ping-slave-period otherwise a timeout will be detected
+# every time there is low traffic between the master and the slave.
+#
+# repl-timeout 60
+
+# Disable TCP_NODELAY on the slave socket after SYNC?
+#
+# If you select "yes" Redis will use a smaller number of TCP packets and
+# less bandwidth to send data to slaves. But this can add a delay for
+# the data to appear on the slave side, up to 40 milliseconds with
+# Linux kernels using a default configuration.
+#
+# If you select "no" the delay for data to appear on the slave side will
+# be reduced but more bandwidth will be used for replication.
+#
+# By default we optimize for low latency, but in very high traffic conditions
+# or when the master and slaves are many hops away, turning this to "yes" may
+# be a good idea.
+repl-disable-tcp-nodelay no
+
+# Set the replication backlog size. The backlog is a buffer that accumulates
+# slave data when slaves are disconnected for some time, so that when a slave
+# wants to reconnect again, often a full resync is not needed, but a partial
+# resync is enough, just passing the portion of data the slave missed while
+# disconnected.
+#
+# The bigger the replication backlog, the longer the time the slave can be
+# disconnected and later be able to perform a partial resynchronization.
+#
+# The backlog is only allocated once there is at least a slave connected.
+#
+# repl-backlog-size 1mb
+
+# After a master has no longer connected slaves for some time, the backlog
+# will be freed. The following option configures the amount of seconds that
+# need to elapse, starting from the time the last slave disconnected, for
+# the backlog buffer to be freed.
+#
+# A value of 0 means to never release the backlog.
+#
+# repl-backlog-ttl 3600
+
+# The slave priority is an integer number published by Redis in the INFO output.
+# It is used by Redis Sentinel in order to select a slave to promote into a
+# master if the master is no longer working correctly.
+#
+# A slave with a low priority number is considered better for promotion, so
+# for instance if there are three slaves with priority 10, 100, 25 Sentinel will
+# pick the one with priority 10, that is the lowest.
+#
+# However a special priority of 0 marks the slave as not able to perform the
+# role of master, so a slave with priority of 0 will never be selected by
+# Redis Sentinel for promotion.
+#
+# By default the priority is 100.
+slave-priority 100
+
+# It is possible for a master to stop accepting writes if there are less than
+# N slaves connected, having a lag less or equal than M seconds.
+#
+# The N slaves need to be in "online" state.
+#
+# The lag in seconds, that must be <= the specified value, is calculated from
+# the last ping received from the slave, that is usually sent every second.
+#
+# This option does not GUARANTEE that N replicas will accept the write, but
+# will limit the window of exposure for lost writes in case not enough slaves
+# are available, to the specified number of seconds.
+#
+# For example to require at least 3 slaves with a lag <= 10 seconds use:
+#
+# min-slaves-to-write 3
+# min-slaves-max-lag 10
+#
+# Setting one or the other to 0 disables the feature.
+#
+# By default min-slaves-to-write is set to 0 (feature disabled) and
+# min-slaves-max-lag is set to 10.
+
+################################## SECURITY ###################################
+
+# Require clients to issue AUTH <PASSWORD> before processing any other
+# commands.  This might be useful in environments in which you do not trust
+# others with access to the host running redis-server.
+#
+# This should stay commented out for backward compatibility and because most
+# people do not need auth (e.g. they run their own servers).
+#
+# Warning: since Redis is pretty fast an outside user can try up to
+# 150k passwords per second against a good box. This means that you should
+# use a very strong password otherwise it will be very easy to break.
+#
+# requirepass foobared
+
+# Command renaming.
+#
+# It is possible to change the name of dangerous commands in a shared
+# environment. For instance the CONFIG command may be renamed into something
+# hard to guess so that it will still be available for internal-use tools
+# but not available for general clients.
+#
+# Example:
+#
+# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
+#
+# It is also possible to completely kill a command by renaming it into
+# an empty string:
+#
+# rename-command CONFIG ""
+#
+# Please note that changing the name of commands that are logged into the
+# AOF file or transmitted to slaves may cause problems.
+
+################################### LIMITS ####################################
+
+# Set the max number of connected clients at the same time. By default
+# this limit is set to 10000 clients, however if the Redis server is not
+# able to configure the process file limit to allow for the specified limit
+# the max number of allowed clients is set to the current file limit
+# minus 32 (as Redis reserves a few file descriptors for internal uses).
+#
+# Once the limit is reached Redis will close all the new connections sending
+# an error 'max number of clients reached'.
+#
+# maxclients 10000
+
+# Don't use more memory than the specified amount of bytes.
+# When the memory limit is reached Redis will try to remove keys
+# according to the eviction policy selected (see maxmemory-policy).
+#
+# If Redis can't remove keys according to the policy, or if the policy is
+# set to 'noeviction', Redis will start to reply with errors to commands
+# that would use more memory, like SET, LPUSH, and so on, and will continue
+# to reply to read-only commands like GET.
+#
+# This option is usually useful when using Redis as an LRU cache, or to set
+# a hard memory limit for an instance (using the 'noeviction' policy).
+#
+# WARNING: If you have slaves attached to an instance with maxmemory on,
+# the size of the output buffers needed to feed the slaves are subtracted
+# from the used memory count, so that network problems / resyncs will
+# not trigger a loop where keys are evicted, and in turn the output
+# buffer of slaves is full with DELs of keys evicted triggering the deletion
+# of more keys, and so forth until the database is completely emptied.
+#
+# In short... if you have slaves attached it is suggested that you set a lower
+# limit for maxmemory so that there is some free RAM on the system for slave
+# output buffers (but this is not needed if the policy is 'noeviction').
+#
+# maxmemory <bytes>
+
+# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
+# is reached. You can select among five behaviors:
+#
+# volatile-lru -> remove the key with an expire set using an LRU algorithm
+# allkeys-lru -> remove any key according to the LRU algorithm
+# volatile-random -> remove a random key with an expire set
+# allkeys-random -> remove a random key, any key
+# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
+# noeviction -> don't expire at all, just return an error on write operations
+#
+# Note: with any of the above policies, Redis will return an error on write
+#       operations, when there are no suitable keys for eviction.
+#
+#       At the date of writing these commands are: set setnx setex append
+#       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
+#       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
+#       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
+#       getset mset msetnx exec sort
+#
+# The default is:
+#
+# maxmemory-policy noeviction
+
+# LRU and minimal TTL algorithms are not precise algorithms but approximated
+# algorithms (in order to save memory), so you can tune it for speed or
+# accuracy. For default Redis will check five keys and pick the one that was
+# used less recently, you can change the sample size using the following
+# configuration directive.
+#
+# The default of 5 produces good enough results. 10 Approximates very closely
+# true LRU but costs a bit more CPU. 3 is very fast but not very accurate.
+#
+# maxmemory-samples 5
+
+############################## APPEND ONLY MODE ###############################
+
+# By default Redis asynchronously dumps the dataset on disk. This mode is
+# good enough in many applications, but an issue with the Redis process or
+# a power outage may result into a few minutes of writes lost (depending on
+# the configured save points).
+#
+# The Append Only File is an alternative persistence mode that provides
+# much better durability. For instance using the default data fsync policy
+# (see later in the config file) Redis can lose just one second of writes in a
+# dramatic event like a server power outage, or a single write if something
+# wrong with the Redis process itself happens, but the operating system is
+# still running correctly.
+#
+# AOF and RDB persistence can be enabled at the same time without problems.
+# If the AOF is enabled on startup Redis will load the AOF, that is the file
+# with the better durability guarantees.
+#
+# Please check http://redis.io/topics/persistence for more information.
+
+appendonly no
+
+# The name of the append only file (default: "appendonly.aof")
+
+appendfilename "appendonly.aof"
+
+# The fsync() call tells the Operating System to actually write data on disk
+# instead of waiting for more data in the output buffer. Some OS will really flush
+# data on disk, some other OS will just try to do it ASAP.
+#
+# Redis supports three different modes:
+#
+# no: don't fsync, just let the OS flush the data when it wants. Faster.
+# always: fsync after every write to the append only log. Slow, Safest.
+# everysec: fsync only one time every second. Compromise.
+#
+# The default is "everysec", as that's usually the right compromise between
+# speed and data safety. It's up to you to understand if you can relax this to
+# "no" that will let the operating system flush the output buffer when
+# it wants, for better performances (but if you can live with the idea of
+# some data loss consider the default persistence mode that's snapshotting),
+# or on the contrary, use "always" that's very slow but a bit safer than
+# everysec.
+#
+# More details please check the following article:
+# http://antirez.com/post/redis-persistence-demystified.html
+#
+# If unsure, use "everysec".
+
+# appendfsync always
+appendfsync everysec
+# appendfsync no
+
+# When the AOF fsync policy is set to always or everysec, and a background
+# saving process (a background save or AOF log background rewriting) is
+# performing a lot of I/O against the disk, in some Linux configurations
+# Redis may block too long on the fsync() call. Note that there is no fix for
+# this currently, as even performing fsync in a different thread will block
+# our synchronous write(2) call.
+#
+# In order to mitigate this problem it's possible to use the following option
+# that will prevent fsync() from being called in the main process while a
+# BGSAVE or BGREWRITEAOF is in progress.
+#
+# This means that while another child is saving, the durability of Redis is
+# the same as "appendfsync none". In practical terms, this means that it is
+# possible to lose up to 30 seconds of log in the worst scenario (with the
+# default Linux settings).
+#
+# If you have latency problems turn this to "yes". Otherwise leave it as
+# "no" that is the safest pick from the point of view of durability.
+
+no-appendfsync-on-rewrite no
+
+# Automatic rewrite of the append only file.
+# Redis is able to automatically rewrite the log file implicitly calling
+# BGREWRITEAOF when the AOF log size grows by the specified percentage.
+#
+# This is how it works: Redis remembers the size of the AOF file after the
+# latest rewrite (if no rewrite has happened since the restart, the size of
+# the AOF at startup is used).
+#
+# This base size is compared to the current size. If the current size is
+# bigger than the specified percentage, the rewrite is triggered. Also
+# you need to specify a minimal size for the AOF file to be rewritten, this
+# is useful to avoid rewriting the AOF file even if the percentage increase
+# is reached but it is still pretty small.
+#
+# Specify a percentage of zero in order to disable the automatic AOF
+# rewrite feature.
+
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+
+# An AOF file may be found to be truncated at the end during the Redis
+# startup process, when the AOF data gets loaded back into memory.
+# This may happen when the system where Redis is running
+# crashes, especially when an ext4 filesystem is mounted without the
+# data=ordered option (however this can't happen when Redis itself
+# crashes or aborts but the operating system still works correctly).
+#
+# Redis can either exit with an error when this happens, or load as much
+# data as possible (the default now) and start if the AOF file is found
+# to be truncated at the end. The following option controls this behavior.
+#
+# If aof-load-truncated is set to yes, a truncated AOF file is loaded and
+# the Redis server starts emitting a log to inform the user of the event.
+# Otherwise if the option is set to no, the server aborts with an error
+# and refuses to start. When the option is set to no, the user requires
+# to fix the AOF file using the "redis-check-aof" utility before to restart
+# the server.
+#
+# Note that if the AOF file will be found to be corrupted in the middle
+# the server will still exit with an error. This option only applies when
+# Redis will try to read more data from the AOF file but not enough bytes
+# will be found.
+aof-load-truncated yes
+
+################################ LUA SCRIPTING  ###############################
+
+# Max execution time of a Lua script in milliseconds.
+#
+# If the maximum execution time is reached Redis will log that a script is
+# still in execution after the maximum allowed time and will start to
+# reply to queries with an error.
+#
+# When a long running script exceeds the maximum execution time only the
+# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be
+# used to stop a script that did not yet called write commands. The second
+# is the only way to shut down the server in the case a write command was
+# already issued by the script but the user doesn't want to wait for the natural
+# termination of the script.
+#
+# Set it to 0 or a negative value for unlimited execution without warnings.
+lua-time-limit 5000
+
+################################ REDIS CLUSTER  ###############################
+#
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however
+# in order to mark it as "mature" we need to wait for a non trivial percentage
+# of users to deploy it in production.
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
+# started as cluster nodes can. In order to start a Redis instance as a
+# cluster node enable the cluster support uncommenting the following:
+#
+# cluster-enabled yes
+
+# Every cluster node has a cluster configuration file. This file is not
+# intended to be edited by hand. It is created and updated by Redis nodes.
+# Every Redis Cluster node requires a different cluster configuration file.
+# Make sure that instances running in the same system do not have
+# overlapping cluster configuration file names.
+#
+# cluster-config-file nodes-6379.conf
+
+# Cluster node timeout is the amount of milliseconds a node must be unreachable
+# for it to be considered in failure state.
+# Most other internal time limits are multiple of the node timeout.
+#
+# cluster-node-timeout 15000
+
+# A slave of a failing master will avoid to start a failover if its data
+# looks too old.
+#
+# There is no simple way for a slave to actually have a exact measure of
+# its "data age", so the following two checks are performed:
+#
+# 1) If there are multiple slaves able to failover, they exchange messages
+#    in order to try to give an advantage to the slave with the best
+#    replication offset (more data from the master processed).
+#    Slaves will try to get their rank by offset, and apply to the start
+#    of the failover a delay proportional to their rank.
+#
+# 2) Every single slave computes the time of the last interaction with
+#    its master. This can be the last ping or command received (if the master
+#    is still in the "connected" state), or the time that elapsed since the
+#    disconnection with the master (if the replication link is currently down).
+#    If the last interaction is too old, the slave will not try to failover
+#    at all.
+#
+# The point "2" can be tuned by user. Specifically a slave will not perform
+# the failover if, since the last interaction with the master, the time
+# elapsed is greater than:
+#
+#   (node-timeout * slave-validity-factor) + repl-ping-slave-period
+#
+# So for example if node-timeout is 30 seconds, and the slave-validity-factor
+# is 10, and assuming a default repl-ping-slave-period of 10 seconds, the
+# slave will not try to failover if it was not able to talk with the master
+# for longer than 310 seconds.
+#
+# A large slave-validity-factor may allow slaves with too old data to failover
+# a master, while a too small value may prevent the cluster from being able to
+# elect a slave at all.
+#
+# For maximum availability, it is possible to set the slave-validity-factor
+# to a value of 0, which means, that slaves will always try to failover the
+# master regardless of the last time they interacted with the master.
+# (However they'll always try to apply a delay proportional to their
+# offset rank).
+#
+# Zero is the only value able to guarantee that when all the partitions heal
+# the cluster will always be able to continue.
+#
+# cluster-slave-validity-factor 10
+
+# Cluster slaves are able to migrate to orphaned masters, that are masters
+# that are left without working slaves. This improves the cluster ability
+# to resist to failures as otherwise an orphaned master can't be failed over
+# in case of failure if it has no working slaves.
+#
+# Slaves migrate to orphaned masters only if there are still at least a
+# given number of other working slaves for their old master. This number
+# is the "migration barrier". A migration barrier of 1 means that a slave
+# will migrate only if there is at least 1 other working slave for its master
+# and so forth. It usually reflects the number of slaves you want for every
+# master in your cluster.
+#
+# Default is 1 (slaves migrate only if their masters remain with at least
+# one slave). To disable migration just set it to a very large value.
+# A value of 0 can be set but is useful only for debugging and dangerous
+# in production.
+#
+# cluster-migration-barrier 1
+
+# By default Redis Cluster nodes stop accepting queries if they detect there
+# is at least an hash slot uncovered (no available node is serving it).
+# This way if the cluster is partially down (for example a range of hash slots
+# are no longer covered) all the cluster becomes, eventually, unavailable.
+# It automatically returns available as soon as all the slots are covered again.
+#
+# However sometimes you want the subset of the cluster which is working,
+# to continue to accept queries for the part of the key space that is still
+# covered. In order to do so, just set the cluster-require-full-coverage
+# option to no.
+#
+# cluster-require-full-coverage yes
+
+# In order to setup your cluster make sure to read the documentation
+# available at http://redis.io web site.
+
+################################## SLOW LOG ###################################
+
+# The Redis Slow Log is a system to log queries that exceeded a specified
+# execution time. The execution time does not include the I/O operations
+# like talking with the client, sending the reply and so forth,
+# but just the time needed to actually execute the command (this is the only
+# stage of command execution where the thread is blocked and can not serve
+# other requests in the meantime).
+#
+# You can configure the slow log with two parameters: one tells Redis
+# what is the execution time, in microseconds, to exceed in order for the
+# command to get logged, and the other parameter is the length of the
+# slow log. When a new command is logged the oldest one is removed from the
+# queue of logged commands.
+
+# The following time is expressed in microseconds, so 1000000 is equivalent
+# to one second. Note that a negative number disables the slow log, while
+# a value of zero forces the logging of every command.
+slowlog-log-slower-than 10000
+
+# There is no limit to this length. Just be aware that it will consume memory.
+# You can reclaim memory used by the slow log with SLOWLOG RESET.
+slowlog-max-len 128
+
+################################ LATENCY MONITOR ##############################
+
+# The Redis latency monitoring subsystem samples different operations
+# at runtime in order to collect data related to possible sources of
+# latency of a Redis instance.
+#
+# Via the LATENCY command this information is available to the user that can
+# print graphs and obtain reports.
+#
+# The system only logs operations that were performed in a time equal or
+# greater than the amount of milliseconds specified via the
+# latency-monitor-threshold configuration directive. When its value is set
+# to zero, the latency monitor is turned off.
+#
+# By default latency monitoring is disabled since it is mostly not needed
+# if you don't have latency issues, and collecting data has a performance
+# impact, that while very small, can be measured under big load. Latency
+# monitoring can easily be enabled at runtime using the command
+# "CONFIG SET latency-monitor-threshold <milliseconds>" if needed.
+latency-monitor-threshold 0
+
+############################# EVENT NOTIFICATION ##############################
+
+# Redis can notify Pub/Sub clients about events happening in the key space.
+# This feature is documented at http://redis.io/topics/notifications
+#
+# For instance if keyspace events notification is enabled, and a client
+# performs a DEL operation on key "foo" stored in the Database 0, two
+# messages will be published via Pub/Sub:
+#
+# PUBLISH __keyspace@0__:foo del
+# PUBLISH __keyevent@0__:del foo
+#
+# It is possible to select the events that Redis will notify among a set
+# of classes. Every class is identified by a single character:
+#
+#  K     Keyspace events, published with __keyspace@<db>__ prefix.
+#  E     Keyevent events, published with __keyevent@<db>__ prefix.
+#  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
+#  $     String commands
+#  l     List commands
+#  s     Set commands
+#  h     Hash commands
+#  z     Sorted set commands
+#  x     Expired events (events generated every time a key expires)
+#  e     Evicted events (events generated when a key is evicted for maxmemory)
+#  A     Alias for g$lshzxe, so that the "AKE" string means all the events.
+#
+#  The "notify-keyspace-events" takes as argument a string that is composed
+#  of zero or multiple characters. The empty string means that notifications
+#  are disabled.
+#
+#  Example: to enable list and generic events, from the point of view of the
+#           event name, use:
+#
+#  notify-keyspace-events Elg
+#
+#  Example 2: to get the stream of the expired keys subscribing to channel
+#             name __keyevent@0__:expired use:
+#
+#  notify-keyspace-events Ex
+#
+#  By default all notifications are disabled because most users don't need
+#  this feature and the feature has some overhead. Note that if you don't
+#  specify at least one of K or E, no events will be delivered.
+notify-keyspace-events Ex
+
+############################### ADVANCED CONFIG ###############################
+
+# Hashes are encoded using a memory efficient data structure when they have a
+# small number of entries, and the biggest entry does not exceed a given
+# threshold. These thresholds can be configured using the following directives.
+hash-max-ziplist-entries 512
+hash-max-ziplist-value 64
+
+# Similarly to hashes, small lists are also encoded in a special way in order
+# to save a lot of space. The special representation is only used when
+# you are under the following limits:
+list-max-ziplist-entries 512
+list-max-ziplist-value 64
+
+# Sets have a special encoding in just one case: when a set is composed
+# of just strings that happen to be integers in radix 10 in the range
+# of 64 bit signed integers.
+# The following configuration setting sets the limit in the size of the
+# set in order to use this special memory saving encoding.
+set-max-intset-entries 512
+
+# Similarly to hashes and lists, sorted sets are also specially encoded in
+# order to save a lot of space. This encoding is only used when the length and
+# elements of a sorted set are below the following limits:
+zset-max-ziplist-entries 128
+zset-max-ziplist-value 64
+
+# HyperLogLog sparse representation bytes limit. The limit includes the
+# 16 bytes header. When an HyperLogLog using the sparse representation crosses
+# this limit, it is converted into the dense representation.
+#
+# A value greater than 16000 is totally useless, since at that point the
+# dense representation is more memory efficient.
+#
+# The suggested value is ~ 3000 in order to have the benefits of
+# the space efficient encoding without slowing down too much PFADD,
+# which is O(N) with the sparse encoding. The value can be raised to
+# ~ 10000 when CPU is not a concern, but space is, and the data set is
+# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
+hll-sparse-max-bytes 3000
+
+# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
+# order to help rehashing the main Redis hash table (the one mapping top-level
+# keys to values). The hash table implementation Redis uses (see dict.c)
+# performs a lazy rehashing: the more operation you run into a hash table
+# that is rehashing, the more rehashing "steps" are performed, so if the
+# server is idle the rehashing is never complete and some more memory is used
+# by the hash table.
+#
+# The default is to use this millisecond 10 times every second in order to
+# actively rehash the main dictionaries, freeing memory when possible.
+#
+# If unsure:
+# use "activerehashing no" if you have hard latency requirements and it is
+# not a good thing in your environment that Redis can reply from time to time
+# to queries with 2 milliseconds delay.
+#
+# use "activerehashing yes" if you don't have such hard requirements but
+# want to free memory asap when possible.
+activerehashing yes
+
+# The client output buffer limits can be used to force disconnection of clients
+# that are not reading data from the server fast enough for some reason (a
+# common reason is that a Pub/Sub client can't consume messages as fast as the
+# publisher can produce them).
+#
+# The limit can be set differently for the three different classes of clients:
+#
+# normal -> normal clients including MONITOR clients
+# slave  -> slave clients
+# pubsub -> clients subscribed to at least one pubsub channel or pattern
+#
+# The syntax of every client-output-buffer-limit directive is the following:
+#
+# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
+#
+# A client is immediately disconnected once the hard limit is reached, or if
+# the soft limit is reached and remains reached for the specified number of
+# seconds (continuously).
+# So for instance if the hard limit is 32 megabytes and the soft limit is
+# 16 megabytes / 10 seconds, the client will get disconnected immediately
+# if the size of the output buffers reach 32 megabytes, but will also get
+# disconnected if the client reaches 16 megabytes and continuously overcomes
+# the limit for 10 seconds.
+#
+# By default normal clients are not limited because they don't receive data
+# without asking (in a push way), but just after a request, so only
+# asynchronous clients may create a scenario where data is requested faster
+# than it can read.
+#
+# Instead there is a default limit for pubsub and slave clients, since
+# subscribers and slaves receive data in a push fashion.
+#
+# Both the hard or the soft limit can be disabled by setting them to zero.
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit slave 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+
+# Redis calls an internal function to perform many background tasks, like
+# closing connections of clients in timeout, purging expired keys that are
+# never requested, and so forth.
+#
+# Not all tasks are performed with the same frequency, but Redis checks for
+# tasks to perform according to the specified "hz" value.
+#
+# By default "hz" is set to 10. Raising the value will use more CPU when
+# Redis is idle, but at the same time will make Redis more responsive when
+# there are many keys expiring at the same time, and timeouts may be
+# handled with more precision.
+#
+# The range is between 1 and 500, however a value over 100 is usually not
+# a good idea. Most users should use the default of 10 and raise this up to
+# 100 only in environments where very low latency is required.
+hz 10
+
+# When a child rewrites the AOF file, if the following option is enabled
+# the file will be fsync-ed every 32 MB of data generated. This is useful
+# in order to commit the file to the disk more incrementally and avoid
+# big latency spikes.
+aof-rewrite-incremental-fsync yes

+ 944 - 0
docker/compose/xyzt/conf/redis/6380.conf

@@ -0,0 +1,944 @@
+## Generated by install_server.sh ##
+# Redis configuration file example.
+#
+# Note that in order to read the configuration file, Redis must be
+# started with the file path as first argument:
+#
+# ./redis-server /path/to/redis.conf
+
+# Note on units: when memory size is needed, it is possible to specify
+# it in the usual form of 1k 5GB 4M and so forth:
+#
+# 1k => 1000 bytes
+# 1kb => 1024 bytes
+# 1m => 1000000 bytes
+# 1mb => 1024*1024 bytes
+# 1g => 1000000000 bytes
+# 1gb => 1024*1024*1024 bytes
+#
+# units are case insensitive so 1GB 1Gb 1gB are all the same.
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here.  This is useful if you
+# have a standard template that goes to all Redis servers but also need
+# to customize a few per-server settings.  Include files can include
+# other files, so use this wisely.
+#
+# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
+# from admin or Redis Sentinel. Since Redis always uses the last processed
+# line as value of a configuration directive, you'd better put includes
+# at the beginning of this file to avoid overwriting config change at runtime.
+#
+# If instead you are interested in using includes to override configuration
+# options, it is better to use include as the last line.
+#
+# include /path/to/local.conf
+# include /path/to/other.conf
+
+################################ GENERAL  #####################################
+
+# By default Redis does not run as a daemon. Use 'yes' if you need it.
+# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
+daemonize yes
+
+# When running daemonized, Redis writes a pid file in /var/run/redis.pid by
+# default. You can specify a custom pid file location here.
+pidfile /var/run/redis.pid
+
+# Accept connections on the specified port, default is 6379.
+# If port 0 is specified Redis will not listen on a TCP socket.
+port 6380
+
+# TCP listen() backlog.
+#
+# In high requests-per-second environments you need an high backlog in order
+# to avoid slow clients connections issues. Note that the Linux kernel
+# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
+# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
+# in order to get the desired effect.
+tcp-backlog 511
+
+# By default Redis listens for connections from all the network interfaces
+# available on the server. It is possible to listen to just one or multiple
+# interfaces using the "bind" configuration directive, followed by one or
+# more IP addresses.
+#
+# Examples:
+#
+# bind 192.168.1.100 10.0.0.1
+bind 0.0.0.0
+
+# Specify the path for the Unix socket that will be used to listen for
+# incoming connections. There is no default, so Redis will not listen
+# on a unix socket when not specified.
+#
+# unixsocket /tmp/redis.sock
+# unixsocketperm 700
+
+# Close the connection after a client is idle for N seconds (0 to disable)
+timeout 0
+
+# TCP keepalive.
+#
+# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
+# of communication. This is useful for two reasons:
+#
+# 1) Detect dead peers.
+# 2) Take the connection alive from the point of view of network
+#    equipment in the middle.
+#
+# On Linux, the specified value (in seconds) is the period used to send ACKs.
+# Note that to close the connection the double of the time is needed.
+# On other kernels the period depends on the kernel configuration.
+#
+# A reasonable value for this option is 60 seconds.
+tcp-keepalive 0
+
+# Specify the server verbosity level.
+# This can be one of:
+# debug (a lot of information, useful for development/testing)
+# verbose (many rarely useful info, but not a mess like the debug level)
+# notice (moderately verbose, what you want in production probably)
+# warning (only very important / critical messages are logged)
+loglevel notice
+
+# Specify the log file name. Also the empty string can be used to force
+# Redis to log on the standard output. Note that if you use standard
+# output for logging but daemonize, logs will be sent to /dev/null
+logfile /var/redis/redis-6380.log
+
+# To enable logging to the system logger, just set 'syslog-enabled' to yes,
+# and optionally update the other syslog parameters to suit your needs.
+# syslog-enabled no
+
+# Specify the syslog identity.
+# syslog-ident redis
+
+# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
+# syslog-facility local0
+
+# Set the number of databases. The default database is DB 0, you can select
+# a different one on a per-connection basis using SELECT <dbid> where
+# dbid is a number between 0 and 'databases'-1
+databases 16
+
+################################ SNAPSHOTTING  ################################
+#
+# Save the DB on disk:
+#
+#   save <seconds> <changes>
+#
+#   Will save the DB if both the given number of seconds and the given
+#   number of write operations against the DB occurred.
+#
+#   In the example below the behaviour will be to save:
+#   after 900 sec (15 min) if at least 1 key changed
+#   after 300 sec (5 min) if at least 10 keys changed
+#   after 60 sec if at least 10000 keys changed
+#
+#   Note: you can disable saving completely by commenting out all "save" lines.
+#
+#   It is also possible to remove all the previously configured save
+#   points by adding a save directive with a single empty string argument
+#   like in the following example:
+#
+#   save ""
+
+save 900 1
+save 300 10
+save 60 10000
+
+# By default Redis will stop accepting writes if RDB snapshots are enabled
+# (at least one save point) and the latest background save failed.
+# This will make the user aware (in a hard way) that data is not persisting
+# on disk properly, otherwise chances are that no one will notice and some
+# disaster will happen.
+#
+# If the background saving process will start working again Redis will
+# automatically allow writes again.
+#
+# However if you have setup your proper monitoring of the Redis server
+# and persistence, you may want to disable this feature so that Redis will
+# continue to work as usual even if there are problems with disk,
+# permissions, and so forth.
+stop-writes-on-bgsave-error yes
+
+# Compress string objects using LZF when dump .rdb databases?
+# For default that's set to 'yes' as it's almost always a win.
+# If you want to save some CPU in the saving child set it to 'no' but
+# the dataset will likely be bigger if you have compressible values or keys.
+rdbcompression yes
+
+# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
+# This makes the format more resistant to corruption but there is a performance
+# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
+# for maximum performances.
+#
+# RDB files created with checksum disabled have a checksum of zero that will
+# tell the loading code to skip the check.
+rdbchecksum yes
+
+# The filename where to dump the DB
+dbfilename dump.rdb
+
+# The working directory.
+#
+# The DB will be written inside this directory, with the filename specified
+# above using the 'dbfilename' configuration directive.
+#
+# The Append Only File will also be created inside this directory.
+#
+# Note that you must specify a directory here, not a file name.
+dir /var/redis
+
+################################# REPLICATION #################################
+
+# Master-Slave replication. Use slaveof to make a Redis instance a copy of
+# another Redis server. A few things to understand ASAP about Redis replication.
+#
+# 1) Redis replication is asynchronous, but you can configure a master to
+#    stop accepting writes if it appears to be not connected with at least
+#    a given number of slaves.
+# 2) Redis slaves are able to perform a partial resynchronization with the
+#    master if the replication link is lost for a relatively small amount of
+#    time. You may want to configure the replication backlog size (see the next
+#    sections of this file) with a sensible value depending on your needs.
+# 3) Replication is automatic and does not need user intervention. After a
+#    network partition slaves automatically try to reconnect to masters
+#    and resynchronize with them.
+#
+# slaveof <masterip> <masterport>
+
+# If the master is password protected (using the "requirepass" configuration
+# directive below) it is possible to tell the slave to authenticate before
+# starting the replication synchronization process, otherwise the master will
+# refuse the slave request.
+#
+# masterauth <master-password>
+
+# When a slave loses its connection with the master, or when the replication
+# is still in progress, the slave can act in two different ways:
+#
+# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
+#    still reply to client requests, possibly with out of date data, or the
+#    data set may just be empty if this is the first synchronization.
+#
+# 2) if slave-serve-stale-data is set to 'no' the slave will reply with
+#    an error "SYNC with master in progress" to all the kind of commands
+#    but to INFO and SLAVEOF.
+#
+slave-serve-stale-data yes
+
+# You can configure a slave instance to accept writes or not. Writing against
+# a slave instance may be useful to store some ephemeral data (because data
+# written on a slave will be easily deleted after resync with the master) but
+# may also cause problems if clients are writing to it because of a
+# misconfiguration.
+#
+# Since Redis 2.6 by default slaves are read-only.
+#
+# Note: read only slaves are not designed to be exposed to untrusted clients
+# on the internet. It's just a protection layer against misuse of the instance.
+# Still a read only slave exports by default all the administrative commands
+# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
+# security of read only slaves using 'rename-command' to shadow all the
+# administrative / dangerous commands.
+slave-read-only yes
+
+# Replication SYNC strategy: disk or socket.
+#
+# -------------------------------------------------------
+# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY
+# -------------------------------------------------------
+#
+# New slaves and reconnecting slaves that are not able to continue the replication
+# process just receiving differences, need to do what is called a "full
+# synchronization". An RDB file is transmitted from the master to the slaves.
+# The transmission can happen in two different ways:
+#
+# 1) Disk-backed: The Redis master creates a new process that writes the RDB
+#                 file on disk. Later the file is transferred by the parent
+#                 process to the slaves incrementally.
+# 2) Diskless: The Redis master creates a new process that directly writes the
+#              RDB file to slave sockets, without touching the disk at all.
+#
+# With disk-backed replication, while the RDB file is generated, more slaves
+# can be queued and served with the RDB file as soon as the current child producing
+# the RDB file finishes its work. With diskless replication instead once
+# the transfer starts, new slaves arriving will be queued and a new transfer
+# will start when the current one terminates.
+#
+# When diskless replication is used, the master waits a configurable amount of
+# time (in seconds) before starting the transfer in the hope that multiple slaves
+# will arrive and the transfer can be parallelized.
+#
+# With slow disks and fast (large bandwidth) networks, diskless replication
+# works better.
+repl-diskless-sync no
+
+# When diskless replication is enabled, it is possible to configure the delay
+# the server waits in order to spawn the child that transfers the RDB via socket
+# to the slaves.
+#
+# This is important since once the transfer starts, it is not possible to serve
+# new slaves arriving, that will be queued for the next RDB transfer, so the server
+# waits a delay in order to let more slaves arrive.
+#
+# The delay is specified in seconds, and by default is 5 seconds. To disable
+# it entirely just set it to 0 seconds and the transfer will start ASAP.
+repl-diskless-sync-delay 5
+
+# Slaves send PINGs to server in a predefined interval. It's possible to change
+# this interval with the repl_ping_slave_period option. The default value is 10
+# seconds.
+#
+# repl-ping-slave-period 10
+
+# The following option sets the replication timeout for:
+#
+# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
+# 2) Master timeout from the point of view of slaves (data, pings).
+# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
+#
+# It is important to make sure that this value is greater than the value
+# specified for repl-ping-slave-period otherwise a timeout will be detected
+# every time there is low traffic between the master and the slave.
+#
+# repl-timeout 60
+
+# Disable TCP_NODELAY on the slave socket after SYNC?
+#
+# If you select "yes" Redis will use a smaller number of TCP packets and
+# less bandwidth to send data to slaves. But this can add a delay for
+# the data to appear on the slave side, up to 40 milliseconds with
+# Linux kernels using a default configuration.
+#
+# If you select "no" the delay for data to appear on the slave side will
+# be reduced but more bandwidth will be used for replication.
+#
+# By default we optimize for low latency, but in very high traffic conditions
+# or when the master and slaves are many hops away, turning this to "yes" may
+# be a good idea.
+repl-disable-tcp-nodelay no
+
+# Set the replication backlog size. The backlog is a buffer that accumulates
+# slave data when slaves are disconnected for some time, so that when a slave
+# wants to reconnect again, often a full resync is not needed, but a partial
+# resync is enough, just passing the portion of data the slave missed while
+# disconnected.
+#
+# The bigger the replication backlog, the longer the time the slave can be
+# disconnected and later be able to perform a partial resynchronization.
+#
+# The backlog is only allocated once there is at least a slave connected.
+#
+# repl-backlog-size 1mb
+
+# After a master has no longer connected slaves for some time, the backlog
+# will be freed. The following option configures the amount of seconds that
+# need to elapse, starting from the time the last slave disconnected, for
+# the backlog buffer to be freed.
+#
+# A value of 0 means to never release the backlog.
+#
+# repl-backlog-ttl 3600
+
+# The slave priority is an integer number published by Redis in the INFO output.
+# It is used by Redis Sentinel in order to select a slave to promote into a
+# master if the master is no longer working correctly.
+#
+# A slave with a low priority number is considered better for promotion, so
+# for instance if there are three slaves with priority 10, 100, 25 Sentinel will
+# pick the one with priority 10, that is the lowest.
+#
+# However a special priority of 0 marks the slave as not able to perform the
+# role of master, so a slave with priority of 0 will never be selected by
+# Redis Sentinel for promotion.
+#
+# By default the priority is 100.
+slave-priority 100
+
+# It is possible for a master to stop accepting writes if there are less than
+# N slaves connected, having a lag less or equal than M seconds.
+#
+# The N slaves need to be in "online" state.
+#
+# The lag in seconds, that must be <= the specified value, is calculated from
+# the last ping received from the slave, that is usually sent every second.
+#
+# This option does not GUARANTEE that N replicas will accept the write, but
+# will limit the window of exposure for lost writes in case not enough slaves
+# are available, to the specified number of seconds.
+#
+# For example to require at least 3 slaves with a lag <= 10 seconds use:
+#
+# min-slaves-to-write 3
+# min-slaves-max-lag 10
+#
+# Setting one or the other to 0 disables the feature.
+#
+# By default min-slaves-to-write is set to 0 (feature disabled) and
+# min-slaves-max-lag is set to 10.
+
+################################## SECURITY ###################################
+
+# Require clients to issue AUTH <PASSWORD> before processing any other
+# commands.  This might be useful in environments in which you do not trust
+# others with access to the host running redis-server.
+#
+# This should stay commented out for backward compatibility and because most
+# people do not need auth (e.g. they run their own servers).
+#
+# Warning: since Redis is pretty fast an outside user can try up to
+# 150k passwords per second against a good box. This means that you should
+# use a very strong password otherwise it will be very easy to break.
+#
+# requirepass foobared
+
+# Command renaming.
+#
+# It is possible to change the name of dangerous commands in a shared
+# environment. For instance the CONFIG command may be renamed into something
+# hard to guess so that it will still be available for internal-use tools
+# but not available for general clients.
+#
+# Example:
+#
+# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
+#
+# It is also possible to completely kill a command by renaming it into
+# an empty string:
+#
+# rename-command CONFIG ""
+#
+# Please note that changing the name of commands that are logged into the
+# AOF file or transmitted to slaves may cause problems.
+
+################################### LIMITS ####################################
+
+# Set the max number of connected clients at the same time. By default
+# this limit is set to 10000 clients, however if the Redis server is not
+# able to configure the process file limit to allow for the specified limit
+# the max number of allowed clients is set to the current file limit
+# minus 32 (as Redis reserves a few file descriptors for internal uses).
+#
+# Once the limit is reached Redis will close all the new connections sending
+# an error 'max number of clients reached'.
+#
+# maxclients 10000
+
+# Don't use more memory than the specified amount of bytes.
+# When the memory limit is reached Redis will try to remove keys
+# according to the eviction policy selected (see maxmemory-policy).
+#
+# If Redis can't remove keys according to the policy, or if the policy is
+# set to 'noeviction', Redis will start to reply with errors to commands
+# that would use more memory, like SET, LPUSH, and so on, and will continue
+# to reply to read-only commands like GET.
+#
+# This option is usually useful when using Redis as an LRU cache, or to set
+# a hard memory limit for an instance (using the 'noeviction' policy).
+#
+# WARNING: If you have slaves attached to an instance with maxmemory on,
+# the size of the output buffers needed to feed the slaves are subtracted
+# from the used memory count, so that network problems / resyncs will
+# not trigger a loop where keys are evicted, and in turn the output
+# buffer of slaves is full with DELs of keys evicted triggering the deletion
+# of more keys, and so forth until the database is completely emptied.
+#
+# In short... if you have slaves attached it is suggested that you set a lower
+# limit for maxmemory so that there is some free RAM on the system for slave
+# output buffers (but this is not needed if the policy is 'noeviction').
+#
+# maxmemory <bytes>
+
+# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
+# is reached. You can select among five behaviors:
+#
+# volatile-lru -> remove the key with an expire set using an LRU algorithm
+# allkeys-lru -> remove any key according to the LRU algorithm
+# volatile-random -> remove a random key with an expire set
+# allkeys-random -> remove a random key, any key
+# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
+# noeviction -> don't expire at all, just return an error on write operations
+#
+# Note: with any of the above policies, Redis will return an error on write
+#       operations, when there are no suitable keys for eviction.
+#
+#       At the date of writing these commands are: set setnx setex append
+#       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
+#       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
+#       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
+#       getset mset msetnx exec sort
+#
+# The default is:
+#
+# maxmemory-policy noeviction
+
+# LRU and minimal TTL algorithms are not precise algorithms but approximated
+# algorithms (in order to save memory), so you can tune it for speed or
+# accuracy. For default Redis will check five keys and pick the one that was
+# used less recently, you can change the sample size using the following
+# configuration directive.
+#
+# The default of 5 produces good enough results. 10 Approximates very closely
+# true LRU but costs a bit more CPU. 3 is very fast but not very accurate.
+#
+# maxmemory-samples 5
+
+############################## APPEND ONLY MODE ###############################
+
+# By default Redis asynchronously dumps the dataset on disk. This mode is
+# good enough in many applications, but an issue with the Redis process or
+# a power outage may result into a few minutes of writes lost (depending on
+# the configured save points).
+#
+# The Append Only File is an alternative persistence mode that provides
+# much better durability. For instance using the default data fsync policy
+# (see later in the config file) Redis can lose just one second of writes in a
+# dramatic event like a server power outage, or a single write if something
+# wrong with the Redis process itself happens, but the operating system is
+# still running correctly.
+#
+# AOF and RDB persistence can be enabled at the same time without problems.
+# If the AOF is enabled on startup Redis will load the AOF, that is the file
+# with the better durability guarantees.
+#
+# Please check http://redis.io/topics/persistence for more information.
+
+appendonly no
+
+# The name of the append only file (default: "appendonly.aof")
+
+appendfilename "appendonly.aof"
+
+# The fsync() call tells the Operating System to actually write data on disk
+# instead of waiting for more data in the output buffer. Some OS will really flush
+# data on disk, some other OS will just try to do it ASAP.
+#
+# Redis supports three different modes:
+#
+# no: don't fsync, just let the OS flush the data when it wants. Faster.
+# always: fsync after every write to the append only log. Slow, Safest.
+# everysec: fsync only one time every second. Compromise.
+#
+# The default is "everysec", as that's usually the right compromise between
+# speed and data safety. It's up to you to understand if you can relax this to
+# "no" that will let the operating system flush the output buffer when
+# it wants, for better performances (but if you can live with the idea of
+# some data loss consider the default persistence mode that's snapshotting),
+# or on the contrary, use "always" that's very slow but a bit safer than
+# everysec.
+#
+# More details please check the following article:
+# http://antirez.com/post/redis-persistence-demystified.html
+#
+# If unsure, use "everysec".
+
+# appendfsync always
+appendfsync everysec
+# appendfsync no
+
+# When the AOF fsync policy is set to always or everysec, and a background
+# saving process (a background save or AOF log background rewriting) is
+# performing a lot of I/O against the disk, in some Linux configurations
+# Redis may block too long on the fsync() call. Note that there is no fix for
+# this currently, as even performing fsync in a different thread will block
+# our synchronous write(2) call.
+#
+# In order to mitigate this problem it's possible to use the following option
+# that will prevent fsync() from being called in the main process while a
+# BGSAVE or BGREWRITEAOF is in progress.
+#
+# This means that while another child is saving, the durability of Redis is
+# the same as "appendfsync none". In practical terms, this means that it is
+# possible to lose up to 30 seconds of log in the worst scenario (with the
+# default Linux settings).
+#
+# If you have latency problems turn this to "yes". Otherwise leave it as
+# "no" that is the safest pick from the point of view of durability.
+
+no-appendfsync-on-rewrite no
+
+# Automatic rewrite of the append only file.
+# Redis is able to automatically rewrite the log file implicitly calling
+# BGREWRITEAOF when the AOF log size grows by the specified percentage.
+#
+# This is how it works: Redis remembers the size of the AOF file after the
+# latest rewrite (if no rewrite has happened since the restart, the size of
+# the AOF at startup is used).
+#
+# This base size is compared to the current size. If the current size is
+# bigger than the specified percentage, the rewrite is triggered. Also
+# you need to specify a minimal size for the AOF file to be rewritten, this
+# is useful to avoid rewriting the AOF file even if the percentage increase
+# is reached but it is still pretty small.
+#
+# Specify a percentage of zero in order to disable the automatic AOF
+# rewrite feature.
+
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+
+# An AOF file may be found to be truncated at the end during the Redis
+# startup process, when the AOF data gets loaded back into memory.
+# This may happen when the system where Redis is running
+# crashes, especially when an ext4 filesystem is mounted without the
+# data=ordered option (however this can't happen when Redis itself
+# crashes or aborts but the operating system still works correctly).
+#
+# Redis can either exit with an error when this happens, or load as much
+# data as possible (the default now) and start if the AOF file is found
+# to be truncated at the end. The following option controls this behavior.
+#
+# If aof-load-truncated is set to yes, a truncated AOF file is loaded and
+# the Redis server starts emitting a log to inform the user of the event.
+# Otherwise if the option is set to no, the server aborts with an error
+# and refuses to start. When the option is set to no, the user requires
+# to fix the AOF file using the "redis-check-aof" utility before to restart
+# the server.
+#
+# Note that if the AOF file will be found to be corrupted in the middle
+# the server will still exit with an error. This option only applies when
+# Redis will try to read more data from the AOF file but not enough bytes
+# will be found.
+aof-load-truncated yes
+
+################################ LUA SCRIPTING  ###############################
+
+# Max execution time of a Lua script in milliseconds.
+#
+# If the maximum execution time is reached Redis will log that a script is
+# still in execution after the maximum allowed time and will start to
+# reply to queries with an error.
+#
+# When a long running script exceeds the maximum execution time only the
+# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be
+# used to stop a script that did not yet called write commands. The second
+# is the only way to shut down the server in the case a write command was
+# already issued by the script but the user doesn't want to wait for the natural
+# termination of the script.
+#
+# Set it to 0 or a negative value for unlimited execution without warnings.
+lua-time-limit 5000
+
+################################ REDIS CLUSTER  ###############################
+#
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however
+# in order to mark it as "mature" we need to wait for a non trivial percentage
+# of users to deploy it in production.
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#
+# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
+# started as cluster nodes can. In order to start a Redis instance as a
+# cluster node enable the cluster support uncommenting the following:
+#
+# cluster-enabled yes
+
+# Every cluster node has a cluster configuration file. This file is not
+# intended to be edited by hand. It is created and updated by Redis nodes.
+# Every Redis Cluster node requires a different cluster configuration file.
+# Make sure that instances running in the same system do not have
+# overlapping cluster configuration file names.
+#
+# cluster-config-file nodes-6379.conf
+
+# Cluster node timeout is the amount of milliseconds a node must be unreachable
+# for it to be considered in failure state.
+# Most other internal time limits are multiple of the node timeout.
+#
+# cluster-node-timeout 15000
+
+# A slave of a failing master will avoid to start a failover if its data
+# looks too old.
+#
+# There is no simple way for a slave to actually have a exact measure of
+# its "data age", so the following two checks are performed:
+#
+# 1) If there are multiple slaves able to failover, they exchange messages
+#    in order to try to give an advantage to the slave with the best
+#    replication offset (more data from the master processed).
+#    Slaves will try to get their rank by offset, and apply to the start
+#    of the failover a delay proportional to their rank.
+#
+# 2) Every single slave computes the time of the last interaction with
+#    its master. This can be the last ping or command received (if the master
+#    is still in the "connected" state), or the time that elapsed since the
+#    disconnection with the master (if the replication link is currently down).
+#    If the last interaction is too old, the slave will not try to failover
+#    at all.
+#
+# The point "2" can be tuned by user. Specifically a slave will not perform
+# the failover if, since the last interaction with the master, the time
+# elapsed is greater than:
+#
+#   (node-timeout * slave-validity-factor) + repl-ping-slave-period
+#
+# So for example if node-timeout is 30 seconds, and the slave-validity-factor
+# is 10, and assuming a default repl-ping-slave-period of 10 seconds, the
+# slave will not try to failover if it was not able to talk with the master
+# for longer than 310 seconds.
+#
+# A large slave-validity-factor may allow slaves with too old data to failover
+# a master, while a too small value may prevent the cluster from being able to
+# elect a slave at all.
+#
+# For maximum availability, it is possible to set the slave-validity-factor
+# to a value of 0, which means, that slaves will always try to failover the
+# master regardless of the last time they interacted with the master.
+# (However they'll always try to apply a delay proportional to their
+# offset rank).
+#
+# Zero is the only value able to guarantee that when all the partitions heal
+# the cluster will always be able to continue.
+#
+# cluster-slave-validity-factor 10
+
+# Cluster slaves are able to migrate to orphaned masters, that are masters
+# that are left without working slaves. This improves the cluster ability
+# to resist to failures as otherwise an orphaned master can't be failed over
+# in case of failure if it has no working slaves.
+#
+# Slaves migrate to orphaned masters only if there are still at least a
+# given number of other working slaves for their old master. This number
+# is the "migration barrier". A migration barrier of 1 means that a slave
+# will migrate only if there is at least 1 other working slave for its master
+# and so forth. It usually reflects the number of slaves you want for every
+# master in your cluster.
+#
+# Default is 1 (slaves migrate only if their masters remain with at least
+# one slave). To disable migration just set it to a very large value.
+# A value of 0 can be set but is useful only for debugging and dangerous
+# in production.
+#
+# cluster-migration-barrier 1
+
+# By default Redis Cluster nodes stop accepting queries if they detect there
+# is at least an hash slot uncovered (no available node is serving it).
+# This way if the cluster is partially down (for example a range of hash slots
+# are no longer covered) all the cluster becomes, eventually, unavailable.
+# It automatically returns available as soon as all the slots are covered again.
+#
+# However sometimes you want the subset of the cluster which is working,
+# to continue to accept queries for the part of the key space that is still
+# covered. In order to do so, just set the cluster-require-full-coverage
+# option to no.
+#
+# cluster-require-full-coverage yes
+
+# In order to setup your cluster make sure to read the documentation
+# available at http://redis.io web site.
+
+################################## SLOW LOG ###################################
+
+# The Redis Slow Log is a system to log queries that exceeded a specified
+# execution time. The execution time does not include the I/O operations
+# like talking with the client, sending the reply and so forth,
+# but just the time needed to actually execute the command (this is the only
+# stage of command execution where the thread is blocked and can not serve
+# other requests in the meantime).
+#
+# You can configure the slow log with two parameters: one tells Redis
+# what is the execution time, in microseconds, to exceed in order for the
+# command to get logged, and the other parameter is the length of the
+# slow log. When a new command is logged the oldest one is removed from the
+# queue of logged commands.
+
+# The following time is expressed in microseconds, so 1000000 is equivalent
+# to one second. Note that a negative number disables the slow log, while
+# a value of zero forces the logging of every command.
+slowlog-log-slower-than 10000
+
+# There is no limit to this length. Just be aware that it will consume memory.
+# You can reclaim memory used by the slow log with SLOWLOG RESET.
+slowlog-max-len 128
+
+################################ LATENCY MONITOR ##############################
+
+# The Redis latency monitoring subsystem samples different operations
+# at runtime in order to collect data related to possible sources of
+# latency of a Redis instance.
+#
+# Via the LATENCY command this information is available to the user that can
+# print graphs and obtain reports.
+#
+# The system only logs operations that were performed in a time equal or
+# greater than the amount of milliseconds specified via the
+# latency-monitor-threshold configuration directive. When its value is set
+# to zero, the latency monitor is turned off.
+#
+# By default latency monitoring is disabled since it is mostly not needed
+# if you don't have latency issues, and collecting data has a performance
+# impact, that while very small, can be measured under big load. Latency
+# monitoring can easily be enabled at runtime using the command
+# "CONFIG SET latency-monitor-threshold <milliseconds>" if needed.
+latency-monitor-threshold 0
+
+############################# EVENT NOTIFICATION ##############################
+
+# Redis can notify Pub/Sub clients about events happening in the key space.
+# This feature is documented at http://redis.io/topics/notifications
+#
+# For instance if keyspace events notification is enabled, and a client
+# performs a DEL operation on key "foo" stored in the Database 0, two
+# messages will be published via Pub/Sub:
+#
+# PUBLISH __keyspace@0__:foo del
+# PUBLISH __keyevent@0__:del foo
+#
+# It is possible to select the events that Redis will notify among a set
+# of classes. Every class is identified by a single character:
+#
+#  K     Keyspace events, published with __keyspace@<db>__ prefix.
+#  E     Keyevent events, published with __keyevent@<db>__ prefix.
+#  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
+#  $     String commands
+#  l     List commands
+#  s     Set commands
+#  h     Hash commands
+#  z     Sorted set commands
+#  x     Expired events (events generated every time a key expires)
+#  e     Evicted events (events generated when a key is evicted for maxmemory)
+#  A     Alias for g$lshzxe, so that the "AKE" string means all the events.
+#
+#  The "notify-keyspace-events" takes as argument a string that is composed
+#  of zero or multiple characters. The empty string means that notifications
+#  are disabled.
+#
+#  Example: to enable list and generic events, from the point of view of the
+#           event name, use:
+#
+#  notify-keyspace-events Elg
+#
+#  Example 2: to get the stream of the expired keys subscribing to channel
+#             name __keyevent@0__:expired use:
+#
+#  notify-keyspace-events Ex
+#
+#  By default all notifications are disabled because most users don't need
+#  this feature and the feature has some overhead. Note that if you don't
+#  specify at least one of K or E, no events will be delivered.
+notify-keyspace-events Ex
+
+############################### ADVANCED CONFIG ###############################
+
+# Hashes are encoded using a memory efficient data structure when they have a
+# small number of entries, and the biggest entry does not exceed a given
+# threshold. These thresholds can be configured using the following directives.
+hash-max-ziplist-entries 512
+hash-max-ziplist-value 64
+
+# Similarly to hashes, small lists are also encoded in a special way in order
+# to save a lot of space. The special representation is only used when
+# you are under the following limits:
+list-max-ziplist-entries 512
+list-max-ziplist-value 64
+
+# Sets have a special encoding in just one case: when a set is composed
+# of just strings that happen to be integers in radix 10 in the range
+# of 64 bit signed integers.
+# The following configuration setting sets the limit in the size of the
+# set in order to use this special memory saving encoding.
+set-max-intset-entries 512
+
+# Similarly to hashes and lists, sorted sets are also specially encoded in
+# order to save a lot of space. This encoding is only used when the length and
+# elements of a sorted set are below the following limits:
+zset-max-ziplist-entries 128
+zset-max-ziplist-value 64
+
+# HyperLogLog sparse representation bytes limit. The limit includes the
+# 16 bytes header. When an HyperLogLog using the sparse representation crosses
+# this limit, it is converted into the dense representation.
+#
+# A value greater than 16000 is totally useless, since at that point the
+# dense representation is more memory efficient.
+#
+# The suggested value is ~ 3000 in order to have the benefits of
+# the space efficient encoding without slowing down too much PFADD,
+# which is O(N) with the sparse encoding. The value can be raised to
+# ~ 10000 when CPU is not a concern, but space is, and the data set is
+# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
+hll-sparse-max-bytes 3000
+
+# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
+# order to help rehashing the main Redis hash table (the one mapping top-level
+# keys to values). The hash table implementation Redis uses (see dict.c)
+# performs a lazy rehashing: the more operation you run into a hash table
+# that is rehashing, the more rehashing "steps" are performed, so if the
+# server is idle the rehashing is never complete and some more memory is used
+# by the hash table.
+#
+# The default is to use this millisecond 10 times every second in order to
+# actively rehash the main dictionaries, freeing memory when possible.
+#
+# If unsure:
+# use "activerehashing no" if you have hard latency requirements and it is
+# not a good thing in your environment that Redis can reply from time to time
+# to queries with 2 milliseconds delay.
+#
+# use "activerehashing yes" if you don't have such hard requirements but
+# want to free memory asap when possible.
+activerehashing yes
+
+# The client output buffer limits can be used to force disconnection of clients
+# that are not reading data from the server fast enough for some reason (a
+# common reason is that a Pub/Sub client can't consume messages as fast as the
+# publisher can produce them).
+#
+# The limit can be set differently for the three different classes of clients:
+#
+# normal -> normal clients including MONITOR clients
+# slave  -> slave clients
+# pubsub -> clients subscribed to at least one pubsub channel or pattern
+#
+# The syntax of every client-output-buffer-limit directive is the following:
+#
+# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
+#
+# A client is immediately disconnected once the hard limit is reached, or if
+# the soft limit is reached and remains reached for the specified number of
+# seconds (continuously).
+# So for instance if the hard limit is 32 megabytes and the soft limit is
+# 16 megabytes / 10 seconds, the client will get disconnected immediately
+# if the size of the output buffers reach 32 megabytes, but will also get
+# disconnected if the client reaches 16 megabytes and continuously overcomes
+# the limit for 10 seconds.
+#
+# By default normal clients are not limited because they don't receive data
+# without asking (in a push way), but just after a request, so only
+# asynchronous clients may create a scenario where data is requested faster
+# than it can read.
+#
+# Instead there is a default limit for pubsub and slave clients, since
+# subscribers and slaves receive data in a push fashion.
+#
+# Both the hard or the soft limit can be disabled by setting them to zero.
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit slave 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+
+# Redis calls an internal function to perform many background tasks, like
+# closing connections of clients in timeout, purging expired keys that are
+# never requested, and so forth.
+#
+# Not all tasks are performed with the same frequency, but Redis checks for
+# tasks to perform according to the specified "hz" value.
+#
+# By default "hz" is set to 10. Raising the value will use more CPU when
+# Redis is idle, but at the same time will make Redis more responsive when
+# there are many keys expiring at the same time, and timeouts may be
+# handled with more precision.
+#
+# The range is between 1 and 500, however a value over 100 is usually not
+# a good idea. Most users should use the default of 10 and raise this up to
+# 100 only in environments where very low latency is required.
+hz 10
+
+# When a child rewrites the AOF file, if the following option is enabled
+# the file will be fsync-ed every 32 MB of data generated. This is useful
+# in order to commit the file to the disk more incrementally and avoid
+# big latency spikes.
+aof-rewrite-incremental-fsync yes

+ 6 - 6
docker/compose/xyzt-sender/docker-compose.yml

@@ -4,11 +4,11 @@ services:
   sendsrv:
     image: php-swool-redis:latest
     volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../../../../:/var/www/html
       - /nfs/upload:/var/www/html/data/upload
       - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/xyzt-php-swoole.ini:/usr/local/etc/php/php.ini
+      - ../conf/php/php-swoole.ini:/usr/local/etc/php/php.ini
     container_name: "worker-sender"
     command: [php,"/var/www/html/server/send_refill.php"]
     deploy:
@@ -19,11 +19,11 @@ services:
   sendexsrv:
     image: php-swool-redis:latest
     volumes:
-      - ../../conf/etc/localtime:/etc/localtime:ro
-      - ../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../../../../:/var/www/html
       - /nfs/upload:/var/www/html/data/upload
       - /mnt/testlog:/var/www/html/data/log
-      - ../../conf/php/xyzt-php-swoole.ini:/usr/local/etc/php/php.ini
+      - ../conf/php/php-swoole.ini:/usr/local/etc/php/php.ini
     container_name: "worker-senderex"
     command: [php,"/var/www/html/server/send_refillex.php"]
     deploy:

+ 47 - 0
docker/compose/xyzt/stat/docker-compose.yml

@@ -0,0 +1,47 @@
+version: "3.7"
+
+services:
+  readersrv:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-reader"
+    command: ['python','reader.py', '-h', '172.26.105.127', '-p', '6379']
+
+  mchreadersrv:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-mchreader"
+    command: ['python','mchreader.py', '-h', '172.26.105.127', '-p', '6379']
+
+  ratiosrv:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - /mnt/testlog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-ratio"
+    command: ['python','ratio.py', '-h', '172.26.105.127', '-p', '6379']
+
+  flasksrv:
+    image: pycpu:3.7.10
+    ports:
+      - "5000:5000"
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-flask"
+    command: ['python','app.py']

+ 36 - 0
docker/compose/xyzt/storage/docker-compose.yml

@@ -0,0 +1,36 @@
+version: "3.7"
+
+services:
+  redisrv:
+    image: redis:alpine
+    ports:
+      - "6379:6379"
+    volumes:
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/redis/6379.conf:/etc/redis/redis.conf
+      - /mnt/tredisdata:/data
+    container_name: "panda-redis"
+    command: [redis-server,"/etc/redis/redis.conf"]
+
+  crontabsrv:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - ../conf/crontab/root:/var/spool/cron/crontabs/root
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+    container_name: "panda-crontab"
+    command: [crond,"-f"]
+
+  cronsec:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php.ini:/usr/local/etc/php/php.ini
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/testlog:/var/www/html/data/log
+    container_name: "panda-cronsec"
+    command: [php,"/var/www/html/crontab/index.php",'minutes','second_queue']

+ 5 - 5
docker/conf/crontab/root

@@ -5,13 +5,13 @@
 0	2	*	*	*	run-parts /etc/periodic/daily
 0	3	*	*	6	run-parts /etc/periodic/weekly
 0	5	1	*	*	run-parts /etc/periodic/monthly
-0   3   *   *   *   php /var/www/html/crontab/index.php date index
+#0   3   *   *   *   php /var/www/html/crontab/index.php date index
 0   4   *   *   *   php /var/www/html/crontab/index.php date forth_clock
-0   9   *   *   *   php /var/www/html/crontab/index.php date nine_clock
-0   10  *   *   *   php /var/www/html/crontab/index.php date ten_clock
+#0   9   *   *   *   php /var/www/html/crontab/index.php date nine_clock
+#0   10  *   *   *   php /var/www/html/crontab/index.php date ten_clock
 *    *   *   *   *   php /var/www/html/crontab/index.php minutes index
-0   10-20/1 *   *   *   php /var/www/html/crontab/index.php hour index
-0   3   1   */1 *   php /var/www/html/crontab/index.php month index
+#0   10-20/1 *   *   *   php /var/www/html/crontab/index.php hour index
+#0   3   1   */1 *   php /var/www/html/crontab/index.php month index
 *    *   *   *   *   echo "test" >> /var/test.log
 
 #0   1   *   *   *   php /var/www/html/crontab/index.php date _order_stats

文件差異過大導致無法顯示
+ 1941 - 1941
docker/conf/php/xyz-php.ini


+ 2 - 0
global.php

@@ -124,6 +124,8 @@ define('ORDER_STATE_QUEUE', 50);
 
 define('ORDER_STATE_NOEXIST', 60);
 
+define('ORDER_STATE_HANDLED', 70);
+
 //未付款订单,自动取消的分钟
 define('VRORDER_AUTO_CANCEL_MINUTE', 10); //
 //未付款订单,自动取消的天数

+ 31 - 34
helper/fcgisrv/MobileServer.php

@@ -97,45 +97,42 @@ class MobileServer extends BaseServer
                     Log::record("Call {$file}",Log::DEBUG);
                     include $file;
                 }
-                else
+                elseif(defined('COMPANY_NAME') && COMPANY_NAME === 'XYZ_COMPANY')
                 {
                     //部分控制器不需要使用session.
-                    if(defined('COMPANY_NAME') && COMPANY_NAME === 'XYZ_COMPANY')
-                    {
-                        $act = $_GET['act'];
-                        if ($act == 'refill') {
-                            Base::mobile_control();
-                        } else {
-                            fcgi_header("Content-Type: text/html; charset=UTF-8");
-                            echo "no such file.";
-                        }
-                        session::instance()->end(false);
+                    $act = $_GET['act'];
+                    if ($act == 'refill') {
+                        Base::mobile_control();
+                    } else {
+                        fcgi_header("Content-Type: text/html; charset=UTF-8");
+                        echo "no such file.";
+                    }
+                    session::instance()->end(false);
+                }
+                else
+                {
+                    if(!isset($_GET['act'])) {
+                        $_GET['act'] = 'index';
+                    }
+                    if(!isset($_GET['op'])) {
+                        $_GET['op'] = 'index';
+                    }
+                    if(!isset($_POST['act'])) {
+                        $_POST['act'] = 'index';
+                    }
+                    if(!isset($_POST['op'])) {
+                        $_POST['op'] = 'index';
                     }
-                    else
-                    {
-                        if(!isset($_GET['act'])) {
-                            $_GET['act'] = 'index';
-                        }
-                        if(!isset($_GET['op'])) {
-                            $_GET['op'] = 'index';
-                        }
-                        if(!isset($_POST['act'])) {
-                            $_POST['act'] = 'index';
-                        }
-                        if(!isset($_POST['op'])) {
-                            $_POST['op'] = 'index';
-                        }
-
-                        //部分控制器不需要使用session.
-                        $act = $_GET['act'];
-                        if($act != 'refill') {
-                            session::instance()->start();
-                            Log::record("member_id=" . session_helper::memberid(),Log::DEBUG);
-                        }
 
-                        Base::mobile_control();
-                        session::instance()->end(true);
+                    //部分控制器不需要使用session.
+                    $act = $_GET['act'];
+                    if($act != 'refill') {
+                        session::instance()->start();
+                        Log::record("member_id=" . session_helper::memberid(),Log::DEBUG);
                     }
+
+                    Base::mobile_control();
+                    session::instance()->end(true);
                 }
             }
             else

+ 0 - 2
helper/message/msgutil.php

@@ -138,8 +138,6 @@ class StatesHelper
 
 function handler_redis($redis, $chan, $msg)
 {
-    Log::record("message: {$chan} -- {$msg}",Log::DEBUG);
-
     if (defined('UGC_SUBSCRIBER_PROC') && UGC_SUBSCRIBER_PROC == true)
     {
         if($chan == 'special') {

+ 1 - 2
helper/message/subscriber.php

@@ -58,14 +58,13 @@ class subscriber extends Thread
             catch (Exception $ex)
             {
                 Log::record("subscriber quit err={$ex->getMessage()} code={$ex->getCode()}");
+                sleep(5);
             }
         }
     }
 
     public function dispatch($channel,$msg)
     {
-        Log::record("subscriber dispatch ch={$channel} msg={$msg}",Log::DEBUG);
-
         if(empty($msg)) return false;
         $msg = json_decode($msg,true);
         if($msg == false || !is_array($msg)) {

+ 0 - 0
helper/mtopcard/mtopcard.php


部分文件因文件數量過多而無法顯示