Browse Source

add background task

stanley-king 3 năm trước cách đây
mục cha
commit
a307ea83fd

+ 12 - 0
admin/control/control.php

@@ -486,4 +486,16 @@ class SystemControl
         $this->log($log_msg, 1);
         return [true, 'success'];
     }
+
+    protected function task_hash_check($condition, $task_type)
+    {
+        $model = Model('refill_task');
+        $hash = md5(serialize($condition) . $task_type);
+        $check = $model->HashCheck($hash);
+        if($check) {
+            return $hash;
+        }else{
+            return false;
+        }
+    }
 }

+ 1 - 66
admin/control/orderstats.php

@@ -151,7 +151,7 @@ class orderstatsControl extends SystemControl
         }
         $task_list = $model->getList($condition, 50);
         foreach ($task_list as $key => $value) {
-            $task_list[$key]['condition'] = unserialize($value['task_condition']);
+            $task_list[$key]['condition'] = unserialize($value['task_params']);
         }
 
         Tpl::output('list', $task_list);
@@ -164,71 +164,6 @@ class orderstatsControl extends SystemControl
         Tpl::showpage('refill.task');
     }
 
-    public function task_addOp()
-    {
-        if(chksubmit())
-        {
-            $obj_validate = new Validator();
-            $obj_validate->validateparam = [
-                ["input" => $_POST["task_type"], "require" => "true", "message" => '请选择任务类型'],
-                ["input" => $_POST["type"], "require" => "true", "message" => '请选择主体类型'],
-                ["input" => $_POST["body"], "require" => "true", "message" => '请选择统计主体'],
-                ["input" => $_POST["order_time_type"], "require" => "true", "message" => '请选择日期类型'],
-                ["input" => $_POST["query_start_time"], "require" => "true", "message" => '请选择统计日期'],
-            ];
-            $error = $obj_validate->validate();
-            if ($error != '') {
-                showMessage($error, '', '', 'error');
-            }
-            $body = explode('-', $_POST['body']);
-            $insert['task_type'] = $_POST['task_type'];
-            $insert['type'] = $_POST['type'];
-            $insert['cid'] = $body[0];
-            $insert['cname'] = $body[1];
-            $insert['add_time'] = time();
-
-            $order_time_type = $_POST['order_time_type'];
-            $condition['start_unixtime'] = intval(strtotime($_POST['query_start_time']));
-            $condition['end_unixtime'] = intval(strtotime($_POST['query_end_time']));
-            $condition['order_time_type'] = $order_time_type;
-            $condition['order_state'] = $_POST['order_state'] ?? '';
-
-            $hash = $this->task_hash_check($condition, $insert['task_type'], $insert['type']);
-            if($hash === false) {
-                showMessage('此任务已存在,如需重新执行,请删除已存在的任务');
-            }
-            $insert['task_hash'] = $hash;
-            $insert['task_condition'] = serialize($condition);
-
-            $model = Model('refill_task');
-            $resp = $model->insert($insert);
-            if($resp) {
-                showMessage('录入成功', 'index.php?act=OrderStats&&op=refill_task');
-            }else{
-                showMessage('任务添加失败');
-            }
-        }
-        else
-        {
-            Tpl::output('task_type', $this->task_type);
-            Tpl::output('type', $this->type);
-            Tpl::output('order_time_type', $this->order_time_type);
-            Tpl::showpage('refill.task.add');
-        }
-    }
-
-    private function task_hash_check($condition, $task_type, $type)
-    {
-        $model = Model('refill_task');
-        $hash = md5(serialize($condition) . $task_type . $type);
-        $check = $model->HashCheck($hash);
-        if($check) {
-            return $hash;
-        }else{
-            return false;
-        }
-    }
-
     public function task_delOp()
     {
         $task_id = $_GET['task_id'];

+ 65 - 68
admin/control/refill_order.php

@@ -1,8 +1,8 @@
 <?php
 
 require_once(BASE_HELPER_PATH . '/refill/util.php');
+require_once(BASE_HELPER_PATH . '/task/task_helper.php');
 
-use refill\util;
 class refill_orderControl extends SystemControl
 {
     public function __construct()
@@ -19,66 +19,66 @@ class refill_orderControl extends SystemControl
     public function refill_order($fShowStat = false)
     {
         $model_refill_order = Model('refill_order');
-        $condition['inner_status'] = 0;
+        $cond['inner_status'] = 0;
         $_GET['query_start_time'] = $_GET['query_start_time'] ?? date("Y-m-d H:i:s", strtotime("-1 hours"));
 
         if (!empty($_GET['order_sn'])) {
-            $condition['refill_order.order_sn'] = $_GET['order_sn'];
+            $cond['refill_order.order_sn'] = $_GET['order_sn'];
 
         }
         if (!empty($_GET['mch_order'])) {
-            $condition['refill_order.mch_order'] = $_GET['mch_order'];
+            $cond['refill_order.mch_order'] = $_GET['mch_order'];
 
         }
         if (!empty($_GET['ch_trade_no'])) {
-            $condition['refill_order.ch_trade_no'] = $_GET['ch_trade_no'];
+            $cond['refill_order.ch_trade_no'] = $_GET['ch_trade_no'];
 
         }
         if (!empty($_GET['card_no'])) {
-            $condition['refill_order.card_no'] = $_GET['card_no'];
+            $cond['refill_order.card_no'] = $_GET['card_no'];
 
         }
         if (!empty($_GET['no_mchid'])) {
             $no_mchid = explode(',', $_GET['no_mchid']);
-            $condition['refill_order.mchid'] = ['not in', $no_mchid];
+            $cond['refill_order.mchid'] = ['not in', $no_mchid];
         }
         if (!empty($_GET['no_amount'])) {
             $no_amount = explode(',', $_GET['no_amount']);
-            $condition['refill_order.refill_amount'] = ['not in', $no_amount];
+            $cond['refill_order.refill_amount'] = ['not in', $no_amount];
         }
 
         if (!empty($_GET['mchid'])) {
-            $condition['refill_order.mchid'] = $_GET['mchid'];
+            $cond['refill_order.mchid'] = $_GET['mchid'];
         }
         if (!empty($_GET['channel_name'])) {
-            $condition['refill_order.channel_name'] = $_GET['channel_name'];
+            $cond['refill_order.channel_name'] = $_GET['channel_name'];
         }
         if (!empty($_GET['store_id'])) {
-            $condition['vr_order.store_id'] = $_GET['store_id'];
+            $cond['vr_order.store_id'] = $_GET['store_id'];
         }
         if (!empty($_GET['refill_amount'])) {
-            $condition['refill_order.refill_amount'] = $_GET['refill_amount'];
+            $cond['refill_order.refill_amount'] = $_GET['refill_amount'];
         }
         if (!empty($_GET['quality'])) {
-            $condition['refill_order.quality'] = $_GET['quality'];
+            $cond['refill_order.quality'] = $_GET['quality'];
         }
         if(!empty($_GET['official_status'])) {
             if($_GET['official_status'] == 1) {
-                $condition['official_sn'] = '';
+                $cond['official_sn'] = '';
             } elseif ($_GET['official_status'] == 2) {
-                $condition['official_sn'] = ['neq', ''];
+                $cond['official_sn'] = ['neq', ''];
             }
         }
 
         if (!empty($_GET['card_type'])) {
             if (in_array($_GET['card_type'], ['1', '2', '4', '5', '6', '7'])) {
-                $condition['refill_order.card_type'] = intval($_GET['card_type']);
+                $cond['refill_order.card_type'] = intval($_GET['card_type']);
             }
             if ($_GET['card_type'] == 'oil') {
-                $condition['refill_order.card_type'] = ['in', [1, 2]];
+                $cond['refill_order.card_type'] = ['in', [1, 2]];
             }
             if ($_GET['card_type'] == 'phone') {
-                $condition['refill_order.card_type'] = ['in', [4, 5, 6]];
+                $cond['refill_order.card_type'] = ['in', [4, 5, 6]];
             }
         }
 
@@ -87,56 +87,58 @@ class refill_orderControl extends SystemControl
         $end_unixtime = intval(strtotime($_GET['query_end_time']));
 
         if($end_unixtime <= 0) {
-            $end_unixtime = time();
+            $cur_time = time();
+            $cur_time = $cur_time - ($cur_time % 300) + 300;
+            $end_unixtime = $cur_time;
         }
 
         if ($start_unixtime > 0 && $end_unixtime > $start_unixtime) {
-            $condition['refill_order.order_time'] = [['egt', $start_unixtime], ['lt', $end_unixtime], 'and'];
-            $condition['vr_order.add_time'] = [['egt', $start_unixtime],['lt', $end_unixtime], 'and'];
+            $cond['refill_order.order_time'] = [['egt', $start_unixtime], ['lt', $end_unixtime], 'and'];
+            $cond['vr_order.add_time'] = [['egt', $start_unixtime],['lt', $end_unixtime], 'and'];
         } elseif ($start_unixtime > 0) {
-            $condition['refill_order.order_time'] = ['egt', $start_unixtime];
-            $condition['vr_order.add_time'] = ['egt', $start_unixtime];
+            $cond['refill_order.order_time'] = ['egt', $start_unixtime];
+            $cond['vr_order.add_time'] = ['egt', $start_unixtime];
         } elseif ($end_unixtime > 0) {
-            $condition['refill_order.order_time'] = ['lt', $end_unixtime];
+            $cond['refill_order.order_time'] = ['lt', $end_unixtime];
         } else {
             $start = time() - 3600;
             $_GET['query_start_time'] = date("Y-m-d H:i:s",$start);
-            $condition['refill_order.order_time'] = ['egt', $start];
-            $condition['vr_order.add_time'] = ['egt', $start-1];
+            $cond['refill_order.order_time'] = ['egt', $start];
+            $cond['vr_order.add_time'] = ['egt', $start-1];
             $fToday = true;
         }
 
         if(in_array($_GET['cardno_state'], ['0','1', '2', '4', '5'])) {
-            $condition['refill_order.cardno_state'] = $_GET['cardno_state'];
+            $cond['refill_order.cardno_state'] = $_GET['cardno_state'];
         }
         if(in_array($_GET['is_transfer'], ['0','1'])) {
-            $condition['refill_order.is_transfer'] = $_GET['is_transfer'];
+            $cond['refill_order.is_transfer'] = $_GET['is_transfer'];
         }
 
         if (in_array($_GET['order_state'], ['0', '10', '20', '30', '40']))
         {
-            $condition['vr_order.order_state'] = $_GET['order_state'];
+            $cond['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)]];
+                    $cond['refill_order.order_time'] = ['between', [(time() - 3600), (time() - 1800)]];
                 }
                 if ($_GET['time'] == 2) {
-                    $condition['refill_order.order_time'] = ['lt', (time() - 3600)];
+                    $cond['refill_order.order_time'] = ['lt', (time() - 3600)];
                 }
             }
         }
 
         if (!empty($_GET['export']) || !empty($_GET['export_stats'])) {
-            $this->RefillOrderExport($condition);
+            $this->RefillOrderExport($cond);
             exit;
         }
         if (!empty($_GET['mch_notify'])) {
-            $this->mch_notify($condition);
+            $this->mch_notify($cond);
             exit;
         }
         if (!empty($_GET['order_query'])) {
-            $this->updateOrderSend($condition);
+            $this->updateOrderSend($cond);
             exit;
         }
         $merchants = [];
@@ -144,7 +146,7 @@ class refill_orderControl extends SystemControl
         foreach ($merchant_list as $value) {
             $merchants[$value['mchid']] = $value;
         }
-        $order_list = $model_refill_order->getMerchantOrderList($condition, 200, 'refill_order.*,vr_order.order_state', 'refill_order.order_time desc');
+        $order_list = $model_refill_order->getMerchantOrderList($cond, 200, 'refill_order.*,vr_order.order_state', 'refill_order.order_time desc');
 
         foreach ($order_list as $order_id => $order_info) {
             $order_list[$order_id]['card_type_text'] = $this->scard_type($order_info['card_type']);
@@ -162,9 +164,15 @@ class refill_orderControl extends SystemControl
 
         $provider_list = $this->providers();
 
-        if ($fShowStat) {
-            $stat = $this->all_order_state_stat($condition);
-            Tpl::output('stat', $stat);
+        if ($fShowStat)
+        {
+            $manager = new task\manager();
+            $task = $manager->add_task('refill_order_stat',$cond,0);
+            if($task->completed() && $task->success())
+            {
+                $stat = $task->result();
+                Tpl::output('stat', $stat);
+            }
         }
 
         $dispatcher_queue_length = refill\util::dispatcher_queue_length();
@@ -187,8 +195,23 @@ class refill_orderControl extends SystemControl
                 unset($condition['vr_order.add_time']);
             }
         }
-        $result = $this->getAllOrders($condition);
-        $this->createExcel($result);
+//        $result = Model('refill_order')->getAllOrders($condition);
+//        $this->createExcel($result);
+
+        $hash = $this->task_hash_check($condition, 'order_export');
+
+        $insert['task_type'] = 'order_export';
+        $insert['add_time'] = time();
+        $insert['task_hash'] = $hash;
+        $insert['task_params'] = serialize($condition);
+
+        $model = Model('refill_task');
+        $resp = $model->insert($insert);
+        if($resp) {
+            showMessage("录入成功,任务ID:{$resp}", 'index.php?act=OrderStats&&op=refill_task');
+        }else{
+            showMessage('任务添加失败');
+        }
     }
 
     private function createExcel($data = array())
@@ -386,7 +409,7 @@ class refill_orderControl extends SystemControl
         $condition['inner_status'] = 0;
         $condition['is_retrying'] = 0;
 
-        $orders = $this->getAllOrders($condition);
+        $orders = Model('refill_order')->getAllOrders($condition);
         if (!empty($orders))
         {
             foreach ($orders as $order)
@@ -406,7 +429,7 @@ class refill_orderControl extends SystemControl
     private function updateOrderSend($condition)
     {
         $condition['order_state'] = ORDER_STATE_SEND;
-        $orders = $this->getAllOrders($condition);
+        $orders = Model('refill_order')->getAllOrders($condition);
 
         if (!empty($orders)) {
             foreach ($orders as $order) {
@@ -417,30 +440,4 @@ class refill_orderControl extends SystemControl
         }
         showMessage('操作成功');
     }
-
-    private function getAllOrders($condition): array
-    {
-        $len = 1000;
-
-        $i = 0;
-        $orders = [];
-        while (true)
-        {
-            $start = $i * $len;
-            $items = Model('')->table('refill_order,vr_order')
-                                        ->field('refill_order.*,vr_order.order_state')
-                                        ->join('inner')
-                                        ->on('refill_order.order_id=vr_order.order_id')
-                                        ->where($condition)
-                                        ->order('refill_order.order_time desc')
-                                        ->limit("{$start},{$len}")
-                                        ->select();
-            $orders = array_merge($orders,$items);
-            if (empty($items) || count($items) < $len) {
-                break;
-            }
-            $i++;
-        }
-        return $orders;
-    }
 }

+ 14 - 23
admin/templates/default/refill.task.php

@@ -117,7 +117,6 @@
                 <li><a href="index.php?act=OrderStats&op=index&type=provider"><span>上游对账记录</span></a></li>
                 <li><a href="index.php?act=OrderStats&op=index&type=merchant"><span>下游对账记录</span></a></li>
                 <li><a href="JavaScript:void(0);" class="current"><span>任务列表</span></a></li>
-                <li><a href="index.php?act=OrderStats&op=task_add"><span>任务录入</span></a></li>
             </ul>
         </div>
     </div>
@@ -157,9 +156,6 @@
             <th class="align-center">编号</th>
             <th class="align-center">任务ID</th>
             <th class="align-center">任务类型</th>
-            <th class="align-center">主体类型</th>
-            <th class="align-center">主体ID</th>
-            <th class="align-center">主体名称</th>
             <th class="align-center">任务条件</th>
             <th class="align-center">任务状态</th>
             <th class="align-center">生成日期</th>
@@ -177,26 +173,21 @@
                     <td class="align-center"><?php echo $key + 1; ?></td>
                     <td class="align-center"><?php echo $value['task_id']; ?></td>
                     <td class="align-center"><?php echo $output['task_type'][$value['task_type']]; ?></td>
-                    <td class="align-center"><?php echo $output['type'][$value['type']]; ?></td>
-                    <td class="align-center"><?php echo $value['cid']; ?></td>
-                    <td class="align-center"><?php echo $value['cname']; ?></td>
                     <td class="align-center">
-                        <p>统计日期类型:<?php echo $output['order_time_type'][$value['condition']['order_time_type']];?></p>
-                        <p>
-                            统计日期范围:<?php echo date("Y-m-d H:i:s", $value['condition']['start_unixtime'])?>
-                            <?php if (!empty($value['condition']['end_unixtime'])) {
-                                echo '~' . date("Y-m-d H:i:s", $value['condition']['end_unixtime']);
-                            }
-                            ?>
-                        </p>
-                        <p>订单状态:
-                            <?php if ($value['condition']['order_state'] === '') {
-                                echo '/';
-                            } else {
-                                echo orderState($value['condition']);
-                            }
-                            ?>
-                        </p>
+<!--                        --><?php //if(!empty($value['condition']['refill_order.order_time'])) { ?>
+<!--                        <p>统计日期范围:-->
+<!--                            --><?php //echo date("Y-m-d H:i:s", $value['condition']['refill_order.order_time'][0][1]) ?? '/';?>
+<!--                            ~--><?php //echo date("Y-m-d H:i:s", $value['condition']['refill_order.order_time'][1][1]) ?? '/';?>
+<!--                        --><?php //}?>
+<!---->
+<!--                        <p>订单状态:-->
+<!--                            --><?php //if ($value['condition']['order_state'] === '') {
+//                                echo '/';
+//                            } else {
+//                                echo orderState($value['condition']);
+//                            }
+//                            ?>
+<!--                        </p>-->
                     </td>
                     <td class="align-center"><?php echo $output['task_state'][$value['task_state']]; ?></td>
                     <td class="align-center"><?php echo $value['add_time'] ? date('Y-m-d H:i:s', $value['add_time']) : '/'; ?></td>

+ 5 - 5
core/framework/function/goods.php

@@ -213,20 +213,20 @@ function orderState($order_info)
             if ($is_retrying) {
                 $order_state = '重试中';
             } else {
-                $order_state = L('order_state_cancel');
+                $order_state = '已取消';
             }
         break;
         case ORDER_STATE_NEW:
-            $order_state = L('order_state_new');
+            $order_state = '待付款';
         break;
         case ORDER_STATE_PAY:
-            $order_state = L('order_state_pay');
+            $order_state = '待发货';
         break;
         case ORDER_STATE_SEND:
-            $order_state = L('order_state_send');
+            $order_state = '待收货';
         break;
         case ORDER_STATE_SUCCESS:
-            $order_state = L('order_state_success');
+            $order_state = '交易完成';
         break;
     }
     return $order_state;

+ 25 - 28
crontab/control/minutes.php

@@ -15,6 +15,7 @@ require_once(BASE_HELPER_PATH . '/refill/divert_account.php');
 require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
 require_once(BASE_CORE_PATH . '/framework/function/http.php');
 require_once(BASE_HELPER_PATH . '/PHPExcel/PHPExcel.php');
+require_once(BASE_HELPER_PATH . '/task/task_helper.php');
 
 
 class minutesControl extends BaseCronControl
@@ -33,7 +34,6 @@ class minutesControl extends BaseCronControl
         $this->_fetch_order_unavaliable();
         $this->_check_merchant_alarm_amount();
 
-//        $this->_refill_task();
         Log::record(__FUNCTION__ . " end",Log::DEBUG);
 
 //        $this->_web_index_update();
@@ -409,6 +409,29 @@ class minutesControl extends BaseCronControl
         }
     }
 
