浏览代码

客户订单查询->导出表格

lowkeyman 1 年之前
父节点
当前提交
a93c5a9b30
共有 4 个文件被更改,包括 301 次插入1 次删除
  1. 27 1
      admin/control/order_search.php
  2. 35 0
      admin/templates/default/refill.order.search.php
  3. 168 0
      helper/task/handler.php
  4. 71 0
      test/TestOrder.php

+ 27 - 1
admin/control/order_search.php

@@ -1,5 +1,5 @@
 <?php
-
+require_once(BASE_HELPER_PATH . '/task/task_helper.php');
 
 class order_searchControl extends SystemControl
 {
@@ -67,6 +67,11 @@ class order_searchControl extends SystemControl
                 $start = strtotime(date('Y-m-d', time()));
                 $condition['refill_order.order_time'] = ['egt', $start];
             }
+
+            if (!empty($_GET['export'])) {
+                $this->export_excel($condition);
+            }
+
             $order_list = $model_refill_order->getMerchantOrderList($condition, 200, 0,'refill_order.*,vr_order.order_state', 'refill_order.channel_name DESC ');
 
             $merchant_list = Model('')->table('merchant')->limit(1000)->select();
@@ -94,4 +99,25 @@ class order_searchControl extends SystemControl
         Tpl::output('show_page', $model_refill_order->showpage());
         Tpl::showpage('refill.order.search');
     }
+
+    private function export_excel($condition)
+    {
+        if (empty($condition)) {
+            showMessage('请选择导出条件后重新操作', '', '', 'error');
+        }
+
+        $title = $_GET['task_title'] ?? '';
+        $manager = new task\manager();
+
+        $task = $manager->add_task('order_search_export',$condition,1,-1,$title);
+        if ($task->completed() && $task->success()) {
+            $file_name = $task->result();
+            $file_path = UPLOAD_SITE_URL . '/' . ATTACH_TASK . DS . $file_name;
+            header("Content-Disposition: attachment; filename={$file_name}");
+            readfile($file_path);
+        } else {
+            $task_id = $task->task_id();
+            showMessage("录入成功,任务ID:{$task_id},请稍后以相同条件再次导出,或在任务列表直接下载。","index.php?act=task&op=index&task_id={$task_id}");
+        }
+    }
 }

+ 35 - 0
admin/templates/default/refill.order.search.php

@@ -158,6 +158,8 @@
     <form method="get" action="index.php" name="formSearch" id="formSearch">
         <input type="hidden" name="act" value="order_search"/>
         <input type="hidden" name="op" value="index"/>
+        <input type="hidden" name="export" value=""/>
+        <input type="hidden" name="task_title" value=""/>
         <table class="tb-type1 noborder search">
             <tr>
                 <th><label for="query_start_time">下单时间</label></th>
@@ -298,6 +300,11 @@
                         <span><i class="icon-edit"></i>拷贝商家单号</span>
                     </a>
                 </td>
+                <td>
+                    <a href="#" class="btns" id="ncexport">
+                        <span><i class="icon-edit"></i>导出Excel</span>
+                    </a>
+                </td>
             </tr>
         </table>
     </form>
@@ -490,6 +497,34 @@
                 $(this).css('color', 'red')
             }
         })
