mTimeouts = [3 => 180, 4 => 300, 5 => 600, 6 => 900, 7 => 7200]; parent::__construct(); } private function time_cond($timeout_type,$card_type,$cur_time) { $mchid_filter = function ($time_out) { $mchids = Model('')->table('merchant')->where(['time_out' => ['elt', $time_out]])->field('mchid')->select(); $mchids = array_column($mchids, 'mchid'); $mchids = implode(',', $mchids); return $mchids; }; $period = 20; $start_day = strtotime("-5 days",$cur_time); $time_cond = []; $mch_cond = []; if ($timeout_type > 0) { if (in_array($timeout_type, [1, 2])) { if ($timeout_type === 1) { $time_cond['refill_order.order_time'] = ['between', [$cur_time - 3600, $cur_time - 1800]]; $time_cond['vr_order.add_time'] = ['between', [$cur_time - 3600, $cur_time - 1800]]; } if ($timeout_type === 2) { $time_cond['refill_order.order_time'] = ['between', [$start_day, $cur_time - 3600]]; $time_cond['vr_order.add_time'] = ['between', [$start_day, $cur_time - 3600]]; } } elseif (in_array($timeout_type, [3, 4, 5, 6, 7])) { $time_out = $this->mTimeouts[$timeout_type]; $mchids = $mchid_filter($time_out); $time_cond['vr_order.add_time&vr_order.add_time'] = ['_multi' => true, ['egt', $start_day], ['lt', $cur_time - $time_out]]; $time_cond['refill_order.order_time&refill_order.order_time'] = ['_multi' => true, ['egt', $start_day], ['lt', $cur_time - $time_out]]; $mch_cond['refill_order.mchid'] = ['in', $mchids]; $card_type = 'phone'; } else { $time_cond = []; } } else { $time_cond['vr_order.add_time&vr_order.add_time'] = ['_multi' => true, ['egt', $start_day], ['lt', $cur_time]]; $time_cond['refill_order.order_time&refill_order.order_time&refill_order.order_time'] = ['_multi' => true, ['egt', $start_day], ['lt', $cur_time], ['exp', "refill_order.order_time < {$cur_time} - merchant.time_out + {$period}"]]; // $time_cond['refill_order.commit_time'] = ['lt', $cur_time - 180]; } return [$time_cond, $mch_cond, $card_type]; } public function indexOp() { $model_refill_order = Model('refill_order'); $base_cond['refill_order.inner_status'] = 0; $base_cond['vr_order.order_state'] = ORDER_STATE_SEND; $timeout_type = intval($_GET['time']); $card_type = $_GET['card_type']; if (!empty($_GET['store_id'])) { $base_cond['vr_order.store_id'] = $_GET['store_id']; } $cur_time = time(); [$time_cond,$mch_cond,$card_type] = $this->time_cond($timeout_type,$card_type,$cur_time); if (!empty($_GET['mchid'])) { $base_cond['refill_order.mchid'] = $_GET['mchid']; } elseif(!empty($_GET['no_mchid'])) { $no_mchid = explode(',', $_GET['no_mchid']); $base_cond['refill_order.mchid'] = ['not in', $no_mchid]; } elseif(!empty($mch_cond)) { $base_cond = array_merge($base_cond,$mch_cond); } if (!empty($card_type)) { if (in_array($card_type, ['1', '2', '4', '5', '6', '7'])) { $base_cond['refill_order.card_type'] = $card_type; } if ($card_type == 'oil') { $base_cond['refill_order.card_type'] = ['in', ['1', '2']]; } if ($card_type == 'phone') { $base_cond['refill_order.card_type'] = ['in', ['4', '5', '6']]; } } if (!empty($_GET['quality'])) { $base_cond['refill_order.quality'] = $_GET['quality']; } $orders_cond = array_merge($base_cond,$time_cond); if (!empty($_GET['order_query'])) { $this->updateOrderSend($orders_cond); return; } if (!empty($_GET['export'])) { $this->RefillOrderExport($orders_cond, 'time_out_order'); return; } $fields = 'refill_order.*,vr_order.order_state'; $order_by = "( {$cur_time} - refill_order.commit_time ) desc"; $order_list = $model_refill_order->getMerchantTimeOut($orders_cond, 200, 10000,$fields, $order_by); $order_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($orders_cond)->find(); $special_stat = $this->extra_stats($base_cond, $timeout_type,$cur_time); $merchant_list = $this->merchants(); if(!empty($order_list)) { $order_list = $this->orderFormat($order_list, $merchant_list); } $provider_list = $this->providers(); Tpl::output('stat', $order_stat); Tpl::output('count', $special_stat); Tpl::output('order_list', $order_list); Tpl::output('merchant_list', $merchant_list); Tpl::output('provider_list', $provider_list); Tpl::output('show_page', $model_refill_order->showpage()); Tpl::showpage('refill.order.send.index'); } private function notify_time($cur_time,$period) { $start_day = strtotime("-5 days",$cur_time); $time_cond['vr_order.add_time&vr_order.add_time'] = ['_multi' => true, ['egt', $start_day], ['lt', $cur_time]]; $time_cond['refill_order.order_time&refill_order.order_time'] = ['_multi' => true, ['egt', $start_day], ['lt', $cur_time]]; $time_cond['refill_order.commit_time&refill_order.commit_time'] = ['_multi' => true, ['egt', $start_day], ['lt', $cur_time - $period]]; return $time_cond; } public function monitor_notifyOp() { $model_refill_order = Model('refill_order'); $base_cond['refill_order.inner_status'] = 0; $base_cond['vr_order.order_state'] = ORDER_STATE_SEND; $timeout_type = intval($_GET['time']); $card_type = $_GET['card_type']; if (!empty($_GET['store_id'])) { $base_cond['vr_order.store_id'] = $_GET['store_id']; } $cur_time = time(); $time_cond = $this->notify_time($cur_time,180); if (!empty($_GET['mchid'])) { $base_cond['refill_order.mchid'] = $_GET['mchid']; } elseif(!empty($_GET['no_mchid'])) { $no_mchid = explode(',', $_GET['no_mchid']); $base_cond['refill_order.mchid'] = ['not in', $no_mchid]; } elseif(!empty($mch_cond)) { $base_cond = array_merge($base_cond,$mch_cond); } if (!empty($card_type)) { if (in_array($card_type, ['1', '2', '4', '5', '6', '7'])) { $base_cond['refill_order.card_type'] = $card_type; } if ($card_type == 'oil') { $base_cond['refill_order.card_type'] = ['in', ['1', '2']]; } if ($card_type == 'phone') { $base_cond['refill_order.card_type'] = ['in', ['4', '5', '6']]; } } if (!empty($_GET['quality'])) { $base_cond['refill_order.quality'] = $_GET['quality']; } $orders_cond = array_merge($base_cond,$time_cond); if (!empty($_GET['order_query'])) { $this->updateOrderSend($orders_cond); return; } //耗时 $fields = "refill_order.*,vr_order.order_state"; $order_by = "({$cur_time} - refill_order.commit_time) desc"; $order_list = $model_refill_order->getMerchantTimeOut($orders_cond, 200, 10000,$fields, $order_by); $order_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($orders_cond)->find(); $special_stat = $this->extra_stats($base_cond, $timeout_type,$cur_time); $merchant_list = $this->merchants(); if(!empty($order_list)) { $order_list = $this->orderFormat($order_list, $merchant_list); } $provider_list = $this->providers(); Tpl::output('stat', $order_stat); Tpl::output('count', $special_stat); Tpl::output('order_list', $order_list); Tpl::output('merchant_list', $merchant_list); Tpl::output('provider_list', $provider_list); Tpl::output('show_page', $model_refill_order->showpage()); Tpl::showpage('refill.order.send.index'); } private function extra_stats($base_cond, $timeout_type,$cur_time): array { $stat_order = function ($cond) { $stat = Model('')->table('refill_order,vr_order')->join('inner') ->on('refill_order.order_id=vr_order.order_id') ->field('count(*) as order_count ') ->where($cond)->find(); return $stat['order_count']; }; $result = []; $start_day = strtotime("-5 days",$cur_time); $extra_conds = [ ['between', [$cur_time - 3600, $cur_time - 1800]], ['between', [$start_day, $cur_time - 3600]] ]; if (array_key_exists($timeout_type, $this->mTimeouts)) { $time_out = $this->mTimeouts[$timeout_type]; $extra_conds[] = ['_multi' => true, ['egt', $start_day], ['lt', $cur_time - $time_out]]; } foreach ($extra_conds as $stat_cond) { if (!empty($time_out)) { $base_cond['vr_order.add_time&vr_order.add_time'] = $stat_cond; $base_cond['refill_order.order_time&refill_order.order_time'] = $stat_cond; } else { $base_cond['refill_order.order_time'] = $stat_cond; $base_cond['vr_order.add_time'] = $stat_cond; } $result[] = $stat_order($base_cond); } return $result; } private function RefillOrderExport($cond,$type='order') { $result = []; if($type == 'order') { $result = Model('refill_order')->getAllOrders($cond); }elseif($type == 'time_out_order'){ $result = Model('refill_order')->getAllTimeOutOrders($cond); } $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' => '订单状态'); $excel_data[0][] = array('styleid' => 's_title', 'data' => '扣款金额'); //data foreach ((array)$data as $k => $v) { $tmp = array(); $tmp[] = array('data' => $v['mchid']); $tmp[] = array('data' => $v['mch_order']); $tmp[] = array('data' => $v['order_sn']); $tmp[] = array('data' => $v['refill_amount']); $tmp[] = array('data' => $v['card_no']); $tmp[] = array('data' => $this->scard_type($v['card_type'])); $tmp[] = array('data' => date('Y-m-d H:i:s', $v['order_time'])); if (empty($v['notify_time'])) { $tmp[] = array('data' => ''); } else { $tmp[] = array('data' => date('Y-m-d H:i:s', $v['notify_time'])); } $tmp[] = array('data' => $v['official_sn']); $tmp[] = array('data' => orderState($v)); $tmp[] = array('data' => $v['mch_amount']); $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 neterr_orderOp() { $model_refill_order = Model('refill_order'); if (!empty($_GET['store_id'])) { $condition['vr_order.store_id'] = $_GET['store_id']; } $condition['refill_order.inner_status'] = 0; $condition['refill_order.neterr'] = 1; $condition['vr_order.order_state'] = ORDER_STATE_PAY; if (!empty($_GET['export'])) { $this->RefillOrderExport($condition); return; } $order_list = $model_refill_order->getMerchantOrderList($condition, 200, 0,'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); $provider_list = $this->providers(); Tpl::output('provider_list', $provider_list); Tpl::output('order_list', $order_list); Tpl::output('show_page', $model_refill_order->showpage()); Tpl::showpage('refill.order.neterr.index'); } 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) { $merchants[$value['mchid']] = $value; } $cur_time = time(); 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']; if ($order_info['notify_time'] > 0) { $total_diff_time = $order_info['notify_time'] - $order_info['order_time']; $diff_time = $order_info['notify_time'] - $order_info['commit_time']; } else { $total_diff_time = $cur_time - $order_info['order_time']; $diff_time = $cur_time - $order_info['commit_time']; } $order_list[$order_id]['diff_time'] = $diff_time; $order_list[$order_id]['diff_time_text'] = $this->elapse_time($diff_time); $order_list[$order_id]['total_diff_time'] = $total_diff_time; $order_list[$order_id]['total_diff_time_text'] = $this->elapse_time($total_diff_time); $order_list[$order_id]['quality_text'] = $this->quality_format($order_info['quality'], $order_info['card_type']); if ($total_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; } public function notify_err_orderOp() { $model_refill_order = Model('refill_order'); $order_state_cancel = ORDER_STATE_CANCEL; $order_state_success = ORDER_STATE_SUCCESS; $condition['refill_order.inner_status'] = 0; $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'])) { $_GET['notify_time'] = 180; } $cur_time = time(); $time = $_GET['time'] * 3600; $condition['refill_order.order_time'] = [['gt', ($cur_time - $time)], ['lt', $cur_time], 'and']; $condition['vr_order.add_time'] = [['gt', ($cur_time - $time)], ['lt', $cur_time], 'and']; $notify_time = $_GET['notify_time']; if($notify_time > 0) { $start_day = strtotime("-5 days",$cur_time); $condition['refill_order.notify_time'] = ['lt', (time() - $notify_time)]; $condition['refill_order.notify_time'] = [['gt', $start_day], ['lt', ($cur_time - $notify_time)], 'and']; } $order_list = $model_refill_order->getMerchantOrderList($condition, 200, 0,'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); Tpl::output('order_list', $order_list); Tpl::output('show_page', $model_refill_order->showpage()); Tpl::showpage('refill.order.notify.err.index'); } public function notifyerr_all_notifyOp() { if (empty($_GET['time']) || empty($_GET['notify_time'])) { showMessage('日期条件错误'); } $model_refill_order = Model('refill_order'); $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'] = ['in', "0,2"]; $condition['refill_order.is_retrying'] = 0; $time = $_GET['time'] * 3600; $condition['refill_order.order_time'] = ['gt', (time() - $time)]; $notify_time = $_GET['notify_time']; $condition['refill_order.notify_time'] = ['lt', (time() - $notify_time)]; $order_list = $model_refill_order->getMerchantOrderList($condition, '', 0,'refill_order.*,vr_order.order_state', 'refill_order.notify_time asc', 1000); foreach ($order_list as $order) { QueueClient::push("NotifyMerchantComplete", ['order_id' => $order['order_id'], 'manual' => true]); } showMessage('操作成功'); } private function updateOrderSend($condition) { $condition['order_state'] = ORDER_STATE_SEND; $orders = $this->getAllTimeOutOrders($condition); if (!empty($orders)) { foreach ($orders as $order) { $order_id = $order['order_id']; QueueClient::push("QueryRefillState", ['order_id' => $order_id]); } } showMessage('操作成功'); } private function getAllTimeOutOrders($condition): array { $len = 1000; $i = 0; $orders = []; while (true) { $start = $i * $len; $items = Model('')->table('refill_order,vr_order,merchant') ->field('refill_order.*,vr_order.order_state') ->join('inner,inner') ->on('refill_order.order_id=vr_order.order_id,refill_order.mchid=merchant.mchid') ->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; } }