+    //任务队列处理
+    public function taskOp()
+    {
+        $task_manager = new task\manager();
+        $task_id = 0;
+        while (true)
+        {
+            try
+            {
+                $task = $task_manager->pop_task($task_id);
+                if (!empty($task)) {
+                    $task_manager->handle($task);
+                    $task_id = $task['task_id'];
+                }
+            }
+            catch (Exception $ex) {
+                Log::record($ex->getMessage(),Log::ERR);
+            }
+
+            sleep(1);
+        }
+    }
+
     /**
      * 执行通用任务
      */
@@ -701,7 +724,7 @@ class minutesControl extends BaseCronControl
      */
     private function order_export($condition, $type, $task_id)
     {
-        $orders = $this->getAllOrders($condition);
+        $orders = Model('refill_order')->getAllOrders($condition);
         if(empty($orders)) {
             return [false, '统计数据为空'];
         }
@@ -752,32 +775,6 @@ class minutesControl extends BaseCronControl
         }
     }
 
-    private function getAllOrders($condition): array
-    {
-        $len = 1000;
-
-        $i = 0;
-        $orders = [];
-        while (true)
-        {
-            $start = $i * $len;
-            $items = Model('')->table('refill_order,vr_order')
-                ->field('refill_order.*,vr_order.order_state')
-                ->join('inner')
-                ->on('refill_order.order_id=vr_order.order_id')
-                ->where($condition)
-                ->order('refill_order.order_time desc')
-                ->limit("{$start},{$len}")
-                ->select();
-            $orders = array_merge($orders,$items);
-            if (empty($items) || count($items) < $len) {
-                break;
-            }
-            $i++;
-        }
-        return $orders;
-    }
-
     private function orderFormat($orders): array
     {
         $card_type_texts = [mtopcard\PetroChinaCard => '中石油', mtopcard\SinopecCard => '中石化', mtopcard\ChinaMobileCard => '中国移动', mtopcard\ChinaUnicomCard => '中国联通', mtopcard\ChinaTelecomCard => '中国电信'];

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

@@ -86,4 +86,30 @@ class refill_orderModel extends Model
         $item = $this->table('refill_detail')->where(['mchid' => $mchid,'mch_order' => $mch_order])->select();
         return !empty($item);
     }