+        // 导出Excel
+        $('#ncexport').click(function() {
+            const export_flag = $('input[name="export"]');
+            export_flag.val('1');
+            $('input[name="op"]').val('index');
+
+            let mchid = $('select[name="mchid"] option:selected').text();
+            let store_id = $('select[name="store_id"] option:selected').text();
+            let order_state = $('select[name="order_state"] option:selected').text();
+            let startTime = $('input[name="query_start_time"]').val();
+            let endTime = $('input[name="query_end_time"]').val();
+            let str = `下单时间 : ${startTime}-${endTime}`;
+            str = str.replace(/-$/, "");
+            if (mchid !== '请选择') {
+                str = str + `,客户名称:${mchid}`
+            }
+            if (store_id !== '请选择') {
+                str = str + `,供方名称:${store_id}`
+            }
+            if (order_state !== '请选择') {
+                str = str + `,订单状态:${order_state}`
+            }
+            $('input[name="task_title"]').val(str);
+
+            $('#formSearch').submit();
+
+            export_flag.val('');
+        });
     });
 
     function hCopyCardNo(e) {

+ 168 - 0
helper/task/handler.php

@@ -457,4 +457,172 @@ class handler
     {
         return md5("refill_balance_stat_all-".serialize($condition));
     }
+
+    public function order_search_export($cond)
+    {
+        $mod = Model('');
+
+        $order_reader = function ($cond, $total_stage, $stage_limit) use($mod)
+        {
+            for ($cur_stage = 1; $cur_stage <= $total_stage; $cur_stage ++)
+            {
+                $skip = ($cur_stage - 1) * $stage_limit;
+
+                $items = $mod->table('refill_order,vr_order')
+                    ->field('refill_order.*,vr_order.order_state')
+                    ->join('inner')
+                    ->on('refill_order.order_id=vr_order.order_id')
+                    ->where($cond)
+                    ->order('refill_order.channel_name DESC')
+                    ->limit("$skip,$stage_limit")
+                    ->select();
+
+                yield [$items,$total_stage,$cur_stage];
+                if(empty($items)) {
+                    break;
+                }
+            }
+        };
+
+        $elapse_time = function($seconds)
+        {
+            $minutes = intval($seconds / 60);
+            $second = intval($seconds % 60);
+            if ($minutes >= 60) {
+                $minute = $minutes % 60;
+                $hours = intval($minutes / 60);
+                $result = "{$minute}m{$second}s";
+            } elseif ($minutes > 0) {
+                $result = "{$minutes}m{$second}s";
+            } else {
+                $result = "{$second}s";
+            }
+
+            if (isset($hours)) {
+                $result = "{$hours}h{$minute}m";
+            }
+            return $result;
+        };
+
+        $column_values = ['机构名称','订单号', '充值卡号', '充值卡类型', '充值额度', '下单日期', '耗时', '订单状态', '商家单号', '渠道单号'];
+        $data_keys = ['mch_name', 'order_sn', 'card_no', 'card_type_text', 'refill_amount', 'order_time_text', 'diff_time_text', 'order_state_text', 'mch_order', 'ch_trade_no'];
+
+        $column_key = 'A';
+        for ($excel_index = 0; $excel_index < count($column_values); $excel_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) {
+            $objPHPExcel->getActiveSheet()->getColumnDimension($column_key)->setWidth(15);
+            $cell_value = $column_key . 1;
+            $objPHPExcel->getActiveSheet()->setCellValue($cell_value, $column_values[$key]);
+        }
+
+        $card_type_texts = [mtopcard\PetroChinaCard => '中石油', mtopcard\SinopecCard => '中石化', mtopcard\ChinaMobileCard => '中国移动', mtopcard\ChinaUnicomCard => '中国联通', mtopcard\ChinaTelecomCard => '中国电信', mtopcard\ThirdRefillCard => '增值业务'];
+
+        $merchant_list = Model('')->table('merchant')->limit(1000)->select();
+        foreach ($merchant_list as  $value) {
+            $merchants[$value['mchid']] = $value;
+        }
+
+        $excel_writer = function ($order, $index) use ($card_type_texts, $column_keys, $objPHPExcel, $data_keys, $elapse_time, $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']) : '';
+
+            if ($order['notify_time'] > 0) {
+                $diff_time = $order['notify_time'] - $order['order_time'];
+            } else {
+                $cur_time = time();
+                $diff_time = $cur_time - $order['order_time'];
+            }
+            $order['diff_time_text'] = $elapse_time($diff_time);
+            $order['order_state_text'] = orderState($order);
+
+            foreach ($column_keys as $key => $column_key) {
+                $field = $column_key . ($index + 2);
+                $objPHPExcel->getActiveSheet()->setCellValueExplicit($field, $order[$data_keys[$key]]);
+            }
+        };
+
+        $start_time = time();
+        $percentor = function ($total_stage, $cur_stage) use ($start_time)
+        {
+            $task_id = $this->mTtaskId;
+            if($total_stage > $cur_stage) {
+                $total_used = time() - $start_time;
+                $remain = $total_used * ($total_stage - $cur_stage) / $cur_stage;
+                $remain = intval($remain);
+
+                $expected_time = date("H:i:s", (time() + $remain));
+                $stage = "导出进度:{$cur_stage}/{$total_stage}, 预计在{$expected_time}完成";
+            } else {
+                $stage = "已经完成";
+            }
+
+            $mod_task = Model('task');
+            $mod_task->where(['task_id' => $task_id])->update(['stage' => $stage]);
+        };
+
+
+        $stage = 0;
+        $execl_index = 0;
+        $total = $mod->table('refill_order,vr_order')
+            ->field('*')
+            ->where($cond)->join('inner')->on('refill_order.order_id=vr_order.order_id')
+            ->master(false)
+            ->count();
+
+        $stage_limit = 1000;
+        $total_stage = ceil($total / $stage_limit);
+        $reader = $order_reader($cond, $total_stage, $stage_limit);
+        foreach ($reader as $result)
+        {
+            [$items,$total_stage,$cur_stage] = $result;
+            foreach ($items as $order)
+            {
+                Log::record("handler write order index={$execl_index}",Log::DEBUG);
+
+                $excel_writer($order,$execl_index);
+                $execl_index += 1;
+            }
+            Log::record("handler total_stage={$total_stage} cur_stage={$cur_stage}",Log::DEBUG);
+            if($stage == 0) {
+                $stage = $cur_stage;
+            }
+            elseif($stage != $cur_stage) {
+                $percentor($total_stage,$stage);
+                $stage = $cur_stage;
+            }
+        }
+
+        try {
+            $path = BASE_ROOT_PATH . "/data/upload/task/";
+            if (!is_dir($path)) {
+                mkdir($path, 0755);
+            }
+            $filename = date('YmdHis', time()) . "订单导出.xlsx";
+
+            $file_path = "{$path}{$filename}";
+            $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
+            $objWriter->save($file_path);
+
+            $percentor($total_stage,$total_stage);
+
+            return [true, $filename];
+        } catch (Exception $e) {
+            Log::record("handler {$e->getMessage()}",Log::ERR);
+            return [false, false];
+        }
+    }
+
+    public function order_search_export_title($condition)
+    {
+        return md5("refill_order_export-".serialize($condition));
+    }
 }

