mTtaskId = $task_id; } 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_ex($cond) { $tmcond_gen = function ($cur_start,$cur_end) { $cond['refill_order.order_time'] = [['egt', $cur_start], ['lt', $cur_end], 'and']; $end = $cur_end + 86400*2; $cond['vr_order.add_time'] = [['egt', $cur_start], ['elt', $end], 'and']; return $cond; }; $normal_cond = $cond['normal']; $time_scope = $cond['time_scope']; $order_reader = function ($normal_cond, $time_scope) use ($tmcond_gen) { [$start, $end] = $time_scope['order_time']; for ($cur_start = $start; $cur_start < $end; $cur_start += 86400) { if ($cur_start + 86400 >= $end) { $cur_end = $end; } else { $cur_end = $cur_start + 86400; } $tmcond = $tmcond_gen($cur_start, $cur_end); $cond = array_merge($normal_cond, $tmcond); $mod = Model(); $items = $mod->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($cond) ->group('order_state') ->select(); if(empty($items)) continue; yield $items; } }; $summer = function ($items,&$result) { foreach ($items as $item) { $order_state = $item['order_state']; $result[$order_state]['order_count'] += $item['order_count']; $result[$order_state]['refill_amounts'] += ncPriceFormat($item['refill_amounts']); $result[$order_state]['channel_amounts'] += ncPriceFormat($item['channel_amounts']); $result[$order_state]['mch_amounts'] += ncPriceFormat($item['mch_amounts']); } }; $initor = function (&$records) { $order_states = [ORDER_STATE_CANCEL, ORDER_STATE_SEND, ORDER_STATE_SUCCESS]; foreach ($order_states as $state) { $val = ['order_count' => 0, 'refill_amounts' => 0, 'channel_amounts' => 0, 'mch_amounts' => 0]; $records[$state] = $val; } }; $all_summer = function ($records) { $result = ['order_count' => 0, 'refill_amounts' => 0, 'channel_amounts' => 0, 'mch_amounts' => 0]; foreach ($records as $item) { $result['order_count'] += $item['order_count']; $result['refill_amounts'] += ncPriceFormat($item['refill_amounts']); $result['channel_amounts'] += ncPriceFormat($item['channel_amounts']); $result['mch_amounts'] += ncPriceFormat($item['mch_amounts']); } return $result; }; try { $records = []; $initor($records); $stats = $order_reader($normal_cond, $time_scope); foreach ($stats as $items) { $summer($items,$records); } $all = $all_summer($records); $result = ['all' => $all, 'sending' => $records[ORDER_STATE_SEND], 'success' => $records[ORDER_STATE_SUCCESS], 'cancel' => $records[ORDER_STATE_CANCEL]]; return [true, $result]; } catch (Exception $ex) { return [false, false]; } } public function refill_order_stat_title($condition) { return md5("refill_order_stat-".serialize($condition)); } public function refill_order_stat_ex_title($condition) { return md5("refill_order_stat_ex-".serialize($condition)); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public function refill_order_export($cond) { $tmcond_gen = function ($time_type,$time_scope,$cur_start,$cur_end) { if($time_type == 'notify_time') { $start = $cur_start - 86400 * 2; $end = $cur_end + 86400 * 2; $cond['refill_order.order_time'] = [['egt', $start], ['lt', $cur_end], 'and']; $cond['vr_order.add_time'] = [['egt', $start], ['elt', $end], 'and']; $cond['refill_order.notify_time'] = [['egt', $cur_start], ['lt', $cur_end], 'and']; } else { $cond['refill_order.order_time'] = [['egt', $cur_start], ['lt', $cur_end], 'and']; $end = $cur_end + 86400 * 2; $cond['vr_order.add_time'] = [['egt', $cur_start], ['elt', $end], 'and']; } return $cond; }; $normal_cond = $cond['normal']; $time_scope = $cond['time_scope']; $export_type = $cond['export_type']; $order_reader = function ($normal_cond,$time_scope) use ($tmcond_gen) { if(isset($time_scope['notify_time'])) { $time_type = 'notify_time'; [$start,$end] = $time_scope['notify_time']; } else { $time_type = 'order_time'; [$start,$end] = $time_scope['order_time']; } $total_stage = ceil(($end - $start) / 3600); $cur_stage = 1; for ($cur_start = $start; $cur_start < $end; $cur_start += 3600) { if($cur_start + 3600 >= $end) { $cur_end = $end; } else { $cur_end = $cur_start + 3600; } $tmcond = $tmcond_gen($time_type,$time_scope,$cur_start,$cur_end); $cond = array_merge($normal_cond,$tmcond); $mod = Model(); $order_id = 0; while (true) { $cond['refill_order.order_id'] = ['gt', $order_id]; $items = $mod->table('refill_order,vr_order') ->field('refill_order.*,vr_order.order_state,vr_order.store_name') ->join('inner') ->on('refill_order.order_id=vr_order.order_id') ->where($cond) ->order('refill_order.order_id asc') ->limit("0,1000") ->select(); if(empty($items)) { yield [$items,$total_stage,$cur_stage]; break; } else { $last_item = end($items); $order_id = intval($last_item['order_id']); Log::record("handler order_id={$order_id}",Log::DEBUG); yield [$items,$total_stage,$cur_stage]; } } $cur_stage++; } }; $merchants = []; $column_values = ['平台单号','面额', '充值卡号', '充值卡类型', '是否转网', '下单日期', '完成日期', '订单状态', '流水号']; $data_keys = ['order_sn', 'refill_amount', 'card_no', 'card_type_text', 'is_transfer_text', 'order_time_text', 'notify_time_text','order_state_text', 'official_sn']; if($export_type === 'merchant') { $column_values = array_merge(['商户号', '商户订单号'], $column_values, ['扣款金额']); $data_keys = array_merge(['mchid', 'mch_order'], $data_keys, ['mch_amount']); }elseif ($export_type === 'provider') { $column_values = array_merge(['上游名称', '上游订单号'], $column_values, ['折扣金额']); $data_keys = array_merge(['store_name', 'ch_trade_no'], $data_keys, ['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($execl_index=0;$execl_indexsetActiveSheetIndex(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 => '中国电信']; $execl_writer = function ($order,$index) use ($card_type_texts, $column_keys,$objPHPExcel,$data_keys) { 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); if($order['is_transfer'] == 1) { $order['is_transfer_text'] = '是'; }else{ $order['is_transfer_text'] = '否'; } 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; $reader = $order_reader($normal_cond,$time_scope); foreach ($reader as $result) { [$items,$total_stage,$cur_stage] = $result; foreach ($items as $order) { Log::record("handler write order index={$execl_index}",Log::DEBUG); $execl_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 refill_order_export_title($condition) { return md5("refill_order_export-".serialize($condition)); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public function order_stat_reload($condition) { $refill = new stat_refill(); $type = $condition['type']; $time_stamp = $condition['time_stamp']; $cid = $condition['cid']; $order_time_type = $condition['order_time_type']; if ($type == 'merchant') { $refill->merchant_stat($time_stamp, $cid, $order_time_type); } elseif ($type == 'provider') { $refill->provider_stat($time_stamp, $cid, $order_time_type); } elseif ($type == 'system') { $refill->system_stat($time_stamp, $order_time_type, 'reload'); } return [true, 'success']; } public function order_stat_reload_title($condition) { return md5("order_stat_reload-".serialize($condition)); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public function order_stat_reload_some($condes) { foreach ($condes as $cond) { $this->order_stat_reload($cond); } return [true, 'success']; } public function order_stat_reload_some_title($condition) { return md5("order_stat_reload-some".serialize($condition)); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public function refill_balance_create($condition) { $type = $condition['type']; $cid = $condition['cid']; $start = $condition['start']; $end = $condition['end']; $time_type = $condition['time_type']; $parent_balance = $condition['parent_id']; $refill_balance = new refill_balance(); $refill_balance->add_balance($type, $cid, $start, $end, $time_type, $parent_balance); return [true, 'success']; } public function refill_balance_create_title($condition) { return md5("refill_balance_create-".serialize($condition)); } public function refill_balance_rebuild($condition) { $balance_id = $condition['balance_id']; $refill_balance = new refill_balance(); $refill_balance->rebuild_balance($balance_id); return [true, 'success']; } public function refill_balance_rebuild_title($condition) { return md5("refill_balance_rebuild-".serialize($condition)); } public function refill_balance_stat_all($condition) { $end = $condition['end']; $refill_balance = new refill_balance(); $refill_balance->stat_all($end); return [true, 'success']; } public function refill_balance_stat_all_title($condition) { 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)); } public function refill_query_err_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_query_err') ->field('*') ->where($cond) ->order('query_time desc') ->limit("$skip,$stage_limit") ->master(false) ->select(); yield [$items,$total_stage,$cur_stage]; if(empty($items)) { break; } } }; $column_values = ['编号','机构编号', '机构名称', '商家单号', '查询时间', '错误code', '错误信息']; $data_keys = ['number', 'mchid', 'mch_name', 'mch_order', 'query_time', 'code', 'msg']; $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]); } $merchant_list = Model('')->table('merchant')->limit(1000)->select(); foreach ($merchant_list as $value) { $merchants[$value['mchid']] = $value; } $excel_writer = function ($order, $index) use ($column_keys, $objPHPExcel, $data_keys, $merchants) { $order['number'] = $index + 1; $order['mch_name'] = $merchants[$order['mchid']]['company_name']; $order['query_time'] = date('Y-m-d H:i:s', $order['query_time']); 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_query_err') ->field('*') ->where($cond) ->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 refill_query_err_export_title($condition) { return md5("refill_query_err_export-".serialize($condition)); } public function refill_servicefee_export($cond) { $servicefee_default = []; $mch_extra_price = function () use (&$servicefee_default) { $model = Model(''); $count = $model->table('merchant,merchant_price') ->join('inner')->on('merchant.mchid = merchant_price.mchid and merchant.quality = merchant_price.quality and merchant_price.extra_price > 0') ->field('merchant.mchid,merchant_price.extra_price,merchant_price.spec')->count(); $stage_limit = 1000; $total_stage = ceil($count / $stage_limit); for ($i = 1; $i <= $total_stage; $i++) { $skip = ($i - 1) * $stage_limit; $extra_price = $model->table('merchant,merchant_price') ->join('inner')->on('merchant.mchid = merchant_price.mchid and merchant.quality = merchant_price.quality and merchant_price.extra_price > 0') ->field('merchant.mchid,merchant_price.extra_price,merchant_price.spec')->limit("$skip,$stage_limit")->order('merchant_price.extra_price desc')->select(); if (!empty($extra_price)) { foreach ($extra_price as $item) { $mchid = $item['mchid']; if (!isset($servicefee_default[$mchid])) { if (empty($item['extra_price']) || empty($item['spec'])) { continue; } $rate = $item['extra_price'] / $item['spec']; $servicefee_default[$mchid] = number_format(floor($rate * 10000) / 10000, 4, '.', ''); } } } } }; $mch_extra_price();//从机构通道费率设置里读取附加金额配置,作为默认值 $servicefee_date = []; $service_rate = function ($mchid, $date) use (&$servicefee_date, $servicefee_default) { $rate_cache = function ($mchid, $date) { $settings = rcache('service_stats_settings', 'refill-'); $settings = unserialize($settings['data']); $rate_setting = $settings['mch_service_rate']; $filtered = array_filter($rate_setting, function ($entry) use ($mchid, $date) { return $entry[0] == $mchid && $entry[1] == $date; }); return !empty($filtered) ? array_values($filtered)[0][2] : '0.0000'; }; if (isset($servicefee_date[$mchid][$date])) { return $servicefee_date[$mchid][$date]; } $rate = $rate_cache($mchid, $date); if ($rate === '0.0000' && isset($servicefee_default[$mchid])) { $rate = $servicefee_default[$mchid]; } $servicefee_date[$mchid][$date] = $rate; return $rate; }; $mod = Model(''); $stats_reader = function($cond, $total_stage, $stage_limit) use($mod, $service_rate) { $order_time_type_text = ['notify_time' => '回调时间', 'order_time' => '下单时间']; for ($cur_stage = 1; $cur_stage <= $total_stage; $cur_stage ++) { $skip = ($cur_stage - 1) * $stage_limit; $items = $mod->table('refill_stats') ->field('time_text,cname,cid,success_count,success_refill_amounts,success_mch_amounts,success_channel_amounts,order_time_type') ->where($cond) ->order('time_stamp desc, cname asc') ->limit("$skip,$stage_limit") ->master(false) ->select(); foreach ($items as &$item) { $rate = $service_rate($item['cid'], $item['time_text']); $servicefee_rate = $rate; $item['servicefee_rate'] = number_format($servicefee_rate * 100, 2, '.', ''); $item['serivcefee'] = ncPriceFormat($item['success_refill_amounts'] * $servicefee_rate); $item['actual_profit_amounts'] = ncPriceFormat($item['success_mch_amounts'] - $item['success_channel_amounts'] - $item['serivcefee']); $item['order_time_type'] = $order_time_type_text[$item['order_time_type']]; } yield [$items,$total_stage,$cur_stage]; if(empty($items)) { break; } } }; $stats_total_reader = function ($condition) use($service_rate, $mod) { if (!empty($condition['order_time_type'])) { $time_type = $condition['order_time_type']; $order_time_type = [$time_type]; } else { $order_time_type = ['notify_time', 'order_time']; } $total_stats_list = []; foreach ($order_time_type as $type) { $total_stats = []; $condition['order_time_type'] = $type; $count = $mod->table('refill_stats') ->where($condition) ->count(); $stage_limit = 1000; $total_stage = ceil($count / $stage_limit); for ($i = 1; $i <= $total_stage; $i++) { $skip = ($i - 1) * $stage_limit; $stats = $mod->table('refill_stats') ->field('time_text,cname,cid,success_count,success_refill_amounts,success_mch_amounts,success_channel_amounts,profit_amounts,send_count,order_time_type') ->where($condition) ->limit("$skip,$stage_limit") ->select(); foreach ($stats as $stat) { $mchid = $stat['cid']; $time_text = $stat['time_text']; $curr_rate = $service_rate($mchid, $time_text); $servicefee_total = $stat['success_refill_amounts'] * $curr_rate; $total_stats['servicefee_total'] += $servicefee_total; $total_stats['success_count_total'] += $stat['success_count']; $total_stats['success_refill_amounts_total'] += $stat['success_refill_amounts']; $total_stats['success_mch_amounts_toatl'] += $stat['success_mch_amounts']; $total_stats['success_channel_amounts_total'] += $stat['success_channel_amounts']; $total_stats['profit_amounts_total'] += $stat['profit_amounts']; $total_stats['send_count_total'] += $stat['send_count']; $total_stats['actual_profit_amounts_total'] += $stat['success_mch_amounts'] - $stat['success_channel_amounts'] - $servicefee_total; } } $total_stats_list[$type] = [ $type === 'notify_time' ? '回调日期统计' : '下单日期统计', '总计成功订单量: ' . $total_stats['success_count_total'], '总计充值中订单量: ' . $total_stats['send_count_total'], '总计成功订单金额:' . ncPriceFormat($total_stats['success_refill_amounts_total']), '总计下游扣款金额:' . ncPriceFormat($total_stats['success_mch_amounts_toatl']), '总计上游扣款金额:' . ncPriceFormat($total_stats['success_channel_amounts_total']), '总计利润:' . ncPriceFormat($total_stats['profit_amounts_total']), '服务费:' . ncPriceFormat($total_stats['servicefee_total']), '实际利润:' . ncPriceFormat($total_stats['actual_profit_amounts_total']) ]; } return $total_stats_list; }; $normal_cond = $cond['normal']; $total_stats_list = $stats_total_reader($normal_cond); $objPHPExcel = new PHPExcel(); $objPHPExcel->setActiveSheetIndex(0); $objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')->setSize(10); $objSheet = $objPHPExcel->getActiveSheet(); $time_type = $normal_cond['order_time_type']; if (empty($time_type)) //显示下单和回调的汇总 { for ($i = 1; $i <= 9; $i++) { $objSheet->mergeCells("A$i:E$i"); $objSheet->mergeCells("F$i:K$i"); $objSheet->setCellValueExplicit("A$i", $total_stats_list['notify_time'][$i-1]); $objSheet->setCellValueExplicit("F$i", $total_stats_list['order_time'][$i-1]); } } else { for ($i = 1; $i <= 9; $i++) { $objSheet->mergeCells("A$i:K$i"); $objSheet->setCellValueExplicit("A$i", $total_stats_list[$time_type][$i-1]); } } $column_values = ['统计日期', '主体名称', '主体ID', '成功订单数', '成功金额', '下游金额', '上游金额', '服务点', '服务费', '实际利润', '统计日期类型']; $data_keys = ['time_text', 'cname', 'cid', 'success_count', 'success_refill_amounts', 'success_mch_amounts', 'success_channel_amounts', 'servicefee_rate', 'serivcefee', 'actual_profit_amounts', 'order_time_type']; $column_key = 'A'; for ($excel_index = 0; $excel_index < count($column_values); $excel_index++) { $column_keys[] = $column_key; $column_key++; } $excel_writer = function ($order, $index) use ($column_keys, $objPHPExcel, $data_keys) { foreach ($column_keys as $key => $column_key) { $field = $column_key . ($index + 12); $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]); }; foreach ($column_keys as $key => $column_key) { $objPHPExcel->getActiveSheet()->getColumnDimension($column_key)->setWidth(15); $cell_value = $column_key . 11; $objPHPExcel->getActiveSheet()->setCellValue($cell_value, $column_values[$key]); } $stage = 0; $execl_index = 0; $total = $mod->table('refill_stats') ->field('time_text,cname,cid,success_count,success_refill_amounts,success_mch_amounts,success_channel_amounts,profit_amounts,send_count,order_time_type') ->where($normal_cond) ->count();; $stage_limit = 1000; $total_stage = ceil($total / $stage_limit); $reader = $stats_reader($normal_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 refill_servicefee_export_title($condition) { return md5("refill_servicefee_export-".serialize($condition)); } }