+
+    public function getAllOrders($condition)
+    {
+        $len = 1000;
+
+        $i = 0;
+        $orders = [];
+        while (true)
+        {
+            $start = $i * $len;
+            $items = $this->table('refill_order,vr_order')
+                ->field('refill_order.*,vr_order.order_state')
+                ->join('inner')
+                ->on('refill_order.order_id=vr_order.order_id')
+                ->where($condition)
+                ->order('refill_order.order_time desc')
+                ->limit("{$start},{$len}")
+                ->select();
+            $orders = array_merge($orders,$items);
+            if (empty($items) || count($items) < $len) {
+                break;
+            }
+            $i++;
+        }
+        return $orders;
+    }
 }

+ 72 - 74
data/model/refill_task.model.php

@@ -1,75 +1,73 @@
-<?php
-
-defined('InShopNC') or exit('Access Invalid!');
-
-class refill_taskModel extends Model
-{
-    const DisposeState = 2;
-    const FinishState = 3;
-    const ErrState = 4;
-
-    public function __construct()
-    {
-        parent::__construct('refill_task');
-    }
-
-    public function getList($condition, $pagesize = '', $field = '*', $order = 'add_time desc', $limit = '', $master = false): array
-    {
-        $condition['is_del'] = 0;
-        $list = $this->field($field)->where($condition)->page($pagesize)->order($order)->limit($limit)->master($master)->select();
-        if (empty($list)) return [];
-        return $list;
-    }
-
-    public function HashCheck($hash): bool
-    {
-        $condition['is_del'] = 0;
-        $condition['task_hash'] = $hash;
-        return empty($this->where($condition)->find());
-    }
-
-    public function UnDispose($task_type): array
-    {
-        $condition['is_del'] = 0;
-        $condition['task_state'] = 1;
-        $condition['task_type'] = $task_type;
-        $task = $this->where($condition)->order('add_time asc')->find();
-        if (empty($task)) return [];
-        return $task;
-    }
-
-    public function Dispose($task_id)
-    {
-        $condition['is_del'] = 0;
-        $condition['task_id'] = $task_id;
-        return $this->where($condition)->update(
-            ['task_state' => self::DisposeState, 'dispose_time' => time()]
-        );
-    }
-
-    public function DisposeErr($task_id, $err_msg)
-    {
-        $condition['is_del'] = 0;
-        $condition['task_id'] = $task_id;
-        return $this->where($condition)->update(
-            ['task_state' => self::ErrState, 'task_result' => $err_msg, 'finish_time' => time()]
-        );
-    }
-
-    public function DisposeFinish($task_id, $result)
-    {
-        $condition['is_del'] = 0;
-        $condition['task_id'] = $task_id;
-        return $this->where($condition)->update(
-            ['task_state' => self::FinishState, 'task_result' => $result, 'finish_time' => time()]
-        );
-    }
-
-    public function Del($task_id)
-    {
-        $condition['task_id'] = $task_id;
-        return $this->where($condition)->update(
-            ['is_del' => 1]
-        );
-    }
+<?php
+
+defined('InShopNC') or exit('Access Invalid!');
+
+class taskModel extends Model
+{
+    const DisposeState = 2;
+    const FinishState = 3;
+    const ErrState = 4;
+
+    public function __construct()
+    {
+        parent::__construct('task');
+    }
+
+    public function getList($condition, $pagesize = '', $field = '*', $order = 'add_time desc', $limit = '', $master = false): array
+    {
+        $list = $this->field($field)->where($condition)->page($pagesize)->order($order)->limit($limit)->master($master)->select();
+        if (empty($list)) return [];
+        return $list;
+    }
+
+    public function getByHash($hash)
+    {
+        $condition['task_hash'] = $hash;
+        return $this->where($condition)->find();
+    }
+
+
+    public function UnDispose(): array
+    {
+        $condition['is_del'] = 0;
+        $condition['task_state'] = 1;
+        $task = $this->where($condition)->order('add_time asc')->find();
+        if (empty($task)) return [];
+        return $task;
+    }
+
+    public function Dispose($task_id)
+    {
+        $condition['is_del'] = 0;
+        $condition['task_id'] = $task_id;
+        return $this->where($condition)->update(
+            ['task_state' => self::DisposeState, 'dispose_time' => time()]
+        );
+    }
+
+    public function DisposeErr($task_id, $err_msg)
+    {
+        $condition['is_del'] = 0;
+        $condition['task_id'] = $task_id;
+        return $this->where($condition)->update(
+            ['task_state' => self::ErrState, 'task_result' => $err_msg, 'finish_time' => time()]
+        );
+    }
+
+    public function DisposeFinish($task_id, $result)
+    {
+        $condition['is_del'] = 0;
+        $condition['task_id'] = $task_id;
+        return $this->where($condition)->update(
+            ['task_state' => self::FinishState, 'task_result' => $result, 'finish_time' => time()]
+        );
+    }
+
+    public function Del($task_id)
+    {
+        $condition['task_id'] = $task_id;
+        return $this->where($condition)->update(
+            ['is_del' => 1]
+        );
+    }
 }

+ 12 - 1
docker/compose/stanley/master-cron/docker-compose.yml

@@ -33,4 +33,15 @@ services:
       - ../conf/etc/localtime:/etc/localtime:ro
       - ../conf/php/php-debug.ini:/usr/local/etc/php/php.ini
     container_name: "panda-accedit"
-    command: [php,"/var/www/html/crontab/index.php",'minutes','account_edit']
+    command: [php,"/var/www/html/crontab/index.php",'minutes','account_edit']
+
+  crontask:
+    image: php-zts-debug:7.3.18
+    volumes:
+      - ../../../../:/var/www/html
+      - /Volumes/Transcend/upload:/var/www/html/data/upload
+      - /Users/stanley-king/work/PHPProject/shoplog:/var/www/html/data/log
+      - ../conf/etc/localtime:/etc/localtime:ro
+      - ../conf/php/php-debug.ini:/usr/local/etc/php/php.ini
+    container_name: "panda-task"
+    command: [php,"/var/www/html/crontab/index.php",'minutes','task']

+ 13 - 1
docker/compose/xyz/slave-crond/docker-compose.yml

@@ -15,4 +15,16 @@ services:
     deploy:
       resources:
         limits:
-          cpus: '8'
+          cpus: '8'
+
+  crontask:
+    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/slave_root:/var/spool/cron/crontabs/root
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+    container_name: "panda-task"
+    command: [php,"/var/www/html/crontab/index.php",'minutes','task']

+ 8 - 0
helper/refill/api/xyz/feimingyu/北京椰子对接信息.txt

@@ -0,0 +1,8 @@
+客户端入口:http://47.98.163.205:80/
+下单接口:http://47.98.163.205:80/recharge/buy.do
+订单查询:http://47.98.163.205:80/recharge/query.do
+余额查询:http://47.98.163.205:80/user/balance.do
+帐号:北京椰子
+密码:123456
+用户编号:69876
+秘钥:AC7F7353AAA6

+ 56 - 0
helper/task/handler.php

@@ -0,0 +1,56 @@
+<?php
+
+
+namespace task;
+
+use Exception;
+
+class handler
+{
+    public function refill_order_stat($condition)
+    {
+        try
+        {
+            $items = Model('')->table('refill_order,vr_order')
+                ->field('count(*) as order_count, sum(refill_amount) as refill_amounts, sum(channel_amount) as channel_amounts, sum(mch_amount) as mch_amounts, order_state')
+                ->join('inner')
+                ->on('refill_order.order_id=vr_order.order_id')
+                ->where($condition)
+                ->group('order_state')
+                ->select();
+
+            $all = [];
+            $data['order_count'] = $data['refill_amounts'] = $data['channel_amounts'] = $data['mch_amounts'] = 0;
+            $sending = $success = $cancel = $data;
+            foreach ($items as $item)
+            {
+                if ($item['order_state'] == ORDER_STATE_SEND) {
+                    $sending = $item;
+                } elseif ($item['order_state'] == ORDER_STATE_SUCCESS) {
+                    $success = $item;
+                } elseif ($item['order_state'] == ORDER_STATE_CANCEL) {
+                    $cancel = $item;
+                }
+
+                $all['order_count'] += $item['order_count'];
+                $all['refill_amounts'] += ncPriceFormat($item['refill_amounts']);
+                $all['channel_amounts'] += ncPriceFormat($item['channel_amounts']);
+                $all['mch_amounts'] += ncPriceFormat($item['mch_amounts']);
+            }
+
+            $result = ['all' => $all, 'sending' => $sending, 'success' => $success, 'cancel' => $cancel];
+
+            return [true,$result];
+
+        }
+        catch (Exception $ex)
+        {
+            return [false,false];
+        }
+    }
+
+    public function refill_order_stat_title($condition)
+    {
+        return md5("refill_order_stat-".serialize($condition));
+    }
+}

+ 105 - 0
helper/task/manager.php

@@ -0,0 +1,105 @@
+<?php
+
+namespace task;
+
+use Exception;
+use trans_wapper;
+
+class manager
+{
+    private $mHandler;
+    public function __construct()
+    {
+        $this->mHandler = new handler();
+    }
+
+    public function add_task($method,$params,$is_show = 1)
+    {
+        if(empty($method) || empty($params)) {
+            return false;
+        }
+
+        //task 唯一性
+        $hash_fun = function ($method,$params) {
+            $val = $method . '-' . serialize($params);
+            return md5($val);
+        };
+        $task_hash = $hash_fun($method,$params);
+
+        $title_fun = "{$method}_title";
+        $title = $this->mHandler->$title_fun($params);
+
+        $mod_task = Model('task');
+        $item = $mod_task->getByHash($task_hash);
+        if(empty($item))
+        {
+            $item = ['type' => $method, 'title' => $title,
+                     'params' => serialize($params), 'task_hash' => $task_hash,
+                     'add_time' => time(), 'is_show' => $is_show];
+            $task_id = $mod_task->insert($item);
+            $item = $mod_task->where(['task_id' => $task_id])->find();
+        }
+
+        return task_wrapper::CreateTask($item);
+    }
+
+    //弹出一个任务,并且将任务设为进行中
+    public function pop_task($task_id)
+    {
+        $mod_task = Model('task');
+        $trans = new trans_wapper($mod_task,'pop_task');
+
+        try {
+            $item = $mod_task->field('*')
+                             ->where(['task_id' => ['gt',$task_id],'state' => task_wrapper::Waiting])
+                             ->master(true)->lock(true)->find();
+
+            if(!empty($item)) {
+                $mod_task->where(['task_id' => $item['task_id']])->update(['state' => task_wrapper::Processing,'act_time' => time()]);
+            }
+            $trans->commit();
+
+            return $item;
+        }
+        catch (Exception $ex)
+        {
+            $trans->rollback();
+            return [];
+        }
+    }
+
+    //任务结束,并且
+    public function fini_task($task_id,$succ)
+    {
+
+    }
+
+    public function del_task()
+    {
+
+    }
+
+    public function getResult($task)
+    {
+
+    }
+
+    public function handle($task)
+    {
+        $method = $task['type'];
+        $params = unserialize($task['params']);
+
+        $handler = new handler();
+        [$succ,$result] = $handler->$method($params);
+
+        $mod_task = Model('task');
+        if(!empty($result))
+        {
+            $mod_task->where(['task_id' => $task['task_id']])->update(['state' => task_wrapper::Handled,
+                'result_state' => $succ ? 1 : 0, 'result' => serialize($result),
+                'finish_time' => time()]);
+        }
+
+        return $task['task_id'];
+    }
+}

+ 7 - 0
helper/task/task_helper.php

@@ -0,0 +1,7 @@
+<?php
+
+namespace task;
+
+require_once(BASE_HELPER_PATH . '/task/manager.php');
+require_once(BASE_HELPER_PATH . '/task/handler.php');
+require_once(BASE_HELPER_PATH . '/task/task_wrapper.php');

+ 42 - 0
helper/task/task_wrapper.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace task;
+
+
+class task_wrapper
+{
+    //1待处理、2处理中、3已处理、4已经取消'
+    const Waiting = 1;
+    const Processing = 2;
+    const Handled = 3;
+    const Canceled = 4;
+
+    private $mRecord;
+    public function __construct($item)
+    {
+        $this->mRecord = $item;
+    }
+
+    public function completed() : bool
+    {
+        return $this->mRecord['state'] == self::Handled;
+    }
+
+    public function success() : bool {
+        return $this->mRecord['result_state'] == 1;
+    }
+
+    public function result()
+    {
+        if($this->success()) {
+            return unserialize($this->mRecord['result']);
+        } else {
+            return [];
+        }
+    }
+
+    public static function CreateTask($data)
+    {
+        return new task_wrapper($data);
+    }
+}

+ 56 - 118
test/TestExportOrder.php

@@ -10,7 +10,7 @@ define('BASE_ROOT_PATH', str_replace('/test', '', dirname(__FILE__)));
 require_once(BASE_ROOT_PATH . '/global.php');
 require_once(BASE_CORE_PATH . '/lrlz.php');
 require_once(BASE_ROOT_PATH . '/fooder.php');
-
+require_once(BASE_HELPER_PATH . '/PHPExcel/PHPExcel.php');
 
 class TestExportOrder extends TestCase
 {
@@ -22,7 +22,7 @@ class TestExportOrder extends TestCase
     public function testXingzhiyu()
     {
         $end_time = strtotime("2021-06-15");
-        $this->exoprt(10132,null,$end_time);
+        $this->exoprt(1093,null,$end_time);
     }
 
     public function exoprt($mchid,$start_time = null,$end_time = null)
@@ -74,80 +74,69 @@ class TestExportOrder extends TestCase
         fclose($fp);
     }
 
-
     public function testRefillTask()
     {
         $model_refill_task = Model('refill_task');
 
-        $task = $model_refill_task->UnDispose('order_export');
+        $task = $model_refill_task->UnDispose();
         if (empty($task)) return false;
 
         $task_id = $task['task_id'];
-        $task_condition = unserialize($task['task_condition']);
-        if (empty($task_condition)) {
-            Log::record("refill task condition unserialize err, task_id:{$task_id}");
-            return false;
+        switch ($task['task_type']) {
+            case 'order_export' :
+                $result = $this->TaskOrderExport($task,$model_refill_task);
+                break;
+            default:
+                $result = '任务类型匹配失败';
+                break;
         }
+        Log::record("refill task result:{$result}, task_id:{$task_id}");
+        return true;
+    }
 
-        $type = $task['type'];
-        $cid = $task['cid'];
-        if ($type === 'merchant') {
-            $condition['refill_order.mchid'] = $cid;
-        } elseif ($type === 'provider') {
-            $condition['vr_order.store_id'] = $cid;
-        } else {
-            Log::record("refill task type err, task_id:{$task_id}");
+    private function TaskOrderExport($task,$model_refill_task)
+    {
+        $task_id = $task['task_id'];
+        $task_params = unserialize($task['task_params']);
+        if (empty($task_params)) {
+            Log::record("refill task condition unserialize err, task_id:{$task_id}");
             return false;
         }
-        $order_time_type = $task_condition['order_time_type'];
-        $start_unixtime = $task_condition['start_unixtime'];
-        $end_unixtime = $task_condition['end_unixtime'];
-        $order_state = $task_condition['order_state'];
-        if ($start_unixtime > 0 && $end_unixtime > $start_unixtime) {
-            $condition["refill_order.{$order_time_type}"] = [['egt', $start_unixtime], ['lt', $end_unixtime], 'and'];
-            $condition['vr_order.add_time'] = ['egt', $start_unixtime-1];
-        } elseif ($start_unixtime > 0) {
-            $condition["refill_order.{$order_time_type}"] = ['egt', $start_unixtime];
-            $condition['vr_order.add_time'] = ['egt', $start_unixtime-1];
-        }
-        if (in_array($order_state, ['0', '10', '20', '30', '40'], true)) {
-            $condition['order_state'] = $order_state;
-        }
 
         $model_refill_task->Dispose($task_id);
-        [$state, $task_result] = $this->order_export($condition, $type, $task_id);
+        [$state, $task_result] = $this->order_export($task_params, $task_id);
         if ($state) {
             $model_refill_task->DisposeFinish($task_id, $task_result);
         } else {
             $model_refill_task->DisposeErr($task_id, $task_result);
         }
-        return true;
+        return $state;
     }
 
     /**
      * @throws PHPExcel_Exception
      */
-    private function order_export($condition, $type, $task_id)
+    private function order_export($condition, $task_id)
     {
-        $orders = $this->getAllOrders($condition);
-        if(empty($orders)) {
+        $orders = Model('refill_order')->getAllOrders($condition);
+        if (empty($orders)) {
             return [false, '统计数据为空'];
         }
-        $orders = $this->orderFormat($orders);
-        $objPHPExcel = new PHPExcel();
 
-        if ($type === 'merchant') {
-            $column_keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'];
-            $column_values = ['商户号', '客户订单号', '平台单号', '面额', '充值卡号', '充值卡类型', '下单日期', '完成日期', '官方流水号', '订单状态', '扣款金额'];
-            $data_keys = ['mchid', 'mch_order', 'order_sn', 'refill_amount', 'card_no', 'card_type_text', 'order_time_text', 'notify_time_text', 'official_sn', 'order_state_text', 'mch_amount'];
-        } elseif ($type === 'provider') {
-            $column_keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'];
-            $column_values = ['上游订单号', '平台单号', '面额', '充值卡号', '充值卡类型', '下单日期', '完成日期', '官方流水号', '订单状态', '扣款金额'];
-            $data_keys = ['ch_trade_no', 'order_sn', 'refill_amount', 'card_no', 'card_type_text', 'order_time_text', 'notify_time_text', 'official_sn', 'order_state_text', 'channel_amount'];
-        } else {
-            return [false, '主体类型错误'];
+        $merchants = [];
+        $column_values = ['商户号', '商户名称', '商户订单号','平台单号', '面额', '充值卡号', '充值卡类型', '下单日期', '完成日期', '官方流水号', '订单状态', '扣款金额(下游)', '上游名称','上游订单号', '折扣金额(上游)'];
+        $data_keys = ['mchid', 'mch_name', 'mch_order', 'order_sn', 'refill_amount', 'card_no', 'card_type_text', 'order_time_text', 'notify_time_text', 'official_sn', 'order_state_text', 'mch_amount', 'channel_name', 'ch_trade_no', 'channel_amount'];
+        $merchant_list = Model('')->table('merchant')->limit(1000)->order('company_name asc')->select();
+        foreach ($merchant_list as $value) {
+            $merchants[$value['mchid']] = $value;
+        }
+        $column_key = 'A';
+        for($index=0;$index<count($column_values);$index++){
+            $column_keys[] = $column_key;
+            $column_key++;
         }
 
+        $objPHPExcel = new PHPExcel();
         $objPHPExcel->setActiveSheetIndex(0);
         $objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')->setSize(10);
         foreach ($column_keys as $key => $column_key) {
@@ -156,19 +145,26 @@ class TestExportOrder extends TestCase
             $objPHPExcel->getActiveSheet()->setCellValue($cell_value, $column_values[$key]);
         }
 
+        $card_type_texts = [mtopcard\PetroChinaCard => '中石油', mtopcard\SinopecCard => '中石化', mtopcard\ChinaMobileCard => '中国移动', mtopcard\ChinaUnicomCard => '中国联通', mtopcard\ChinaTelecomCard => '中国电信'];
         foreach ($orders as $k => $order) {
+            if(!empty($merchants)) {
+                $order['mch_name'] = $merchants[$order['mchid']]['company_name'];
+            }
+            $order['card_type_text'] = $card_type_texts[$order['card_type']];
+            $order['order_time_text'] = $order['order_time'] ? date('Y-m-d H:i:s', $order['order_time']) : '';
+            $order['notify_time_text'] = $order['notify_time'] ? date('Y-m-d H:i:s', $order['notify_time']) : '';
+            $order['order_state_text'] = orderState($order);
             foreach ($column_keys as $key => $column_key) {
-                $field = $column_key.($k+2);
-                $objPHPExcel->getActiveSheet()->setCellValueExplicit($field, $order[$data_keys[$key]],
-                    PHPExcel_Cell_DataType::TYPE_STRING);
+                $field = $column_key . ($k + 2);
+                $objPHPExcel->getActiveSheet()->setCellValueExplicit($field, $order[$data_keys[$key]]);
             }
         }
         try {
             $path = BASE_ROOT_PATH . "/data/upload/task/";
-            if(!is_dir($path)){
+            if (!is_dir($path)) {
                 mkdir($path, 0755);
             }
-            $filename = date('YmdHis',time())."-任务导出-任务ID:{$task_id}.xlsx";
+            $filename = date('YmdHis', time()) . "-任务导出-任务ID:{$task_id}.xlsx";
 
             $file_path = $path . $filename;
             $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
@@ -180,76 +176,18 @@ class TestExportOrder extends TestCase
         }
     }
 
-    private function getAllOrders($condition): array
-    {
-        $len = 1000;
-
-        $i = 0;
-        $orders = [];
-        while (true)
-        {
-            $start = $i * $len;
-            $items = Model('')->table('refill_order,vr_order')
-                ->field('refill_order.*,vr_order.order_state')
-                ->join('inner')
-                ->on('refill_order.order_id=vr_order.order_id')
-                ->where($condition)
-                ->order('refill_order.order_time desc')
-                ->limit("{$start},{$len}")
-                ->select();
-            $orders = array_merge($orders,$items);
-            if (empty($items) || count($items) < $len) {
-                break;
-            }
-            $i++;
-        }
-        return $orders;
-    }
-
-    private function orderFormat($orders): array
-    {
-        $card_type_texts = [mtopcard\PetroChinaCard => '中石油', mtopcard\SinopecCard => '中石化', mtopcard\ChinaMobileCard => '中国移动', mtopcard\ChinaUnicomCard => '中国联通', mtopcard\ChinaTelecomCard => '中国电信'];
-        $orderState = function ($order_info) {
-            $is_retrying = $order_info['is_retrying'];
-            switch ($order_info['order_state']) {
-                case ORDER_STATE_CANCEL:
-                    if ($is_retrying) {
-                        $order_state = '重试中';
-                    } else {
-                        $order_state = '已取消';
-                    }
-                    break;
-                case ORDER_STATE_NEW:
-                    $order_state = '待付款';
-                    break;
-                case ORDER_STATE_PAY:
-                    $order_state = '待发货';
-                    break;
-                case ORDER_STATE_SEND:
-                    $order_state = '待收货';
-                    break;
-                case ORDER_STATE_SUCCESS:
-                    $order_state = '交易完成';
-                    break;
-                default :
-                    $order_state = '未知状态';
-            }
-            return $order_state;
-        };
-        foreach($orders as $key => $order)
-        {
-            $orders[$key]['card_type_text'] = $card_type_texts[$order['card_type']];
-            $orders[$key]['order_time_text'] = $order['order_time'] ? date('Y-m-d H:i:s', $order['order_time']) : '';
-            $orders[$key]['notify_time_text'] = $order['notify_time'] ? date('Y-m-d H:i:s', $order['notify_time']) : '';
-            $orders[$key]['order_state_text'] = $orderState($order);
-        }
-        return $orders;
-    }
-
     public function testStrSer()
     {
         $str = 'a:3:{s:11:"is_transfer";b:1;s:11:"card_states";a:2:{i:0;i:0;i:1;i:5;}s:10:"card_types";a:1:{i:0;i:4;}}';
         $arr = unserialize($str);
+
+        $j = 'A';
+        for($index=0;$index<10;$index++){
+            $j++;
+        }
+
+        $a1 = [1];
+        $a = array_merge([0],$a1,[2]);
     }
 }
 

+ 5 - 6
test/TestTask.php

@@ -16,6 +16,11 @@ class TestTask extends TestCase
         Base::run_util();
     }
 
+    public function testAddTask()
+    {
+
+    }
+
     public function testXRange()
     {
         $xrange = function ($start, $end, $step = 1) {
@@ -63,11 +68,5 @@ class TestTask extends TestCase
         Log::record($ret,Log::DEBUG);
         $ret = $gen->send('ret2');
         Log::record($ret,Log::DEBUG);
-
-        //var_dump($gen->send('ret1')); // string(4) "ret1"   (the first var_dump in gen)
-        // string(6) "yield2" (the var_dump of the ->send() return value)
-//        var_dump($gen->send('ret2')); // string(4) "ret2"   (again from within gen)
-        // NULL               (the return value of ->send())
-
     }
 }