+ 71 - 0
test/TestOrder.php

@@ -242,4 +242,75 @@ class TestOrder extends TestCase
         $order_sn = '2000000004385101';
         $status = $delivery->cancel_order($order_sn);
     }
+
+    public function testOrderSearchExport()
+    {
+        $cond = [
+            "refill_order.order_sn" => ["in", "406709436906413191,206709436916067721,206709436916957511,206709436925508281,106709436933650541,206709436934516221,806709436935946891,806709436944415021,306709436945883701,506709436701006101,506709427984404438,506709436584639651,306709436867082271,906709436874179531,706709427972789371,206709427984976461,806709436854558061,706709427974847671,206709436782418101"],
+            "refill_order.inner_status" => 0,
+            "refill_order.order_time" => ["lt", 1712124874]
+        ];
+
+        $order_reader = function ($cond, $total_stage, $stage_limit)
+        {
+            for ($cur_stage = 1; $cur_stage <= $total_stage; $cur_stage ++)
+            {
+                $skip = ($cur_stage - 1) * $stage_limit;
+                $mod= Model('refill_order');
+
+                $items = $mod->table('refill_order,vr_order')
+                    ->field('refill_order.*,vr_order.order_state')
+                    ->join('inner')
+                    ->on('refill_order.order_id=vr_order.order_id')
+                    ->where($cond)
+                    ->order('refill_order.channel_name DESC')
+                    ->limit("$skip,$stage_limit")
+                    ->select();
+
+                yield [$items,$total_stage,$cur_stage];
+                if(empty($items)) {
+                    break;
+                }
+            }
+        };
+
+        $mod = Model('');
+        $total = $mod->table('refill_order,vr_order')
+            ->field('*')
+            ->where($cond)->join('inner')->on('refill_order.order_id=vr_order.order_id')
+            ->master(false)
+            ->count();
+
+        $stage_limit = 10;
+        $total_stage = ceil($total / $stage_limit);
+
+        $reader = $order_reader($cond, $total_stage, $stage_limit);
+        foreach ($reader as $result)
+        {
+            [$items,$total_stage,$cur_stage] = $result;
+        }
+    }
+
+    public function testOrderTask()
+    {
+        require_once(BASE_HELPER_PATH . '/task/task_helper.php');
+        $task_manager = new task\manager();
+        $task_id = 0;
+        while (true)
+        {
+            try
+            {
+                $task = $task_manager->pop_task($task_id,false);
+                if (!empty($task)) {
+                    $task_manager->handle($task);
+                    $task_id = $task['task_id'];
+                }
+            }
+            catch (Exception $ex) {
+                Log::record($ex->getMessage(),Log::ERR);
+            }
+
+            sleep(1);
+        }
+    }
 }